ags: sync

This commit is contained in:
end-4
2024-02-16 17:08:11 +07:00
parent 631d0da839
commit a83d93e98a
52 changed files with 2648 additions and 756 deletions
+389 -250
View File
@@ -3,6 +3,7 @@
// - Active ws hook optimization: only update when moving to next group
//
const { Gdk, Gtk } = imports.gi;
const { Gravity } = imports.gi.Gdk;
import { SCREEN_HEIGHT, SCREEN_WIDTH } from '../../imports.js';
import App from 'resource:///com/github/Aylur/ags/app.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
@@ -48,260 +49,398 @@ function substitute(str) {
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, '-'); // Turn into kebab-case
return str;
}
export default () => {
const clientMap = new Map();
let workspaceGroup = 0;
const ContextMenuWorkspaceArray = ({ label, actionFunc, thisWorkspace }) => Widget.MenuItem({
label: `${label}`,
setup: (menuItem) => {
let submenu = new Gtk.Menu();
submenu.className = 'menu';
const ContextMenuWorkspaceArray = ({ label, actionFunc, thisWorkspace }) => Widget.MenuItem({
label: `${label}`,
setup: (menuItem) => {
let submenu = new Gtk.Menu();
submenu.className = 'menu';
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
const startWorkspace = offset + 1;
const endWorkspace = startWorkspace + NUM_OF_WORKSPACES_SHOWN - 1;
for (let i = startWorkspace; i <= endWorkspace; i++) {
let button = new Gtk.MenuItem({
label: `Workspace ${i}`
});
button.connect("activate", () => {
// execAsync([`${onClickBinary}`, `${thisWorkspace}`, `${i}`]).catch(print);
actionFunc(thisWorkspace, i);
});
submenu.append(button);
}
menuItem.set_reserve_indicator(true);
menuItem.set_submenu(submenu);
}
})
const Window = ({ address, at: [x, y], size: [w, h], workspace: { id, name }, class: c, title, xwayland }) => {
const revealInfoCondition = (Math.min(w, h) * OVERVIEW_SCALE > 70);
if (w <= 0 || h <= 0 || (c === '' && title === '')) return null;
if (x + w <= 0) x += (Math.floor(x / SCREEN_WIDTH) * SCREEN_WIDTH);
else if (x < 0) { x = 0; w = x + w; }
if (y + h <= 0) x += (Math.floor(y / SCREEN_HEIGHT) * SCREEN_HEIGHT);
else if (y < 0) { y = 0; h = y + h; }
if (x >= SCREEN_WIDTH) x %= SCREEN_WIDTH;
else if (x + w > SCREEN_WIDTH) w = SCREEN_WIDTH - x;
if (y >= SCREEN_HEIGHT) y %= SCREEN_HEIGHT;
else if (y + h > SCREEN_HEIGHT) h = SCREEN_HEIGHT - y;
// title = truncateTitle(title);
return Widget.Button({
attribute: { x, y },
className: 'overview-tasks-window',
hpack: 'center',
vpack: 'center',
onClicked: () => {
Hyprland.sendMessage(`dispatch focuswindow address:${address}`);
App.closeWindow('overview');
},
onMiddleClickRelease: () => Hyprland.sendMessage(`dispatch closewindow address:${address}`),
onSecondaryClick: (button) => {
button.toggleClassName('overview-tasks-window-selected', true);
const menu = Widget.Menu({
className: 'menu',
children: [
Widget.MenuItem({
child: Widget.Label({
xalign: 0,
label: "Close (Middle-click)",
}),
onActivate: () => Hyprland.sendMessage(`dispatch closewindow address:${address}`),
}),
ContextMenuWorkspaceArray({
label: "Dump windows to workspace",
actionFunc: dumpToWorkspace,
thisWorkspace: Number(id)
}),
ContextMenuWorkspaceArray({
label: "Swap windows with workspace",
actionFunc: swapWorkspace,
thisWorkspace: Number(id)
}),
],
});
menu.connect("deactivate", () => {
button.toggleClassName('overview-tasks-window-selected', false);
})
menu.connect("selection-done", () => {
button.toggleClassName('overview-tasks-window-selected', false);
})
menu.popup_at_pointer(null); // Show the menu at the pointer's position
},
child: Widget.Box({
css: `
min-width: ${Math.max(w * OVERVIEW_SCALE - 4, 1)}px;
min-height: ${Math.max(h * OVERVIEW_SCALE - 4, 1)}px;
`,
homogeneous: true,
child: Widget.Box({
vertical: true,
vpack: 'center',
className: 'spacing-v-5',
children: [
Widget.Icon({
icon: substitute(c),
size: Math.min(w, h) * OVERVIEW_SCALE / 2.5,
}),
// TODO: Add xwayland tag instead of just having italics
Widget.Revealer({
transition: 'slide_down',
revealChild: revealInfoCondition,
child: Widget.Label({
truncate: 'end',
className: `${xwayland ? 'txt txt-italic' : 'txt'}`,
css: `
font-size: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE / 14.6}px;
margin: 0px ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE / 10}px;
`,
// If the title is too short, include the class
label: (title.length <= 1 ? `${c}: ${title}` : title),
})
})
]
})
}),
tooltipText: `${c}: ${title}`,
setup: (button) => {
setupCursorHoverGrab(button);
button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.MOVE);
button.drag_source_set_icon_name(substitute(c));
// button.drag_source_set_icon_gicon(icon);
button.connect('drag-begin', (button) => { // On drag start, add the dragging class
button.toggleClassName('overview-tasks-window-dragging', true);
});
button.connect('drag-data-get', (_w, _c, data) => { // On drag finish, give address
data.set_text(address, address.length);
button.toggleClassName('overview-tasks-window-dragging', false);
});
},
});
}
const Workspace = (index) => {
const fixed = Gtk.Fixed.new();
// const clientMap = new Map();
const WorkspaceNumber = (index) => Widget.Label({
className: 'overview-tasks-workspace-number',
label: `${index}`,
css: `
margin: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE * OVERVIEW_WS_NUM_MARGIN_SCALE}px;
font-size: ${SCREEN_HEIGHT * OVERVIEW_SCALE * OVERVIEW_WS_NUM_SCALE}px;
`,
})
const widget = Widget.Box({
className: 'overview-tasks-workspace',
vpack: 'center',
css: `
min-width: ${SCREEN_WIDTH * OVERVIEW_SCALE}px;
min-height: ${SCREEN_HEIGHT * OVERVIEW_SCALE}px;
`,
children: [Widget.EventBox({
hexpand: true,
vexpand: true,
onPrimaryClick: () => {
Hyprland.sendMessage(`dispatch workspace ${index}`)
App.closeWindow('overview');
},
setup: (eventbox) => {
eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
eventbox.connect('drag-data-received', (_w, _c, _x, _y, data) => {
Hyprland.sendMessage(`dispatch movetoworkspacesilent ${index},address:${data.get_text()}`)
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
const startWorkspace = offset + 1;
const endWorkspace = startWorkspace + NUM_OF_WORKSPACES_SHOWN - 1;
for (let i = startWorkspace; i <= endWorkspace; i++) {
let button = new Gtk.MenuItem({
label: `Workspace ${i}`
});
button.connect("activate", () => {
// execAsync([`${onClickBinary}`, `${thisWorkspace}`, `${i}`]).catch(print);
actionFunc(thisWorkspace, i);
overviewTick.setValue(!overviewTick.value);
});
},
child: fixed,
})],
});
widget.clear = () => {
fixed.get_children().forEach(ch => ch.destroy());
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
fixed.put(WorkspaceNumber(offset + index), 0, 0);
}
widget.set = (clientJson) => {
// if(clientMap.get(clientJson.address)) clientMap.get(clientJson.address).destroy();
const newWindow = Window(clientJson);
if (newWindow === null) return;
// clientMap.set(clientJson.address, newWindow);
fixed.put(newWindow,
Math.max(0, newWindow.attribute.x * OVERVIEW_SCALE),
Math.max(0, newWindow.attribute.y * OVERVIEW_SCALE)
);
};
// widget.unset = (clientAddress) => {
// if(clientMap.get(clientAddress)) {
// clientMap.get(clientAddress).destroy();
// clientMap.delete(clientAddress);
// }
// };
widget.show = () => {
fixed.show_all();
}
return widget;
};
const arr = (s, n) => {
const array = [];
for (let i = 0; i < n; i++)
array.push(s + i);
return array;
};
const OverviewRow = ({ startWorkspace, workspaces, windowName = 'overview' }) => Widget.Box({
children: arr(startWorkspace, workspaces).map(Workspace),
attribute: {
update: (box) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
if (!App.getWindow(windowName).visible) return;
execAsync('hyprctl -j clients').then(clients => {
const allClients = JSON.parse(clients);
const kids = box.get_children();
kids.forEach(kid => kid.clear());
for (let i = 0; i < allClients.length; i++) {
const client = allClients[i];
if (offset + startWorkspace <= client.workspace.id &&
client.workspace.id <= offset + startWorkspace + workspaces) {
kids[client.workspace.id - (offset + startWorkspace)]
?.set(client);
}
}
kids.forEach(kid => kid.show());
}).catch(print);
submenu.append(button);
}
menuItem.set_reserve_indicator(true);
menuItem.set_submenu(submenu);
}
},
setup: (box) => box
.hook(overviewTick, (box) => box.attribute.update(box))
.hook(Hyprland, (box, clientAddress) => {
box.attribute.update(box)
}, 'client-removed')
.hook(Hyprland, (box, clientAddress) => {
box.attribute.update(box);
}, 'client-added')
.hook(Hyprland.active.workspace, (box) => box.attribute.update(box))
.hook(App, (box, name, visible) => { // Update on open
if (name == 'overview' && visible) box.attribute.update(box);
})
const Window = ({ address, at: [x, y], size: [w, h], workspace: { id, name }, class: c, title, xwayland }, screenCoords) => {
const revealInfoCondition = (Math.min(w, h) * OVERVIEW_SCALE > 70);
if (w <= 0 || h <= 0 || (c === '' && title === '')) return null;
// Non-primary monitors
if (screenCoords.x != 0) x -= screenCoords.x;
if (screenCoords.y != 0) y -= screenCoords.y;
// Other offscreen adjustments
if (x + w <= 0) x += (Math.floor(x / SCREEN_WIDTH) * SCREEN_WIDTH);
else if (x < 0) { w = x + w; x = 0; }
if (y + h <= 0) x += (Math.floor(y / SCREEN_HEIGHT) * SCREEN_HEIGHT);
else if (y < 0) { h = y + h; y = 0; }
// Truncate if offscreen
if (x + w > SCREEN_WIDTH) w = SCREEN_WIDTH - x;
if (y + h > SCREEN_HEIGHT) h = SCREEN_HEIGHT - y;
const appIcon = Widget.Icon({
icon: substitute(c),
size: Math.min(w, h) * OVERVIEW_SCALE / 2.5,
});
return Widget.Button({
attribute: {
address, x, y, w, h, ws: id,
updateIconSize: (self) => {
appIcon.size = Math.min(self.attribute.w, self.attribute.h) * OVERVIEW_SCALE / 2.5;
},
},
className: 'overview-tasks-window',
hpack: 'start',
vpack: 'start',
css: `
margin-left: ${Math.round(x * OVERVIEW_SCALE)}px;
margin-top: ${Math.round(y * OVERVIEW_SCALE)}px;
margin-right: -${Math.round((x + w) * OVERVIEW_SCALE)}px;
margin-bottom: -${Math.round((y + h) * OVERVIEW_SCALE)}px;
`,
onClicked: (self) => {
Hyprland.sendMessage(`dispatch focuswindow address:${address}`);
App.closeWindow('overview');
},
onMiddleClickRelease: () => Hyprland.sendMessage(`dispatch closewindow address:${address}`),
onSecondaryClick: (button) => {
button.toggleClassName('overview-tasks-window-selected', true);
const menu = Widget.Menu({
className: 'menu',
children: [
Widget.MenuItem({
child: Widget.Label({
xalign: 0,
label: "Close (Middle-click)",
}),
onActivate: () => Hyprland.sendMessage(`dispatch closewindow address:${address}`),
}),
ContextMenuWorkspaceArray({
label: "Dump windows to workspace",
actionFunc: dumpToWorkspace,
thisWorkspace: Number(id)
}),
ContextMenuWorkspaceArray({
label: "Swap windows with workspace",
actionFunc: swapWorkspace,
thisWorkspace: Number(id)
}),
],
});
menu.connect("deactivate", () => {
button.toggleClassName('overview-tasks-window-selected', false);
})
menu.connect("selection-done", () => {
button.toggleClassName('overview-tasks-window-selected', false);
})
menu.popup_at_widget(button.get_parent(), Gravity.SOUTH, Gravity.NORTH, null); // Show menu below the button
button.connect("destroy", () => menu.destroy());
},
child: Widget.Box({
homogeneous: true,
child: Widget.Box({
vertical: true,
vpack: 'center',
className: 'spacing-v-5',
children: [
appIcon,
// TODO: Add xwayland tag instead of just having italics
// Widget.Revealer({
// transition: 'slide_down',
// revealChild: revealInfoCondition,
// child: Widget.Label({
// truncate: 'end',
// className: `${xwayland ? 'txt txt-italic' : 'txt'}`,
// css: `
// font-size: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE / 14.6}px;
// margin: 0px ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE / 10}px;
// `,
// // If the title is too short, include the class
// label: (title.length <= 1 ? `${c}: ${title}` : title),
// })
// })
]
})
}),
tooltipText: `${c}: ${title}`,
setup: (button) => {
setupCursorHoverGrab(button);
button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.MOVE);
button.drag_source_set_icon_name(substitute(c));
// button.drag_source_set_icon_gicon(icon);
button.connect('drag-begin', (button) => { // On drag start, add the dragging class
button.toggleClassName('overview-tasks-window-dragging', true);
});
button.connect('drag-data-get', (_w, _c, data) => { // On drag finish, give address
data.set_text(address, address.length);
button.toggleClassName('overview-tasks-window-dragging', false);
});
},
});
}
const Workspace = (index) => {
// const fixed = Widget.Fixed({
// attribute: {
// put: (widget, x, y) => {
// fixed.put(widget, x, y);
// },
// move: (widget, x, y) => {
// fixed.move(widget, x, y);
// },
// }
// });
const fixed = Widget.Box({
attribute: {
put: (widget, x, y) => {
if (!widget.attribute) return;
// Note: x and y are already multiplied by OVERVIEW_SCALE
const newCss = `
margin-left: ${Math.round(x)}px;
margin-top: ${Math.round(y)}px;
margin-right: -${Math.round(x + (widget.attribute.w * OVERVIEW_SCALE))}px;
margin-bottom: -${Math.round(y + (widget.attribute.h * OVERVIEW_SCALE))}px;
`;
widget.css = newCss;
fixed.pack_start(widget, false, false, 0);
},
move: (widget, x, y) => {
if (!widget) return;
if (!widget.attribute) return;
// Note: x and y are already multiplied by OVERVIEW_SCALE
const newCss = `
margin-left: ${Math.round(x)}px;
margin-top: ${Math.round(y)}px;
margin-right: -${Math.round(x + (widget.attribute.w * OVERVIEW_SCALE))}px;
margin-bottom: -${Math.round(y + (widget.attribute.h * OVERVIEW_SCALE))}px;
`;
widget.css = newCss;
},
}
})
,
});
const WorkspaceNumber = (index) => Widget.Label({
className: 'overview-tasks-workspace-number',
label: `${index}`,
css: `
margin: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE * OVERVIEW_WS_NUM_MARGIN_SCALE}px;
font-size: ${SCREEN_HEIGHT * OVERVIEW_SCALE * OVERVIEW_WS_NUM_SCALE}px;
`,
})
const widget = Widget.Box({
className: 'overview-tasks-workspace',
vpack: 'center',
css: `
min-width: ${SCREEN_WIDTH * OVERVIEW_SCALE}px;
min-height: ${SCREEN_HEIGHT * OVERVIEW_SCALE}px;
`,
children: [Widget.EventBox({
hexpand: true,
vexpand: true,
onPrimaryClick: () => {
Hyprland.sendMessage(`dispatch workspace ${index}`)
App.closeWindow('overview');
},
setup: (eventbox) => {
eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
eventbox.connect('drag-data-received', (_w, _c, _x, _y, data) => {
Hyprland.sendMessage(`dispatch movetoworkspacesilent ${index},address:${data.get_text()}`)
overviewTick.setValue(!overviewTick.value);
});
},
child: fixed,
})],
});
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
fixed.attribute.put(WorkspaceNumber(offset + index), 0, 0);
widget.clear = () => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
clientMap.forEach((client, address) => {
if (!client || client.ws !== offset + index) return;
client.destroy();
client = null;
clientMap.delete(address);
});
}
widget.set = (clientJson, screenCoords) => {
let c = clientMap.get(clientJson.address);
if (c) {
if (c.attribute?.ws !== clientJson.workspace.id) {
c.destroy();
c = null;
clientMap.delete(clientJson.address);
}
else if (c) {
c.attribute.w = clientJson.size[0];
c.attribute.h = clientJson.size[1];
c.attribute.updateIconSize(c);
fixed.attribute.move(c,
Math.max(0, clientJson.at[0] * OVERVIEW_SCALE),
Math.max(0, clientJson.at[1] * OVERVIEW_SCALE)
);
return;
}
}
const newWindow = Window(clientJson, screenCoords);
if (newWindow === null) return;
// clientMap.set(clientJson.address, newWindow);
fixed.attribute.put(newWindow,
Math.max(0, newWindow.attribute.x * OVERVIEW_SCALE),
Math.max(0, newWindow.attribute.y * OVERVIEW_SCALE)
);
clientMap.set(clientJson.address, newWindow);
};
widget.unset = (clientAddress) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
let c = clientMap.get(clientAddress);
if (!c) return;
c.destroy();
c = null;
clientMap.delete(clientAddress);
};
widget.show = () => {
fixed.show_all();
}
return widget;
};
const arr = (s, n) => {
const array = [];
for (let i = 0; i < n; i++)
array.push(s + i);
export default () => Widget.Revealer({
revealChild: true,
transition: 'slide_down',
transitionDuration: 200,
child: Widget.Box({
vertical: true,
className: 'overview-tasks',
children: Array.from({ length: NUM_OF_WORKSPACE_ROWS }, (_, index) =>
OverviewRow({
startWorkspace: 1 + index * NUM_OF_WORKSPACE_COLS,
workspaces: NUM_OF_WORKSPACE_COLS,
})
)
}),
});
return array;
};
const OverviewRow = ({ startWorkspace, workspaces, windowName = 'overview' }) => Widget.Box({
children: arr(startWorkspace, workspaces).map(Workspace),
attribute: {
monitorMap: [],
getMonitorMap: (box) => {
execAsync('hyprctl -j monitors').then(monitors => {
box.attribute.monitorMap = JSON.parse(monitors).reduce((acc, item) => {
acc[item.id] = { x: item.x, y: item.y };
return acc;
}, {});
});
},
update: (box) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
if (!App.getWindow(windowName).visible) return;
Hyprland.sendMessage('j/clients').then(clients => {
const allClients = JSON.parse(clients);
const kids = box.get_children();
kids.forEach(kid => kid.clear());
// console.log('----------------------------');
for (let i = 0; i < allClients.length; i++) {
const client = allClients[i];
const childID = client.workspace.id - (offset + startWorkspace);
if (offset + startWorkspace <= client.workspace.id &&
client.workspace.id <= offset + startWorkspace + workspaces) {
const screenCoords = box.attribute.monitorMap[client.monitor];
if (kids[childID]) {
kids[childID].set(client, screenCoords);
}
continue;
}
// const modID = client.workspace.id % NUM_OF_WORKSPACES_SHOWN;
// console.log(`[${startWorkspace} -> ${startWorkspace + workspaces - 1}] ? (${client.workspace.id} == ${modID})`);
// // console.log(`[${startWorkspace} -> ${startWorkspace + workspaces}] ? (${modID})`);
// if (startWorkspace <= modID && modID < startWorkspace + workspaces) {
// console.log('i care');
// const clientWidget = clientMap.get(client.address);
// console.log(childID, kids[childID], clientWidget);
// if (kids[childID] && clientWidget) {
// console.log('hmm remove', clientWidget.attribute)
// kids[childID].remove(clientWidget);
// }
// }
}
kids.forEach(kid => kid.show());
}).catch(print);
},
updateWorkspace: (box, id) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
if (!( // Not in range, ignore
offset + startWorkspace <= id &&
id <= offset + startWorkspace + workspaces
)) return;
// if (!App.getWindow(windowName).visible) return;
Hyprland.sendMessage('j/clients').then(clients => {
const allClients = JSON.parse(clients);
const kids = box.get_children();
for (let i = 0; i < allClients.length; i++) {
const client = allClients[i];
if (client.workspace.id != id) continue;
const screenCoords = box.attribute.monitorMap[client.monitor];
kids[id - (offset + startWorkspace)]?.set(client, screenCoords);
}
kids[id - (offset + startWorkspace)]?.show();
}).catch(print);
},
},
setup: (box) => {
box.attribute.getMonitorMap(box);
box
.hook(overviewTick, (box) => box.attribute.update(box))
.hook(Hyprland, (box, clientAddress) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
const kids = box.get_children();
const client = Hyprland.getClient(clientAddress);
if (!client) return;
const id = client.workspace.id;
box.attribute.updateWorkspace(box, id);
kids[id - (offset + startWorkspace)]?.unset(clientAddress);
}, 'client-removed')
.hook(Hyprland, (box, clientAddress) => {
const client = Hyprland.getClient(clientAddress);
if (!client) return;
box.attribute.updateWorkspace(box, client.workspace.id);
}, 'client-added')
.hook(Hyprland.active.workspace, (box) => {
const previousGroup = box.attribute.workspaceGroup;
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN);
if (currentGroup !== previousGroup) {
box.attribute.update(box);
workspaceGroup = currentGroup;
}
// box.attribute.update(box);
})
.hook(App, (box, name, visible) => { // Update on open
if (name == 'overview' && visible) box.attribute.update(box);
})
},
});
return Widget.Revealer({
revealChild: true,
transition: 'slide_down',
transitionDuration: 200,
child: Widget.Box({
vertical: true,
className: 'overview-tasks',
children: Array.from({ length: NUM_OF_WORKSPACE_ROWS }, (_, index) =>
OverviewRow({
startWorkspace: 1 + index * NUM_OF_WORKSPACE_COLS,
workspaces: NUM_OF_WORKSPACE_COLS,
})
)
}),
});
}
@@ -38,12 +38,6 @@ export const DirectoryButton = ({ parentPath, name, type, icon }) => {
homogeneous: true,
child: Widget.Icon({
icon: icon,
setup: (self) => Utils.timeout(1, () => {
const styleContext = self.get_parent().get_style_context();
const width = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
self.size = Math.max(width, height, 1);
})
}),
}),
Widget.Label({
@@ -112,12 +106,6 @@ export const DesktopEntryButton = (app) => {
homogeneous: true,
child: Widget.Icon({
icon: app.iconName,
setup: (self) => Utils.timeout(1, () => {
const styleContext = self.get_parent().get_style_context();
const width = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
self.size = Math.max(width, height, 1);
})
}),
}),
Widget.Label({
+31 -7
View File
@@ -1,4 +1,4 @@
const { Gtk } = imports.gi;
const { Gdk, Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
@@ -76,7 +76,7 @@ export const SearchAndWindows = () => {
child: Widget.Label({
className: 'overview-search-prompt txt-small txt',
label: 'Type to search'
})
}),
});
const entryIconRevealer = Widget.Revealer({
@@ -217,7 +217,10 @@ export const SearchAndWindows = () => {
entry,
Widget.Box({
className: 'overview-search-icon-box',
setup: box => box.pack_start(entryPromptRevealer, true, true, 0),
setup: (box) => {
box.pack_start(entryPromptRevealer, true, true, 0)
// enableClickthrough(box);
},
}),
entryIcon,
]
@@ -233,10 +236,31 @@ export const SearchAndWindows = () => {
}
})
.on('key-press-event', (widget, event) => { // Typing
if (event.get_keyval()[1] >= 32 && event.get_keyval()[1] <= 126 && widget != entry) {
Utils.timeout(1, () => entry.grab_focus());
entry.set_text(entry.text + String.fromCharCode(event.get_keyval()[1]));
entry.set_position(-1);
const keyval = event.get_keyval()[1];
const modstate = event.get_state()[1];
if (modstate & Gdk.ModifierType.CONTROL_MASK) { // Ctrl held
if (keyval == Gdk.KEY_b)
entry.set_position(Math.max(entry.get_position() - 1, 0));
else if (keyval == Gdk.KEY_f)
entry.set_position(Math.min(entry.get_position() + 1, entry.get_text().length));
else if (keyval == Gdk.KEY_n) { // simulate Down arrow
entry.get_root_window().simulate_key_press(Gdk.KEY_Down, Gdk.ModifierType.NONE);
// entry.get_root_window().simulate_key_release(Gdk.KEY_Down, Gdk.ModifierType.NONE);
}
else if (keyval == Gdk.KEY_k) { // Delete to end
const text = entry.get_text();
const pos = entry.get_position();
const newText = text.slice(0, pos);
entry.set_text(newText);
entry.set_position(newText.length);
}
}
else { // Ctrl not held
if (keyval >= 32 && keyval <= 126 && widget != entry) {
Utils.timeout(1, () => entry.grab_focus());
entry.set_text(entry.text + String.fromCharCode(keyval));
entry.set_position(-1);
}
}
})
,