feat(ags overview): redesign workspace overview
This commit is contained in:
parent
8dd83e99ca
commit
297e274c9a
6 changed files with 103 additions and 133 deletions
35
devices/wim/config/ags/js/overview/current-workspace.js
Normal file
35
devices/wim/config/ags/js/overview/current-workspace.js
Normal 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;
|
||||||
|
`);
|
||||||
|
};
|
|
@ -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);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,14 +11,22 @@ 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: Overlay({
|
||||||
|
setup: self => {
|
||||||
|
self.set_overlay_pass_through(
|
||||||
|
self.get_children()[1],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
overlays: [Highlighter()],
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'overview',
|
className: 'overview',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
|
@ -45,5 +54,6 @@ export default () => PopupWindow({
|
||||||
['workspaces'],
|
['workspaces'],
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
}),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 active',
|
|
||||||
style: `${DEFAULT_STYLE} opacity: 0;`,
|
|
||||||
}),
|
|
||||||
overlays: [
|
|
||||||
Box({
|
|
||||||
className: 'workspace active',
|
|
||||||
style: `${DEFAULT_STYLE} opacity: 0;`,
|
|
||||||
}),
|
|
||||||
Box({
|
|
||||||
className: 'workspace',
|
className: 'workspace',
|
||||||
style: DEFAULT_STYLE,
|
style: DEFAULT_STYLE,
|
||||||
child: fixed,
|
child: fixed,
|
||||||
}),
|
}),
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 'add' workspace
|
||||||
else {
|
else {
|
||||||
workspace = Revealer({
|
workspace = Revealer({
|
||||||
transition: 'slide_right',
|
transition: 'slide_right',
|
||||||
|
@ -165,18 +96,9 @@ const Workspace = (id, name, extra = false) => {
|
||||||
['name', name],
|
['name', name],
|
||||||
],
|
],
|
||||||
child: WorkspaceDrop({
|
child: WorkspaceDrop({
|
||||||
child: Overlay({
|
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'workspace',
|
style: `min-width: ${VARS.SCREEN.X * VARS.SCALE / 2}px;
|
||||||
style: DEFAULT_STYLE,
|
min-height: ${VARS.SCREEN.Y * VARS.SCALE}px;`,
|
||||||
}),
|
|
||||||
overlays: [
|
|
||||||
Box({
|
|
||||||
className: 'workspace active',
|
|
||||||
style: `${DEFAULT_STYLE} opacity: 0;`,
|
|
||||||
}),
|
|
||||||
Box({
|
|
||||||
style: DEFAULT_STYLE,
|
|
||||||
children: [
|
children: [
|
||||||
fixed,
|
fixed,
|
||||||
Label({
|
Label({
|
||||||
|
@ -185,8 +107,6 @@ const Workspace = (id, name, extra = false) => {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue