mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
user config round 1 (#271)
This commit is contained in:
parent
99b8b92889
commit
29fdbd376f
20 changed files with 170 additions and 224 deletions
|
|
@ -4,6 +4,8 @@ import Gdk from 'gi://Gdk';
|
|||
import GLib from 'gi://GLib';
|
||||
import App from 'resource:///com/github/Aylur/ags/app.js'
|
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
||||
// Stuff
|
||||
import userOptions from './user_options.js';
|
||||
// Widgets
|
||||
import { Bar, BarCornerTopleft, BarCornerTopright } from './modules/bar/main.js';
|
||||
import Cheatsheet from './modules/cheatsheet/main.js';
|
||||
|
|
|
|||
13
.config/ags/modules/.miscutils/icons.js
Normal file
13
.config/ags/modules/.miscutils/icons.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
const { Gtk } = imports.gi;
|
||||
|
||||
export function iconExists(iconName) {
|
||||
let iconTheme = Gtk.IconTheme.get_default();
|
||||
return iconTheme.has_icon(iconName);
|
||||
}
|
||||
|
||||
export function substitute(str) {
|
||||
if(userOptions.icons.substitutions[str]) return userOptions.icons.substitutions[str];
|
||||
|
||||
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, '-'); // Turn into kebab-case
|
||||
return str;
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|||
const { Box, DrawingArea, EventBox } = Widget;
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
|
||||
const NUM_OF_WORKSPACES_SHOWN = 10; // Limit = 53 I think
|
||||
const dummyWs = Box({ className: 'bar-ws-focus' }); // Not shown. Only for getting size props
|
||||
const dummyActiveWs = Box({ className: 'bar-ws-focus bar-ws-focus-active' }); // Not shown. Only for getting size props
|
||||
const dummyOccupiedWs = Box({ className: 'bar-ws-focus bar-ws-focus-occupied' }); // Not shown. Only for getting size props
|
||||
|
|
@ -21,8 +20,7 @@ const ceil = Math.ceil;
|
|||
// Font size = workspace id
|
||||
const WorkspaceContents = (count = 10) => {
|
||||
return DrawingArea({
|
||||
className: 'element-decel',
|
||||
// css: `transition: 300ms cubic-bezier(0.1, 1, 0, 1);`,
|
||||
className: 'menu-decel',
|
||||
attribute: {
|
||||
lastImmediateActiveWs: 0,
|
||||
immediateActiveWs: 0,
|
||||
|
|
@ -30,7 +28,7 @@ const WorkspaceContents = (count = 10) => {
|
|||
workspaceMask: 0,
|
||||
workspaceGroup: 0,
|
||||
updateMask: (self) => {
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * NUM_OF_WORKSPACES_SHOWN;
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
||||
// if (self.attribute.initialized) return; // We only need this to run once
|
||||
const workspaces = Hyprland.workspaces;
|
||||
let workspaceMask = 0;
|
||||
|
|
@ -66,7 +64,7 @@ const WorkspaceContents = (count = 10) => {
|
|||
})
|
||||
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
|
||||
.on('draw', Lang.bind(area, (area, cr) => {
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * NUM_OF_WORKSPACES_SHOWN;
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
||||
|
||||
const allocation = area.get_allocation();
|
||||
const { width, height } = allocation;
|
||||
|
|
@ -186,7 +184,7 @@ export default () => EventBox({
|
|||
children: [Box({
|
||||
// className: 'bar-group bar-group-standalone bar-group-pad',
|
||||
css: 'min-width: 2px;',
|
||||
children: [WorkspaceContents(NUM_OF_WORKSPACES_SHOWN)],
|
||||
children: [WorkspaceContents(userOptions.workspaces.shown)],
|
||||
})]
|
||||
}),
|
||||
setup: (self) => {
|
||||
|
|
@ -195,7 +193,7 @@ export default () => EventBox({
|
|||
if (!self.attribute.clicked) return;
|
||||
const [_, cursorX, cursorY] = event.get_coords();
|
||||
const widgetWidth = self.get_allocation().width;
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_SHOWN / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
||||
.catch(print);
|
||||
})
|
||||
|
|
@ -206,7 +204,7 @@ export default () => EventBox({
|
|||
const widgetWidth = self.get_allocation().width;
|
||||
// const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_PER_GROUP / widgetWidth) + self.attribute.ws_group * NUM_OF_WORKSPACES_PER_GROUP;
|
||||
// Hyprland.messageAsync(`dispatch workspace ${wsId}`).catch(print);
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_SHOWN / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
||||
.catch(print);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
|||
const { execAsync, exec } = Utils;
|
||||
const { Box, DrawingArea, EventBox } = Widget;
|
||||
|
||||
const NUM_OF_WORKSPACES = 10;
|
||||
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
|
||||
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
|
||||
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
|
||||
|
|
@ -168,7 +167,7 @@ export default () => EventBox({
|
|||
if (!self.attribute.clicked) return;
|
||||
const [_, cursorX, cursorY] = event.get_coords();
|
||||
const widgetWidth = self.get_allocation().width;
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
switchToWorkspace(wsId);
|
||||
})
|
||||
self.on('button-press-event', (self, event) => {
|
||||
|
|
@ -176,7 +175,7 @@ export default () => EventBox({
|
|||
self.attribute.clicked = true;
|
||||
const [_, cursorX, cursorY] = event.get_coords();
|
||||
const widgetWidth = self.get_allocation().width;
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
switchToWorkspace(wsId);
|
||||
})
|
||||
self.on('button-release-event', (self) => self.attribute.clicked = false);
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import { enableClickthrough } from "../.widgetutils/clickthrough.js";
|
|||
import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js";
|
||||
import { currentShellMode } from '../../variables.js';
|
||||
|
||||
const BATTERY_LOW = 20;
|
||||
|
||||
const NormalOptionalWorkspaces = async () => {
|
||||
try {
|
||||
return (await import('./normal/workspaces_hyprland.js')).default();
|
||||
|
|
@ -80,8 +78,7 @@ export const Bar = async (monitor = 0) => {
|
|||
setup: (self) => {
|
||||
self.hook(Battery, (self) => {
|
||||
if(!Battery.available) return;
|
||||
print(Battery.percent)
|
||||
self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= BATTERY_LOW);
|
||||
self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= userOptions.battery.low);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,22 +9,14 @@ import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
|
|||
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
|
||||
import { WWO_CODE, WEATHER_SYMBOL, NIGHT_WEATHER_SYMBOL } from '../../.commondata/weather.js';
|
||||
|
||||
const BATTERY_LOW = 20;
|
||||
const WEATHER_CACHE_FOLDER = `${GLib.get_user_cache_dir()}/ags/weather`;
|
||||
Utils.exec(`mkdir -p ${WEATHER_CACHE_FOLDER}`);
|
||||
|
||||
let WEATHER_CITY = '';
|
||||
try {
|
||||
WEATHER_CITY = GLib.getenv('AGS_WEATHER_CITY');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
const BatBatteryProgress = () => {
|
||||
const _updateProgress = (circprog) => { // Set circular progress value
|
||||
circprog.css = `font-size: ${Math.abs(Battery.percent)}px;`
|
||||
|
||||
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= BATTERY_LOW);
|
||||
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= userOptions.battery.low);
|
||||
circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
|
||||
}
|
||||
return AnimatedCircProg({
|
||||
|
|
@ -119,7 +111,7 @@ const BarBattery = () => Box({
|
|||
MaterialIcon('settings_heart', 'small'),
|
||||
],
|
||||
setup: (self) => self.hook(Battery, box => {
|
||||
box.toggleClassName('bar-batt-low', Battery.percent <= BATTERY_LOW);
|
||||
box.toggleClassName('bar-batt-low', Battery.percent <= userOptions.battery.low);
|
||||
box.toggleClassName('bar-batt-full', Battery.charged);
|
||||
}),
|
||||
}),
|
||||
|
|
@ -192,8 +184,8 @@ const BatteryModule = () => Stack({
|
|||
print(err);
|
||||
}
|
||||
});
|
||||
if (WEATHER_CITY != '' && WEATHER_CITY != null) {
|
||||
updateWeatherForCity(WEATHER_CITY);
|
||||
if (userOptions.weather.city != '' && userOptions.weather.city != null) {
|
||||
updateWeatherForCity(userOptions.weather.city);
|
||||
}
|
||||
else {
|
||||
Utils.execAsync('curl ipinfo.io')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
const { Gtk } = imports.gi;
|
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
|
||||
const { Box, Icon, Button, Revealer } = Widget;
|
||||
|
|
@ -23,52 +22,6 @@ const SysTrayItem = (item) => Button({
|
|||
export const Tray = (props = {}) => {
|
||||
const trayContent = Box({
|
||||
className: 'margin-right-5 spacing-h-15',
|
||||
// attribute: {
|
||||
// items: new Map(),
|
||||
// addItem: (box, item) => {
|
||||
// if (!item) return;
|
||||
// console.log('init item:', item)
|
||||
|
||||
// item.menu.className = 'menu';
|
||||
// if (box.attribute.items.has(item.id) || !item)
|
||||
// return;
|
||||
// const widget = SysTrayItem(item);
|
||||
// box.attribute.items.set(item.id, widget);
|
||||
// box.add(widget);
|
||||
// box.show_all();
|
||||
// },
|
||||
// onAdded: (box, id) => {
|
||||
// console.log('supposed to add', id)
|
||||
// const item = SystemTray.getItem(id);
|
||||
// if (!item) return;
|
||||
// console.log('which is', box.attribute.items.get(id))
|
||||
|
||||
// item.menu.className = 'menu';
|
||||
// if (box.attribute.items.has(id) || !item)
|
||||
// return;
|
||||
// const widget = SysTrayItem(item);
|
||||
// box.attribute.items.set(id, widget);
|
||||
// box.add(widget);
|
||||
// box.show_all();
|
||||
// },
|
||||
// onRemoved: (box, id) => {
|
||||
// console.log('supposed to remove', id)
|
||||
// if (!box.attribute.items.has(id)) return;
|
||||
// console.log('which is', box.attribute.items.get(id))
|
||||
// box.attribute.items.get(id).destroy();
|
||||
// box.attribute.items.delete(id);
|
||||
// },
|
||||
// },
|
||||
// setup: (self) => {
|
||||
// // self.hook(SystemTray, (box, id) => box.attribute.onAdded(box, id), 'added')
|
||||
// // .hook(SystemTray, (box, id) => box.attribute.onRemoved(box, id), 'removed');
|
||||
// // SystemTray.items.forEach(item => self.attribute.addItem(self, item));
|
||||
// // self.chidren = SystemTray.items.map(item => SysTrayItem(item));
|
||||
// console.log(SystemTray.items.map(item => SysTrayItem(item)))
|
||||
// self.chidren = SystemTray.items.map(item => SysTrayItem(item));
|
||||
|
||||
// self.show_all();
|
||||
// },
|
||||
setup: (self) => self
|
||||
.hook(SystemTray, (self) => {
|
||||
self.children = SystemTray.items.map(SysTrayItem);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|||
const { Box, DrawingArea, EventBox } = Widget;
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
|
||||
const NUM_OF_WORKSPACES_SHOWN = 10; // Limit = 53 I think
|
||||
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
|
||||
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
|
||||
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
|
||||
|
|
@ -23,7 +22,7 @@ const WorkspaceContents = (count = 10) => {
|
|||
workspaceMask: 0,
|
||||
workspaceGroup: 0,
|
||||
updateMask: (self) => {
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * NUM_OF_WORKSPACES_SHOWN;
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
||||
// if (self.attribute.initialized) return; // We only need this to run once
|
||||
const workspaces = Hyprland.workspaces;
|
||||
let workspaceMask = 0;
|
||||
|
|
@ -56,7 +55,7 @@ const WorkspaceContents = (count = 10) => {
|
|||
})
|
||||
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
|
||||
.on('draw', Lang.bind(area, (area, cr) => {
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * NUM_OF_WORKSPACES_SHOWN;
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
||||
|
||||
const allocation = area.get_allocation();
|
||||
const { width, height } = allocation;
|
||||
|
|
@ -162,7 +161,7 @@ export default () => EventBox({
|
|||
children: [Box({
|
||||
className: 'bar-group bar-group-standalone bar-group-pad',
|
||||
css: 'min-width: 2px;',
|
||||
children: [WorkspaceContents(NUM_OF_WORKSPACES_SHOWN)],
|
||||
children: [WorkspaceContents(userOptions.workspaces.shown)],
|
||||
})]
|
||||
}),
|
||||
setup: (self) => {
|
||||
|
|
@ -171,7 +170,7 @@ export default () => EventBox({
|
|||
if (!self.attribute.clicked) return;
|
||||
const [_, cursorX, cursorY] = event.get_coords();
|
||||
const widgetWidth = self.get_allocation().width;
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_SHOWN / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
||||
.catch(print);
|
||||
})
|
||||
|
|
@ -182,7 +181,7 @@ export default () => EventBox({
|
|||
const widgetWidth = self.get_allocation().width;
|
||||
// const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_PER_GROUP / widgetWidth) + self.attribute.ws_group * NUM_OF_WORKSPACES_PER_GROUP;
|
||||
// Hyprland.messageAsync(`dispatch workspace ${wsId}`).catch(print);
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_SHOWN / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
||||
.catch(print);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
|||
const { execAsync, exec } = Utils;
|
||||
const { Box, DrawingArea, EventBox } = Widget;
|
||||
|
||||
const NUM_OF_WORKSPACES = 10;
|
||||
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
|
||||
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
|
||||
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
|
||||
|
|
@ -168,7 +167,7 @@ export default () => EventBox({
|
|||
if (!self.attribute.clicked) return;
|
||||
const [_, cursorX, cursorY] = event.get_coords();
|
||||
const widgetWidth = self.get_allocation().width;
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
switchToWorkspace(wsId);
|
||||
})
|
||||
self.on('button-press-event', (self, event) => {
|
||||
|
|
@ -176,7 +175,7 @@ export default () => EventBox({
|
|||
self.attribute.clicked = true;
|
||||
const [_, cursorX, cursorY] = event.get_coords();
|
||||
const widgetWidth = self.get_allocation().width;
|
||||
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES / widgetWidth);
|
||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
||||
switchToWorkspace(wsId);
|
||||
})
|
||||
self.on('button-release-event', (self) => self.attribute.clicked = false);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
|
||||
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
|
||||
const { Box, Label } = Widget;
|
||||
import { showColorScheme } from '../../variables.js';
|
||||
|
||||
const ColorBox = ({
|
||||
|
|
|
|||
|
|
@ -11,18 +11,9 @@ import { showMusicControls } from '../../variables.js';
|
|||
|
||||
const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
|
||||
|
||||
function expandTilde(path) {
|
||||
if (path.startsWith('~')) {
|
||||
return GLib.get_home_dir() + path.slice(1);
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_cache_dir()}/ags/user/colormode.txt`;
|
||||
const lightDark = Utils.readFile(expandTilde(LIGHTDARK_FILE_LOCATION)).trim();
|
||||
const lightDark = Utils.readFile(LIGHTDARK_FILE_LOCATION).trim();
|
||||
const COVER_COLORSCHEME_SUFFIX = '_colorscheme.css';
|
||||
const PREFERRED_PLAYER = 'plasma-browser-integration';
|
||||
var lastCoverPath = '';
|
||||
|
||||
function isRealPlayer(player) {
|
||||
|
|
@ -33,7 +24,7 @@ function isRealPlayer(player) {
|
|||
);
|
||||
}
|
||||
|
||||
export const getPlayer = (name = PREFERRED_PLAYER) => Mpris.getPlayer(name) || Mpris.players[0] || null;
|
||||
export const getPlayer = (name = userOptions.music.preferredPlayer) => Mpris.getPlayer(name) || Mpris.players[0] || null;
|
||||
function lengthStr(length) {
|
||||
const min = Math.floor(length / 60);
|
||||
const sec = Math.floor(length % 60);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// We're going to use ydotool
|
||||
// See /usr/include/linux/input-event-codes.h for keycodes
|
||||
|
||||
export const defaultOskLayout = "qwerty_full"
|
||||
export const DEFAULT_OSK_LAYOUT = "qwerty_full"
|
||||
export const oskLayouts = {
|
||||
qwerty_full: {
|
||||
name: "QWERTY - Full",
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|||
const { Box, EventBox, Button, Revealer } = Widget;
|
||||
const { execAsync } = Utils;
|
||||
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
|
||||
import { defaultOskLayout, oskLayouts } from './data_keyboardlayouts.js';
|
||||
import { DEFAULT_OSK_LAYOUT, oskLayouts } from './data_keyboardlayouts.js';
|
||||
import { setupCursorHoverGrab } from '../.widgetutils/cursorhover.js';
|
||||
|
||||
const keyboardLayout = defaultOskLayout;
|
||||
const keyboardLayout = oskLayouts[userOptions.onScreenKeyboard.layout] ? userOptions.onScreenKeyboard.layout : DEFAULT_OSK_LAYOUT;
|
||||
const keyboardJson = oskLayouts[keyboardLayout];
|
||||
execAsync(`ydotoold`).catch(print); // Start ydotool daemon
|
||||
|
||||
|
|
|
|||
|
|
@ -14,41 +14,13 @@ import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
|||
const { execAsync, exec } = Utils;
|
||||
import { setupCursorHoverGrab } from '../.widgetutils/cursorhover.js';
|
||||
import { dumpToWorkspace, swapWorkspace } from "./actions.js";
|
||||
import { substitute } from "../.miscutils/icons.js";
|
||||
|
||||
const OVERVIEW_SCALE = 0.18;
|
||||
const NUM_OF_WORKSPACE_ROWS = 2;
|
||||
const NUM_OF_WORKSPACE_COLS = 5;
|
||||
const OVERVIEW_WS_NUM_SCALE = 0.09;
|
||||
const NUM_OF_WORKSPACES_SHOWN = NUM_OF_WORKSPACE_COLS * NUM_OF_WORKSPACE_ROWS;
|
||||
const OVERVIEW_WS_NUM_MARGIN_SCALE = 0.07;
|
||||
const NUM_OF_WORKSPACES_SHOWN = userOptions.overview.numOfCols * userOptions.overview.numOfRows;
|
||||
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
|
||||
|
||||
const overviewTick = Variable(false);
|
||||
|
||||
function iconExists(iconName) {
|
||||
let iconTheme = Gtk.IconTheme.get_default();
|
||||
return iconTheme.has_icon(iconName);
|
||||
}
|
||||
|
||||
function substitute(str) {
|
||||
const subs = [
|
||||
{ from: 'code-url-handler', to: 'visual-studio-code' },
|
||||
{ from: 'Code', to: 'visual-studio-code' },
|
||||
{ from: 'GitHub Desktop', to: 'github-desktop' },
|
||||
{ from: 'wps', to: 'wps-office2019-kprometheus' },
|
||||
{ from: 'gnome-tweaks', to: 'org.gnome.tweaks' },
|
||||
{ from: 'Minecraft* 1.20.1', to: 'minecraft' },
|
||||
{ from: '', to: 'image-missing' },
|
||||
];
|
||||
|
||||
for (const { from, to } of subs) {
|
||||
if (from === str)
|
||||
return to;
|
||||
}
|
||||
|
||||
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, '-'); // Turn into kebab-case
|
||||
return str;
|
||||
}
|
||||
export default () => {
|
||||
const clientMap = new Map();
|
||||
let workspaceGroup = 0;
|
||||
|
|
@ -78,7 +50,7 @@ export default () => {
|
|||
})
|
||||
|
||||
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);
|
||||
const revealInfoCondition = (Math.min(w, h) * userOptions.overview.scale > 70);
|
||||
if (w <= 0 || h <= 0 || (c === '' && title === '')) return null;
|
||||
// Non-primary monitors
|
||||
if (screenCoords.x != 0) x -= screenCoords.x;
|
||||
|
|
@ -94,23 +66,23 @@ export default () => {
|
|||
|
||||
const appIcon = Widget.Icon({
|
||||
icon: substitute(c),
|
||||
size: Math.min(w, h) * OVERVIEW_SCALE / 2.5,
|
||||
size: Math.min(w, h) * userOptions.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;
|
||||
appIcon.size = Math.min(self.attribute.w, self.attribute.h) * userOptions.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;
|
||||
margin-left: ${Math.round(x * userOptions.overview.scale)}px;
|
||||
margin-top: ${Math.round(y * userOptions.overview.scale)}px;
|
||||
margin-right: -${Math.round((x + w) * userOptions.overview.scale)}px;
|
||||
margin-bottom: -${Math.round((y + h) * userOptions.overview.scale)}px;
|
||||
`,
|
||||
onClicked: (self) => {
|
||||
App.closeWindow('overview');
|
||||
|
|
@ -167,8 +139,8 @@ export default () => {
|
|||
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;
|
||||
font-size: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale / 14.6}px;
|
||||
margin: 0px ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale / 10}px;
|
||||
`,
|
||||
// If the title is too short, include the class
|
||||
label: (title.length <= 1 ? `${c}: ${title}` : title),
|
||||
|
|
@ -211,12 +183,12 @@ export default () => {
|
|||
attribute: {
|
||||
put: (widget, x, y) => {
|
||||
if (!widget.attribute) return;
|
||||
// Note: x and y are already multiplied by OVERVIEW_SCALE
|
||||
// Note: x and y are already multiplied by userOptions.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;
|
||||
margin-right: -${Math.round(x + (widget.attribute.w * userOptions.overview.scale))}px;
|
||||
margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px;
|
||||
`;
|
||||
widget.css = newCss;
|
||||
fixed.pack_start(widget, false, false, 0);
|
||||
|
|
@ -224,12 +196,12 @@ export default () => {
|
|||
move: (widget, x, y) => {
|
||||
if (!widget) return;
|
||||
if (!widget.attribute) return;
|
||||
// Note: x and y are already multiplied by OVERVIEW_SCALE
|
||||
// Note: x and y are already multiplied by userOptions.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;
|
||||
margin-right: -${Math.round(x + (widget.attribute.w * userOptions.overview.scale))}px;
|
||||
margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px;
|
||||
`;
|
||||
widget.css = newCss;
|
||||
},
|
||||
|
|
@ -239,16 +211,16 @@ export default () => {
|
|||
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;
|
||||
margin: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale * userOptions.overview.wsNumMarginScale}px;
|
||||
font-size: ${SCREEN_HEIGHT * userOptions.overview.scale * userOptions.overview.wsNumScale}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;
|
||||
min-width: ${SCREEN_WIDTH * userOptions.overview.scale}px;
|
||||
min-height: ${SCREEN_HEIGHT * userOptions.overview.scale}px;
|
||||
`,
|
||||
children: [Widget.EventBox({
|
||||
hexpand: true,
|
||||
|
|
@ -295,8 +267,8 @@ export default () => {
|
|||
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)
|
||||
Math.max(0, clientJson.at[0] * userOptions.overview.scale),
|
||||
Math.max(0, clientJson.at[1] * userOptions.overview.scale)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -305,8 +277,8 @@ export default () => {
|
|||
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)
|
||||
Math.max(0, newWindow.attribute.x * userOptions.overview.scale),
|
||||
Math.max(0, newWindow.attribute.y * userOptions.overview.scale)
|
||||
);
|
||||
clientMap.set(clientJson.address, newWindow);
|
||||
};
|
||||
|
|
@ -427,10 +399,10 @@ export default () => {
|
|||
child: Widget.Box({
|
||||
vertical: true,
|
||||
className: 'overview-tasks',
|
||||
children: Array.from({ length: NUM_OF_WORKSPACE_ROWS }, (_, index) =>
|
||||
children: Array.from({ length: userOptions.overview.numOfRows }, (_, index) =>
|
||||
OverviewRow({
|
||||
startWorkspace: 1 + index * NUM_OF_WORKSPACE_COLS,
|
||||
workspaces: NUM_OF_WORKSPACE_COLS,
|
||||
startWorkspace: 1 + index * userOptions.overview.numOfCols,
|
||||
workspaces: userOptions.overview.numOfCols,
|
||||
})
|
||||
)
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -158,6 +158,6 @@ export const SearchButton = ({ text = '' }) => searchItem({
|
|||
content: `${text}`,
|
||||
onActivate: () => {
|
||||
App.closeWindow('overview');
|
||||
execAsync(['bash', '-c', `xdg-open 'https://www.google.com/search?q=${text} -site:quora.com' &`]).catch(print); // quora is useless
|
||||
execAsync(['bash', '-c', `xdg-open 'https://www.google.com/search?q=${text} ${['', ...userOptions.search.excludedSites].join(' -site:')}' &`]).catch(print);
|
||||
},
|
||||
});
|
||||
|
|
@ -140,7 +140,7 @@ export const SearchAndWindows = () => {
|
|||
|
||||
else {
|
||||
App.closeWindow('overview');
|
||||
execAsync(['bash', '-c', `xdg-open 'https://www.google.com/search?q=${text} -site:quora.com' &`]).catch(print); // quora is useless
|
||||
execAsync(['bash', '-c', `xdg-open 'https://www.google.com/search?q=${text} ${['', ...userOptions.search.excludedSites].join(' -site:')}' &`]).catch(print);
|
||||
}
|
||||
},
|
||||
onChange: (entry) => { // this is when you type
|
||||
|
|
|
|||
|
|
@ -70,6 +70,32 @@ export default () => {
|
|||
const shutdownButton = SessionButton('Shutdown', 'power_settings_new', () => { App.closeWindow('session'); execAsync('systemctl poweroff') });
|
||||
const rebootButton = SessionButton('Reboot', 'restart_alt', () => { App.closeWindow('session'); execAsync('systemctl reboot') });
|
||||
const cancelButton = SessionButton('Cancel', 'close', () => App.closeWindow('session'), { className: 'session-button-cancel' });
|
||||
|
||||
const sessionDescription = Widget.Box({
|
||||
vertical: true,
|
||||
css: 'margin-bottom: 0.682rem;',
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'txt-title txt',
|
||||
label: 'Session',
|
||||
}),
|
||||
Widget.Label({
|
||||
justify: Gtk.Justification.CENTER,
|
||||
className: 'txt-small txt',
|
||||
label: 'Use arrow keys to navigate.\nEnter to select, Esc to cancel.'
|
||||
}),
|
||||
]
|
||||
});
|
||||
const SessionButtonRow = (children) => Widget.Box({
|
||||
hpack: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: children,
|
||||
});
|
||||
const sessionButtonRows = [
|
||||
SessionButtonRow([lockButton, logoutButton, sleepButton]),
|
||||
SessionButtonRow([hibernateButton, shutdownButton, rebootButton]),
|
||||
SessionButtonRow([cancelButton]),
|
||||
]
|
||||
return Widget.Box({
|
||||
className: 'session-bg',
|
||||
css: `
|
||||
|
|
@ -93,46 +119,8 @@ export default () => {
|
|||
vertical: true,
|
||||
className: 'spacing-v-15',
|
||||
children: [
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
css: 'margin-bottom: 0.682rem;',
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'txt-title txt',
|
||||
label: 'Session',
|
||||
}),
|
||||
Widget.Label({
|
||||
justify: Gtk.Justification.CENTER,
|
||||
className: 'txt-small txt',
|
||||
label: 'Use arrow keys to navigate.\nEnter to select, Esc to cancel.'
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
hpack: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: [ // lock, logout, sleep
|
||||
lockButton,
|
||||
logoutButton,
|
||||
sleepButton,
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
hpack: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: [ // hibernate, shutdown, reboot
|
||||
hibernateButton,
|
||||
shutdownButton,
|
||||
rebootButton,
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
hpack: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: [ // hibernate, shutdown, reboot
|
||||
cancelButton,
|
||||
]
|
||||
}),
|
||||
sessionDescription,
|
||||
...sessionButtonRows,
|
||||
]
|
||||
})
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,30 +1,29 @@
|
|||
$darkmode: true;
|
||||
$primary: #e2e2e2;
|
||||
$onPrimary: #000000;
|
||||
$primaryContainer: #6b6b6b;
|
||||
$onPrimaryContainer: #e2e2e2;
|
||||
$secondary: #e2e2e2;
|
||||
$onSecondary: #000000;
|
||||
$secondaryContainer: #313131;
|
||||
$onSecondaryContainer: #e2e2e2;
|
||||
$tertiary: #e2e2e2;
|
||||
$onTertiary: #000000;
|
||||
$tertiaryContainer: #000000;
|
||||
$onTertiaryContainer: #e2e2e2;
|
||||
$error: #e2e2e2;
|
||||
$onError: #000000;
|
||||
$errorContainer: #000000;
|
||||
$onErrorContainer: #e2e2e2;
|
||||
$colorbarbg: #000000;
|
||||
$background: #000000;
|
||||
$onBackground: #e2e2e2;
|
||||
$surface: #161616;
|
||||
$onSurface: #e2e2e2;
|
||||
$surfaceVariant: #242424;
|
||||
$onSurfaceVariant: #e2e2e2;
|
||||
$outline: #a1a1a1;
|
||||
$primary: #ffb4a9;
|
||||
$onPrimary: #5f1410;
|
||||
$primaryContainer: #7e2b24;
|
||||
$onPrimaryContainer: #ffdad4;
|
||||
$secondary: #e7bcb7;
|
||||
$onSecondary: #442926;
|
||||
$secondaryContainer: #5d3f3b;
|
||||
$onSecondaryContainer: #ffdad5;
|
||||
$tertiary: #e0c38c;
|
||||
$onTertiary: #3f2e04;
|
||||
$tertiaryContainer: #574419;
|
||||
$onTertiaryContainer: #fddfa6;
|
||||
$error: #ffb4a9;
|
||||
$onError: #680003;
|
||||
$errorContainer: #930006;
|
||||
$onErrorContainer: #ffb4a9;
|
||||
$colorbarbg: #130F0F;
|
||||
$background: #130F0F;
|
||||
$onBackground: #ede0de;
|
||||
$surface: #211a19;
|
||||
$onSurface: #ede0de;
|
||||
$surfaceVariant: #534341;
|
||||
$onSurfaceVariant: #d8c2bf;
|
||||
$outline: #a08c89;
|
||||
$shadow: #000000;
|
||||
$inverseSurface: #e2e2e2;
|
||||
$inverseOnSurface: #000000;
|
||||
$inversePrimary: #e2e2e2;
|
||||
|
||||
$inverseSurface: #ede0de;
|
||||
$inverseOnSurface: #362f2e;
|
||||
$inversePrimary: #9c4239;
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
||||
43
.config/ags/user_options.js
Normal file
43
.config/ags/user_options.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
let userConfigOptions = {
|
||||
'battery': {
|
||||
'low': 20,
|
||||
'critical': 10,
|
||||
},
|
||||
'music': {
|
||||
'preferredPlayer': 'plasma-browser-integration',
|
||||
},
|
||||
'onScreenKeyboard': {
|
||||
'layout': 'qwerty_full', // See modules/onscreenkeyboard/onscreenkeyboard.js for available layouts
|
||||
},
|
||||
'overview': {
|
||||
'scale': 0.18,
|
||||
'numOfRows': 2,
|
||||
'numOfCols': 5,
|
||||
'wsNumScale': 0.09,
|
||||
'wsNumMarginScale': 0.07,
|
||||
},
|
||||
'search': {
|
||||
'excludedSites': ['quora.com'], // Exclude bullshit
|
||||
},
|
||||
'weather': {
|
||||
'city': '',
|
||||
},
|
||||
'workspaces': {
|
||||
'shown': 10,
|
||||
},
|
||||
icons: {
|
||||
substitutions: {
|
||||
'code-url-handler': 'visual-studio-code',
|
||||
'Code': 'visual-studio-code',
|
||||
'GitHub Desktop': 'github-desktop',
|
||||
'wps': 'wps-office2019-kprometheus',
|
||||
'gnome-tweaks': 'org.gnome.tweaks',
|
||||
'Minecraft* 1.20.1': 'minecraft',
|
||||
'': 'image-missing',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globalThis['userOptions'] = userConfigOptions;
|
||||
export default userOptions;
|
||||
Loading…
Reference in a new issue