aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai-context.jsx
blob: 245977be7a41205b1832634138c62bfe983b3a5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import * as Uebersicht from "uebersicht";
import { useSimpleBarContext } from "./simple-bar-context.jsx";
import useServerSocket from "../hooks/use-server-socket.js";
import * as Yabai from "../yabai.js";
import * as Skhd from "../skhd.js";

const { React } = Uebersicht;

// Create a context with default values
const YabaiContext = React.createContext({
  spaces: [],
  windows: [],
  skhdMode: "",
});

/**
 * Custom hook to use the YabaiContext
 * @returns {Object} The context value
 */
export function useYabaiContext() {
  return React.useContext(YabaiContext);
}

export default React.memo(YabaiContextProvider);

/**
 * YabaiContextProvider component provides context for Yabai spaces, windows, and skhd mode.
 * It uses server sockets to fetch and update the context values.
 *
 * @param {Object} props - The component props.
 * @param {Array} props.spaces - Initial spaces data.
 * @param {Array} props.windows - Initial windows data.
 * @param {Object} props.skhdMode - Initial skhd mode data.
 * @param {React.ReactNode} props.children - The child components to be wrapped by the provider.
 * @returns {JSX.Element} The YabaiContext provider component.
 */
function YabaiContextProvider({ spaces, windows, skhdMode, children }) {
  const { settings, setDisplays } = useSimpleBarContext();
  const { enableServer, yabaiServerRefresh } = settings.global;
  const { displaySkhdMode } = settings.process;
  const serverEnabled = enableServer && yabaiServerRefresh;

  const [yabaiSpaces, setYabaiSpaces] = React.useState(spaces);
  const [yabaiWindows, setYabaiWindows] = React.useState(windows);
  const [currentSkhdMode, setCurrentSkhdMode] = React.useState(skhdMode);

  // Resets the spaces state to an empty array.
  const resetSpaces = () => {
    setYabaiSpaces([]);
  };

  // Resets the windows state to an empty array.
  const resetWindows = () => {
    setYabaiWindows([]);
  };

  // Resets the displays state to an empty array.
  const resetDisplays = () => {
    setDisplays([]);
  };

  // Resets the skhd mode state to an empty object.
  const resetSkhdMode = () => {
    setCurrentSkhdMode({});
  };

  // Fetches the current spaces from Yabai and updates the state.
  const getSpaces = async () => {
    const newSpaces = await Yabai.getSpaces();
    setYabaiSpaces(newSpaces);
  };

  // Fetches the current windows from Yabai and updates the state.
  const getWindows = async () => {
    const newWindows = await Yabai.getWindows();
    setYabaiWindows(newWindows);
  };

  // Fetches the current displays from Yabai and updates the state.
  const getDisplays = async () => {
    const newDisplays = await Yabai.getDisplays();
    setDisplays(newDisplays);
  };

  // Fetches the current skhd mode from Skhd and updates the state.
  const getSkhdMode = async () => {
    const newSkhdMode = await Skhd.getMode();
    setCurrentSkhdMode(newSkhdMode);
  };

  useServerSocket("spaces", serverEnabled, getSpaces, resetSpaces);
  useServerSocket("windows", serverEnabled, getWindows, resetWindows);
  useServerSocket("displays", serverEnabled, getDisplays, resetDisplays);
  useServerSocket("mode", displaySkhdMode, getSkhdMode, resetSkhdMode);

  const usedWindows = serverEnabled ? yabaiWindows : windows;
  // Windows with an empty subrole should not be displayed in the UI
  // See https://github.com/Jean-Tinland/simple-bar/issues/495 for reference
  const filteredWindows = usedWindows.filter((window) => window.subrole);

  return (
    <YabaiContext.Provider
      value={{
        spaces: serverEnabled ? yabaiSpaces : spaces,
        windows: filteredWindows,
        skhdMode: serverEnabled ? currentSkhdMode : skhdMode,
      }}
    >
      {children}
    </YabaiContext.Provider>
  );
}