feat(ags overview): redesign workspace overview

This commit is contained in:
matt1432 2023-10-30 22:00:46 -04:00
parent 8dd83e99ca
commit 297e274c9a
6 changed files with 103 additions and 133 deletions

View file

@ -0,0 +1,35 @@
import { Hyprland, Widget } from '../../imports.js';
const { Box } = Widget;
import * as VARS from './variables.js';
const DEFAULT_STYLE = `
min-width: ${VARS.SCREEN.X * VARS.SCALE}px;
min-height: ${VARS.SCREEN.Y * VARS.SCALE - 4}px;
border-radius: 10px;
`;
export const Highlighter = () => Box({
valign: 'start',
halign: 'start',
className: 'workspace active',
style: DEFAULT_STYLE,
});
export const updateCurrentWorkspace = self => {
self = self.get_parent().get_children()[1];
const currentId = Hyprland.active.workspace.id;
const row = Math.floor((currentId - 1) / VARS.WORKSPACE_PER_ROW);
const rowObject = self.get_parent().get_children()[0].children[0].children[row];
const workspaces = rowObject.child.centerWidget.child.get_children().filter(w => w.revealChild);
const height = row * (VARS.SCREEN.Y * VARS.SCALE + 17);
const currentIndex = workspaces.findIndex(w => w._id == currentId);
self.setStyle(`
${DEFAULT_STYLE}
margin-left: ${9 + currentIndex * (VARS.SCREEN.X * VARS.SCALE + 34)}px;
margin-top: ${9 + height}px;
`);
};

View file

@ -67,7 +67,7 @@ export const WindowButton = ({ address, ...props } = {}) => Button({
self.get_parent().destroy(); self.get_parent().destroy();
const mainBox = App.getWindow('overview').getChild(); const mainBox = App.getWindow('overview').getChild();
updateClients(mainBox); updateClients(mainBox.child);
}); });
}, },
}); });

View file

@ -1,8 +1,9 @@
import { App, Hyprland, Widget } from '../../imports.js'; import { App, Hyprland, Widget } from '../../imports.js';
const { Box } = Widget; const { Box, Overlay } = Widget;
import PopupWindow from '../misc/popup.js'; import PopupWindow from '../misc/popup.js';
import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.js'; import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.js';
import { Highlighter, updateCurrentWorkspace } from './current-workspace.js';
import { updateClients } from './clients.js'; import { updateClients } from './clients.js';
@ -10,40 +11,49 @@ function update(box) {
getWorkspaces(box); getWorkspaces(box);
updateWorkspaces(box); updateWorkspaces(box);
updateClients(box); updateClients(box);
updateCurrentWorkspace(box);
} }
export default () => PopupWindow({ export default () => PopupWindow({
name: 'overview', name: 'overview',
transition: 'crossfade',
closeOnUnfocus: 'none', closeOnUnfocus: 'none',
onOpen: child => update(child), onOpen: child => update(child.child),
child: Box({ child: Overlay({
className: 'overview', setup: self => {
vertical: true, self.set_overlay_pass_through(
children: [ self.get_children()[1],
Box({ true,
vertical: true, );
children: [ },
WorkspaceRow('normal', 0), overlays: [Highlighter()],
], child: Box({
}), className: 'overview',
Box({ vertical: true,
vertical: true, children: [
children: [ Box({
WorkspaceRow('special', 0), vertical: true,
], children: [
}), WorkspaceRow('normal', 0),
], ],
connections: [[Hyprland, self => { }),
if (!App.getWindow('overview').visible) Box({
return; vertical: true,
children: [
WorkspaceRow('special', 0),
],
}),
],
connections: [[Hyprland, self => {
if (!App.getWindow('overview').visible)
return;
update(self); update(self);
}]], }]],
properties: [ properties: [
['workspaces'], ['workspaces'],
], ],
}),
}), }),
}); });

View file

@ -1,8 +1,7 @@
import { Hyprland, Utils, Widget } from '../../imports.js'; import { Hyprland, Widget } from '../../imports.js';
const { Revealer, CenterBox, Box, EventBox, Label, Overlay } = Widget; const { Revealer, CenterBox, Box, EventBox, Label, Overlay } = Widget;
import Gtk from 'gi://Gtk'; import Gtk from 'gi://Gtk';
import GLib from 'gi://GLib';
import { WorkspaceDrop } from './dragndrop.js'; import { WorkspaceDrop } from './dragndrop.js';
import * as VARS from './variables.js'; import * as VARS from './variables.js';
@ -25,30 +24,33 @@ export function getWorkspaces(box) {
export const WorkspaceRow = (className, i) => Revealer({ export const WorkspaceRow = (className, i) => Revealer({
transition: 'slide_down', transition: 'slide_down',
halign: className === 'special' ? '' : 'start',
connections: [[Hyprland, rev => { connections: [[Hyprland, rev => {
const minId = i * VARS.WORKSPACE_PER_ROW; const minId = i * VARS.WORKSPACE_PER_ROW;
const activeId = Hyprland.active.workspace.id; const activeId = Hyprland.active.workspace.id;
rev.revealChild = Hyprland.workspaces.some(ws => ws.id > minId && rev.revealChild = Hyprland.workspaces
(ws.windows > 0 || .some(ws => ws.id > minId &&
ws.id === activeId)); (ws.windows > 0 || ws.id === activeId));
}]], }]],
child: CenterBox({ child: CenterBox({
children: [null, EventBox({ children: [null, EventBox({
// save ref to the 'add' workspace
properties: [['box']], properties: [['box']],
setup: eventbox => eventbox._box = eventbox.child.children[0], setup: eventbox => eventbox._box = eventbox.child.children[0],
connections: [[Hyprland, eventbox => { connections: [[Hyprland, eventbox => {
const maxId = i * VARS.WORKSPACE_PER_ROW + VARS.WORKSPACE_PER_ROW; const maxId = i * VARS.WORKSPACE_PER_ROW + VARS.WORKSPACE_PER_ROW;
const activeId = Hyprland.active.workspace.id; const activeId = Hyprland.active.workspace.id;
eventbox._box.revealChild = className === 'special' || eventbox._box.revealChild = className === 'special' ||
!Hyprland.workspaces.some(ws => ws.id > maxId && !Hyprland.workspaces.some(ws => ws.id > maxId &&
(ws.windows > 0 || (ws.windows > 0 || ws.id === activeId));
ws.id === activeId));
}]], }]],
child: Box({ child: Box({
className: className, className: className,
children: [ children: [
// the 'add' workspace
Workspace(className === 'special' ? -1 : 1000, Workspace(className === 'special' ? -1 : 1000,
className === 'special' ? 'special' : '', className === 'special' ? 'special' : '',
true), true),
@ -58,7 +60,6 @@ export const WorkspaceRow = (className, i) => Revealer({
}), }),
}); });
// TODO: please make this readable for the love of god
const Workspace = (id, name, extra = false) => { const Workspace = (id, name, extra = false) => {
let workspace; let workspace;
const fixed = Gtk.Fixed.new(); const fixed = Gtk.Fixed.new();
@ -70,93 +71,23 @@ const Workspace = (id, name, extra = false) => {
properties: [ properties: [
['id', id], ['id', id],
['name', name], ['name', name],
['timeouts', []],
['wasActive', false],
], ],
connections: [[Hyprland, box => { connections: [[Hyprland, box => {
box._timeouts.forEach(timer => {
GLib.source_remove(timer);
box._timeouts.remove(timer);
});
const activeId = Hyprland.active.workspace.id; const activeId = Hyprland.active.workspace.id;
const active = activeId === box._id; const active = activeId === box._id;
const rev = box.child.child.get_children()[1]; box.revealChild = Hyprland.getWorkspace(box._id)?.windows > 0 || active;
const n = activeId > box._id;
if (Hyprland.getWorkspace(box._id)?.windows > 0 || active) {
rev.setStyle(DEFAULT_STYLE);
const timer = Utils.timeout(100, () => {
box.revealChild = true;
box._timeouts.remove(timer);
});
box._timeouts.push(timer);
}
else if (!Hyprland.getWorkspace(box._id)?.windows > 0) {
rev.setStyle(DEFAULT_STYLE);
const timer = Utils.timeout(100, () => {
box.revealChild = false;
box._timeouts.remove(timer);
});
box._timeouts.push(timer);
return;
}
if (active) {
rev.setStyle(`${DEFAULT_STYLE}
transition: margin 0.5s ease-in-out;
opacity: 1;`);
box._wasActive = true;
}
else if (box._wasActive) {
const timer1 = Utils.timeout(120, () => {
rev.setStyle(`${DEFAULT_STYLE}
transition: margin 0.5s ease-in-out;
opacity: 1; margin-left: ${n ? '' : '-'}300px;
margin-right: ${n ? '-' : ''}300px;`);
box._wasActive = false;
box._timeouts.remove(timer1);
});
box._timeouts.push(timer1);
const timer2 = Utils.timeout(500, () => {
rev.setStyle(`${DEFAULT_STYLE} opacity: 0;
margin-left: ${n ? '' : '-'}300px;
margin-right: ${n ? '-' : ''}300px;`);
box._timeouts.remove(timer2);
});
box._timeouts.push(timer2);
}
else {
rev.setStyle(`${DEFAULT_STYLE} opacity: 0;
margin-left: ${n ? '' : '-'}300px;
margin-right: ${n ? '-' : ''}300px;`);
}
}]], }]],
child: WorkspaceDrop({ child: WorkspaceDrop({
child: Overlay({ child: Box({
child: Box({ className: 'workspace',
className: 'workspace active', style: DEFAULT_STYLE,
style: `${DEFAULT_STYLE} opacity: 0;`, child: fixed,
}),
overlays: [
Box({
className: 'workspace active',
style: `${DEFAULT_STYLE} opacity: 0;`,
}),
Box({
className: 'workspace',
style: DEFAULT_STYLE,
child: fixed,
}),
],
}), }),
}), }),
}); });
} }
// 'add' workspace
else { else {
workspace = Revealer({ workspace = Revealer({
transition: 'slide_right', transition: 'slide_right',
@ -165,25 +96,14 @@ const Workspace = (id, name, extra = false) => {
['name', name], ['name', name],
], ],
child: WorkspaceDrop({ child: WorkspaceDrop({
child: Overlay({ child: Box({
child: Box({ style: `min-width: ${VARS.SCREEN.X * VARS.SCALE / 2}px;
className: 'workspace', min-height: ${VARS.SCREEN.Y * VARS.SCALE}px;`,
style: DEFAULT_STYLE, children: [
}), fixed,
overlays: [ Label({
Box({ label: ' +',
className: 'workspace active', style: 'font-size: 40px;',
style: `${DEFAULT_STYLE} opacity: 0;`,
}),
Box({
style: DEFAULT_STYLE,
children: [
fixed,
Label({
label: ' +',
style: 'font-size: 40px;',
}),
],
}), }),
], ],
}), }),

View file

@ -1,4 +1,8 @@
.overview { .overview {
background-color: rgba($bgfull, 0.4);
border: 2px solid $contrast-bg;
border-radius: 10px;
.workspace { .workspace {
padding: 4px 15px 4px 0; padding: 4px 15px 4px 0;
border: 2px solid transparent; border: 2px solid transparent;

View file

@ -30,6 +30,7 @@ exec-once = gnome-keyring-daemon --start --components=secrets
exec-once = squeekboard exec-once = squeekboard
exec-once = bash -c "sleep 3; ags -t applauncher" exec-once = bash -c "sleep 3; ags -t applauncher"
layerrule = blur, overview
exec-once = hyprpaper exec-once = hyprpaper
exec-once = wl-paste --watch cliphist store exec-once = wl-paste --watch cliphist store