diff --git a/.config/ags/config.js b/.config/ags/config.js index 59d5e74b..415d5e51 100644 --- a/.config/ags/config.js +++ b/.config/ags/config.js @@ -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'; diff --git a/.config/ags/modules/.miscutils/icons.js b/.config/ags/modules/.miscutils/icons.js new file mode 100644 index 00000000..fb1e20da --- /dev/null +++ b/.config/ags/modules/.miscutils/icons.js @@ -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; +} \ No newline at end of file diff --git a/.config/ags/modules/bar/focus/workspaces_hyprland.js b/.config/ags/modules/bar/focus/workspaces_hyprland.js index 5d610ea3..12a3982a 100644 --- a/.config/ags/modules/bar/focus/workspaces_hyprland.js +++ b/.config/ags/modules/bar/focus/workspaces_hyprland.js @@ -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); }) diff --git a/.config/ags/modules/bar/focus/workspaces_sway.js b/.config/ags/modules/bar/focus/workspaces_sway.js index 632b4b56..e40c7c09 100644 --- a/.config/ags/modules/bar/focus/workspaces_sway.js +++ b/.config/ags/modules/bar/focus/workspaces_sway.js @@ -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); diff --git a/.config/ags/modules/bar/main.js b/.config/ags/modules/bar/main.js index 7719919b..da3962ff 100644 --- a/.config/ags/modules/bar/main.js +++ b/.config/ags/modules/bar/main.js @@ -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); }) } }); diff --git a/.config/ags/modules/bar/normal/system.js b/.config/ags/modules/bar/normal/system.js index 63e5fdb3..d2d4ee87 100644 --- a/.config/ags/modules/bar/normal/system.js +++ b/.config/ags/modules/bar/normal/system.js @@ -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') diff --git a/.config/ags/modules/bar/normal/tray.js b/.config/ags/modules/bar/normal/tray.js index 7d180072..53827ca7 100644 --- a/.config/ags/modules/bar/normal/tray.js +++ b/.config/ags/modules/bar/normal/tray.js @@ -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); diff --git a/.config/ags/modules/bar/normal/workspaces_hyprland.js b/.config/ags/modules/bar/normal/workspaces_hyprland.js index f5edfa2f..770ba6bc 100644 --- a/.config/ags/modules/bar/normal/workspaces_hyprland.js +++ b/.config/ags/modules/bar/normal/workspaces_hyprland.js @@ -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); }) diff --git a/.config/ags/modules/bar/normal/workspaces_sway.js b/.config/ags/modules/bar/normal/workspaces_sway.js index 632b4b56..e40c7c09 100644 --- a/.config/ags/modules/bar/normal/workspaces_sway.js +++ b/.config/ags/modules/bar/normal/workspaces_sway.js @@ -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); diff --git a/.config/ags/modules/indicators/colorscheme.js b/.config/ags/modules/indicators/colorscheme.js index 54ecef8a..d5dfd497 100644 --- a/.config/ags/modules/indicators/colorscheme.js +++ b/.config/ags/modules/indicators/colorscheme.js @@ -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 = ({ diff --git a/.config/ags/modules/indicators/musiccontrols.js b/.config/ags/modules/indicators/musiccontrols.js index 6575c69f..6fd44847 100644 --- a/.config/ags/modules/indicators/musiccontrols.js +++ b/.config/ags/modules/indicators/musiccontrols.js @@ -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); diff --git a/.config/ags/modules/onscreenkeyboard/data_keyboardlayouts.js b/.config/ags/modules/onscreenkeyboard/data_keyboardlayouts.js index cb92b8a3..1a67b7a1 100755 --- a/.config/ags/modules/onscreenkeyboard/data_keyboardlayouts.js +++ b/.config/ags/modules/onscreenkeyboard/data_keyboardlayouts.js @@ -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", diff --git a/.config/ags/modules/onscreenkeyboard/onscreenkeyboard.js b/.config/ags/modules/onscreenkeyboard/onscreenkeyboard.js index 2bb9c7bc..1bbc7b1f 100644 --- a/.config/ags/modules/onscreenkeyboard/onscreenkeyboard.js +++ b/.config/ags/modules/onscreenkeyboard/onscreenkeyboard.js @@ -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 diff --git a/.config/ags/modules/overview/overview_hyprland.js b/.config/ags/modules/overview/overview_hyprland.js index 512d3900..55ef9f15 100644 --- a/.config/ags/modules/overview/overview_hyprland.js +++ b/.config/ags/modules/overview/overview_hyprland.js @@ -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, }) ) }), diff --git a/.config/ags/modules/overview/searchbuttons.js b/.config/ags/modules/overview/searchbuttons.js index 15130ad0..8fb40a23 100644 --- a/.config/ags/modules/overview/searchbuttons.js +++ b/.config/ags/modules/overview/searchbuttons.js @@ -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); }, }); \ No newline at end of file diff --git a/.config/ags/modules/overview/windowcontent.js b/.config/ags/modules/overview/windowcontent.js index 4aeced3c..179739a7 100644 --- a/.config/ags/modules/overview/windowcontent.js +++ b/.config/ags/modules/overview/windowcontent.js @@ -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 diff --git a/.config/ags/modules/session/sessionscreen.js b/.config/ags/modules/session/sessionscreen.js index b0665957..6ba47504 100644 --- a/.config/ags/modules/session/sessionscreen.js +++ b/.config/ags/modules/session/sessionscreen.js @@ -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, ] }) ] diff --git a/.config/ags/scss/_material.scss b/.config/ags/scss/_material.scss index cfab8e9f..6bc96ab6 100644 --- a/.config/ags/scss/_material.scss +++ b/.config/ags/scss/_material.scss @@ -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; diff --git a/.config/ags/scss/_musicmaterial.scss b/.config/ags/scss/_musicmaterial.scss index e69de29b..8b137891 100644 --- a/.config/ags/scss/_musicmaterial.scss +++ b/.config/ags/scss/_musicmaterial.scss @@ -0,0 +1 @@ + diff --git a/.config/ags/user_options.js b/.config/ags/user_options.js new file mode 100644 index 00000000..65044da7 --- /dev/null +++ b/.config/ags/user_options.js @@ -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; \ No newline at end of file