aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx')
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx194
1 files changed, 194 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx
new file mode 100755
index 0000000..3b5e761
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx
@@ -0,0 +1,194 @@
1import * as Uebersicht from "uebersicht";
2import OpenedApps from "./opened-apps.jsx";
3import SpaceOptions from "./space-options.jsx";
4import { useYabaiContext } from "../yabai-context.jsx";
5import { useSimpleBarContext } from "../simple-bar-context.jsx";
6import * as Utils from "../../utils.js";
7import * as Yabai from "../../yabai.js";
8
9const { React } = Uebersicht;
10
11/**
12 * Component representing a space in yabai window manager.
13 * @param {Object} props - The component props.
14 * @param {Object} props.space - The space object.
15 * @param {number} props.display - The display index.
16 * @param {number} props.currentSpaceIndex - The current space index.
17 * @param {boolean} props.lastOfSpace - Whether this is the last space.
18 * @returns {JSX.Element|null} The rendered component.
19 */
20export default function Space({
21 space,
22 display,
23 currentSpaceIndex,
24 lastOfSpace,
25}) {
26 const { windows } = useYabaiContext();
27 const { SIPDisabled, settings } = useSimpleBarContext();
28 const { spacesDisplay } = settings;
29 const {
30 displayAllSpacesOnAllScreens,
31 exclusionsAsRegex,
32 displayStickyWindowsSeparately,
33 hideDuplicateAppsInSpaces,
34 showOptionsOnHover,
35 } = spacesDisplay;
36
37 const labelRef = React.useRef();
38 const [hovered, setHovered] = React.useState(false);
39 const [noDelay, setNoDelay] = React.useState(false);
40 const [editable, setEditable] = React.useState(false);
41 const {
42 index,
43 label,
44 "has-focus": hasFocus,
45 focused: __legacyHasFocus,
46 "is-visible": isVisible,
47 visible: __legacyIsVisible,
48 "is-native-fullscreen": isNativeFullscreen,
49 "native-fullscreen": __legacyIsNativeFullscreen,
50 type,
51 } = space;
52 const [spaceLabel, setSpaceLabel] = React.useState(
53 label?.length ? label : index,
54 );
55
56 // Return null if the space should not be displayed on the current screen
57 if (!displayAllSpacesOnAllScreens && display.index !== space.display)
58 return null;
59
60 const exclusions = exclusionsAsRegex
61 ? spacesDisplay.exclusions
62 : spacesDisplay.exclusions.split(", ");
63 const titleExclusions = exclusionsAsRegex
64 ? spacesDisplay.titleExclusions
65 : spacesDisplay.titleExclusions.split(", ");
66
67 /**
68 * Handle mouse enter event.
69 * @param {MouseEvent} e - The mouse event.
70 */
71 const onMouseEnter = (e) => {
72 if (!showOptionsOnHover) return;
73 const { altKey, metaKey } = e;
74 if (altKey) return;
75 setHovered(true);
76 if (metaKey) setNoDelay(true);
77 };
78
79 /**
80 * Handle mouse leave event.
81 */
82 const onMouseLeave = () => {
83 setHovered(false);
84 setNoDelay(false);
85 setEditable(false);
86 window.getSelection().removeAllRanges();
87 };
88
89 /**
90 * Handle click event.
91 * @param {MouseEvent} e - The mouse event.
92 */
93 const onClick = (e) => {
94 onMouseLeave(e);
95 if (e.altKey) {
96 setEditable(true);
97 labelRef.current?.select();
98 return;
99 }
100 if (hasFocus || __legacyHasFocus) return;
101 if (SIPDisabled && !spacesDisplay.switchSpacesWithoutYabai) {
102 Yabai.goToSpace(index);
103 Utils.clickEffect(e);
104 return;
105 }
106 Utils.switchSpace(currentSpaceIndex, index);
107 Utils.clickEffect(e);
108 };
109
110 /**
111 * Handle right-click event.
112 */
113 const onRightClick = () => {
114 setHovered(true);
115 setNoDelay(true);
116 };
117
118 /**
119 * Handle change event for the space label input.
120 * @param {Event} e - The change event.
121 */
122 const onChange = (e) => {
123 if (!editable) return;
124 const newLabel = e.target.value;
125 setSpaceLabel(newLabel);
126 Yabai.renameSpace(index, newLabel);
127 };
128
129 const { nonStickyWindows: apps, stickyWindows } =
130 Utils.stickyWindowWorkaround({
131 windows,
132 uniqueApps: hideDuplicateAppsInSpaces,
133 currentDisplay: display,
134 currentSpace: index,
135 exclusions,
136 titleExclusions,
137 exclusionsAsRegex,
138 });
139 const allApps = [...apps, ...stickyWindows];
140
141 // Determine if the space should be hidden
142 const hidden =
143 !(hasFocus ?? __legacyHasFocus) &&
144 !(isVisible ?? __legacyHasFocus) &&
145 !allApps.length &&
146 spacesDisplay.hideEmptySpaces;
147
148 if (hidden) return null;
149
150 const classes = Utils.classNames(`space space--${type}`, {
151 "space--focused": hasFocus ?? __legacyHasFocus,
152 "space--visible": isVisible ?? __legacyIsVisible,
153 "space--fullscreen": isNativeFullscreen ?? __legacyIsNativeFullscreen,
154 "space--hovered": hovered,
155 "space--no-delay": noDelay,
156 "space--empty": allApps.length,
157 "space--editable": editable,
158 });
159
160 const labelSize = (
161 typeof spaceLabel === "number" ? spaceLabel.toString() : spaceLabel
162 ).length;
163
164 return (
165 <React.Fragment>
166 {displayAllSpacesOnAllScreens && lastOfSpace && (
167 <div className="spaces__separator" />
168 )}
169 <div
170 className={classes}
171 onMouseLeave={onMouseLeave}
172 onMouseEnter={onMouseEnter}
173 >
174 <button
175 className="space__inner"
176 onClick={onClick}
177 onContextMenu={onRightClick}
178 >
179 <input
180 ref={labelRef}
181 type="text"
182 className="space__label"
183 onChange={onChange}
184 value={spaceLabel}
185 style={{ width: `${labelSize}ch` }}
186 readOnly={!editable}
187 />
188 <OpenedApps apps={displayStickyWindowsSeparately ? apps : allApps} />
189 </button>
190 {SIPDisabled && <SpaceOptions index={index} setHovered={setHovered} />}
191 </div>
192 </React.Fragment>
193 );
194}