user config round 1 (#271)

This commit is contained in:
end-4
2024-03-01 23:18:56 +07:00
parent 7ecbf9b24b
commit e1bb1c9790
20 changed files with 170 additions and 224 deletions
+2
View File
@@ -4,6 +4,8 @@ import Gdk from 'gi://Gdk';
import GLib from 'gi://GLib'; import GLib from 'gi://GLib';
import App from 'resource:///com/github/Aylur/ags/app.js' import App from 'resource:///com/github/Aylur/ags/app.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js' import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
// Stuff
import userOptions from './user_options.js';
// Widgets // Widgets
import { Bar, BarCornerTopleft, BarCornerTopright } from './modules/bar/main.js'; import { Bar, BarCornerTopleft, BarCornerTopright } from './modules/bar/main.js';
import Cheatsheet from './modules/cheatsheet/main.js'; import Cheatsheet from './modules/cheatsheet/main.js';
+13
View 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; const { Box, DrawingArea, EventBox } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js'; 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 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 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 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 // Font size = workspace id
const WorkspaceContents = (count = 10) => { const WorkspaceContents = (count = 10) => {
return DrawingArea({ return DrawingArea({
className: 'element-decel', className: 'menu-decel',
// css: `transition: 300ms cubic-bezier(0.1, 1, 0, 1);`,
attribute: { attribute: {
lastImmediateActiveWs: 0, lastImmediateActiveWs: 0,
immediateActiveWs: 0, immediateActiveWs: 0,
@@ -30,7 +28,7 @@ const WorkspaceContents = (count = 10) => {
workspaceMask: 0, workspaceMask: 0,
workspaceGroup: 0, workspaceGroup: 0,
updateMask: (self) => { 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 // if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Hyprland.workspaces; const workspaces = Hyprland.workspaces;
let workspaceMask = 0; let workspaceMask = 0;
@@ -66,7 +64,7 @@ const WorkspaceContents = (count = 10) => {
}) })
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces') .hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
.on('draw', Lang.bind(area, (area, cr) => { .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 allocation = area.get_allocation();
const { width, height } = allocation; const { width, height } = allocation;
@@ -186,7 +184,7 @@ export default () => EventBox({
children: [Box({ children: [Box({
// className: 'bar-group bar-group-standalone bar-group-pad', // className: 'bar-group bar-group-standalone bar-group-pad',
css: 'min-width: 2px;', css: 'min-width: 2px;',
children: [WorkspaceContents(NUM_OF_WORKSPACES_SHOWN)], children: [WorkspaceContents(userOptions.workspaces.shown)],
})] })]
}), }),
setup: (self) => { setup: (self) => {
@@ -195,7 +193,7 @@ export default () => EventBox({
if (!self.attribute.clicked) return; if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords(); const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width; 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}`]) Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print); .catch(print);
}) })
@@ -206,7 +204,7 @@ export default () => EventBox({
const widgetWidth = self.get_allocation().width; 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; // 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); // 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}`]) Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print); .catch(print);
}) })
@@ -9,7 +9,6 @@ import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
const { execAsync, exec } = Utils; const { execAsync, exec } = Utils;
const { Box, DrawingArea, EventBox } = Widget; const { Box, DrawingArea, EventBox } = Widget;
const NUM_OF_WORKSPACES = 10;
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props 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 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 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; if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords(); const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width; 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); switchToWorkspace(wsId);
}) })
self.on('button-press-event', (self, event) => { self.on('button-press-event', (self, event) => {
@@ -176,7 +175,7 @@ export default () => EventBox({
self.attribute.clicked = true; self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords(); const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width; 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); switchToWorkspace(wsId);
}) })
self.on('button-release-event', (self) => self.attribute.clicked = false); self.on('button-release-event', (self) => self.attribute.clicked = false);
+1 -4
View File
@@ -10,8 +10,6 @@ import { enableClickthrough } from "../.widgetutils/clickthrough.js";
import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js"; import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js";
import { currentShellMode } from '../../variables.js'; import { currentShellMode } from '../../variables.js';
const BATTERY_LOW = 20;
const NormalOptionalWorkspaces = async () => { const NormalOptionalWorkspaces = async () => {
try { try {
return (await import('./normal/workspaces_hyprland.js')).default(); return (await import('./normal/workspaces_hyprland.js')).default();
@@ -80,8 +78,7 @@ export const Bar = async (monitor = 0) => {
setup: (self) => { setup: (self) => {
self.hook(Battery, (self) => { self.hook(Battery, (self) => {
if(!Battery.available) return; if(!Battery.available) return;
print(Battery.percent) self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= userOptions.battery.low);
self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= BATTERY_LOW);
}) })
} }
}); });
+4 -12
View File
@@ -9,22 +9,14 @@ import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js"; import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
import { WWO_CODE, WEATHER_SYMBOL, NIGHT_WEATHER_SYMBOL } from '../../.commondata/weather.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`; const WEATHER_CACHE_FOLDER = `${GLib.get_user_cache_dir()}/ags/weather`;
Utils.exec(`mkdir -p ${WEATHER_CACHE_FOLDER}`); 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 BatBatteryProgress = () => {
const _updateProgress = (circprog) => { // Set circular progress value const _updateProgress = (circprog) => { // Set circular progress value
circprog.css = `font-size: ${Math.abs(Battery.percent)}px;` 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); circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
} }
return AnimatedCircProg({ return AnimatedCircProg({
@@ -119,7 +111,7 @@ const BarBattery = () => Box({
MaterialIcon('settings_heart', 'small'), MaterialIcon('settings_heart', 'small'),
], ],
setup: (self) => self.hook(Battery, box => { 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); box.toggleClassName('bar-batt-full', Battery.charged);
}), }),
}), }),
@@ -192,8 +184,8 @@ const BatteryModule = () => Stack({
print(err); print(err);
} }
}); });
if (WEATHER_CITY != '' && WEATHER_CITY != null) { if (userOptions.weather.city != '' && userOptions.weather.city != null) {
updateWeatherForCity(WEATHER_CITY); updateWeatherForCity(userOptions.weather.city);
} }
else { else {
Utils.execAsync('curl ipinfo.io') Utils.execAsync('curl ipinfo.io')
-47
View File
@@ -1,4 +1,3 @@
const { Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js'; import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
const { Box, Icon, Button, Revealer } = Widget; const { Box, Icon, Button, Revealer } = Widget;
@@ -23,52 +22,6 @@ const SysTrayItem = (item) => Button({
export const Tray = (props = {}) => { export const Tray = (props = {}) => {
const trayContent = Box({ const trayContent = Box({
className: 'margin-right-5 spacing-h-15', 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 setup: (self) => self
.hook(SystemTray, (self) => { .hook(SystemTray, (self) => {
self.children = SystemTray.items.map(SysTrayItem); 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; const { Box, DrawingArea, EventBox } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js'; 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 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 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 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, workspaceMask: 0,
workspaceGroup: 0, workspaceGroup: 0,
updateMask: (self) => { 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 // if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Hyprland.workspaces; const workspaces = Hyprland.workspaces;
let workspaceMask = 0; let workspaceMask = 0;
@@ -56,7 +55,7 @@ const WorkspaceContents = (count = 10) => {
}) })
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces') .hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
.on('draw', Lang.bind(area, (area, cr) => { .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 allocation = area.get_allocation();
const { width, height } = allocation; const { width, height } = allocation;
@@ -162,7 +161,7 @@ export default () => EventBox({
children: [Box({ children: [Box({
className: 'bar-group bar-group-standalone bar-group-pad', className: 'bar-group bar-group-standalone bar-group-pad',
css: 'min-width: 2px;', css: 'min-width: 2px;',
children: [WorkspaceContents(NUM_OF_WORKSPACES_SHOWN)], children: [WorkspaceContents(userOptions.workspaces.shown)],
})] })]
}), }),
setup: (self) => { setup: (self) => {
@@ -171,7 +170,7 @@ export default () => EventBox({
if (!self.attribute.clicked) return; if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords(); const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width; 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}`]) Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print); .catch(print);
}) })
@@ -182,7 +181,7 @@ export default () => EventBox({
const widgetWidth = self.get_allocation().width; 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; // 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); // 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}`]) Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print); .catch(print);
}) })
@@ -9,7 +9,6 @@ import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
const { execAsync, exec } = Utils; const { execAsync, exec } = Utils;
const { Box, DrawingArea, EventBox } = Widget; const { Box, DrawingArea, EventBox } = Widget;
const NUM_OF_WORKSPACES = 10;
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props 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 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 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; if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords(); const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width; 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); switchToWorkspace(wsId);
}) })
self.on('button-press-event', (self, event) => { self.on('button-press-event', (self, event) => {
@@ -176,7 +175,7 @@ export default () => EventBox({
self.attribute.clicked = true; self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords(); const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width; 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); switchToWorkspace(wsId);
}) })
self.on('button-release-event', (self) => self.attribute.clicked = false); self.on('button-release-event', (self) => self.attribute.clicked = false);
@@ -1,6 +1,6 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; 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'; import { showColorScheme } from '../../variables.js';
const ColorBox = ({ const ColorBox = ({
@@ -11,18 +11,9 @@ import { showMusicControls } from '../../variables.js';
const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated` 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_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 COVER_COLORSCHEME_SUFFIX = '_colorscheme.css';
const PREFERRED_PLAYER = 'plasma-browser-integration';
var lastCoverPath = ''; var lastCoverPath = '';
function isRealPlayer(player) { 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) { function lengthStr(length) {
const min = Math.floor(length / 60); const min = Math.floor(length / 60);
const sec = Math.floor(length % 60); const sec = Math.floor(length % 60);
@@ -1,7 +1,7 @@
// We're going to use ydotool // We're going to use ydotool
// See /usr/include/linux/input-event-codes.h for keycodes // 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 = { export const oskLayouts = {
qwerty_full: { qwerty_full: {
name: "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 { Box, EventBox, Button, Revealer } = Widget;
const { execAsync } = Utils; const { execAsync } = Utils;
import { MaterialIcon } from '../.commonwidgets/materialicon.js'; 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'; 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]; const keyboardJson = oskLayouts[keyboardLayout];
execAsync(`ydotoold`).catch(print); // Start ydotool daemon 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; const { execAsync, exec } = Utils;
import { setupCursorHoverGrab } from '../.widgetutils/cursorhover.js'; import { setupCursorHoverGrab } from '../.widgetutils/cursorhover.js';
import { dumpToWorkspace, swapWorkspace } from "./actions.js"; import { dumpToWorkspace, swapWorkspace } from "./actions.js";
import { substitute } from "../.miscutils/icons.js";
const OVERVIEW_SCALE = 0.18; const NUM_OF_WORKSPACES_SHOWN = userOptions.overview.numOfCols * userOptions.overview.numOfRows;
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 TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)]; const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
const overviewTick = Variable(false); 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 () => { export default () => {
const clientMap = new Map(); const clientMap = new Map();
let workspaceGroup = 0; 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 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; if (w <= 0 || h <= 0 || (c === '' && title === '')) return null;
// Non-primary monitors // Non-primary monitors
if (screenCoords.x != 0) x -= screenCoords.x; if (screenCoords.x != 0) x -= screenCoords.x;
@@ -94,23 +66,23 @@ export default () => {
const appIcon = Widget.Icon({ const appIcon = Widget.Icon({
icon: substitute(c), 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({ return Widget.Button({
attribute: { attribute: {
address, x, y, w, h, ws: id, address, x, y, w, h, ws: id,
updateIconSize: (self) => { 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', className: 'overview-tasks-window',
hpack: 'start', hpack: 'start',
vpack: 'start', vpack: 'start',
css: ` css: `
margin-left: ${Math.round(x * OVERVIEW_SCALE)}px; margin-left: ${Math.round(x * userOptions.overview.scale)}px;
margin-top: ${Math.round(y * OVERVIEW_SCALE)}px; margin-top: ${Math.round(y * userOptions.overview.scale)}px;
margin-right: -${Math.round((x + w) * OVERVIEW_SCALE)}px; margin-right: -${Math.round((x + w) * userOptions.overview.scale)}px;
margin-bottom: -${Math.round((y + h) * OVERVIEW_SCALE)}px; margin-bottom: -${Math.round((y + h) * userOptions.overview.scale)}px;
`, `,
onClicked: (self) => { onClicked: (self) => {
App.closeWindow('overview'); App.closeWindow('overview');
@@ -167,8 +139,8 @@ export default () => {
truncate: 'end', truncate: 'end',
className: `${xwayland ? 'txt txt-italic' : 'txt'}`, className: `${xwayland ? 'txt txt-italic' : 'txt'}`,
css: ` css: `
font-size: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE / 14.6}px; font-size: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale / 14.6}px;
margin: 0px ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE / 10}px; margin: 0px ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale / 10}px;
`, `,
// If the title is too short, include the class // If the title is too short, include the class
label: (title.length <= 1 ? `${c}: ${title}` : title), label: (title.length <= 1 ? `${c}: ${title}` : title),
@@ -211,12 +183,12 @@ export default () => {
attribute: { attribute: {
put: (widget, x, y) => { put: (widget, x, y) => {
if (!widget.attribute) 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 = ` const newCss = `
margin-left: ${Math.round(x)}px; margin-left: ${Math.round(x)}px;
margin-top: ${Math.round(y)}px; margin-top: ${Math.round(y)}px;
margin-right: -${Math.round(x + (widget.attribute.w * OVERVIEW_SCALE))}px; margin-right: -${Math.round(x + (widget.attribute.w * userOptions.overview.scale))}px;
margin-bottom: -${Math.round(y + (widget.attribute.h * OVERVIEW_SCALE))}px; margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px;
`; `;
widget.css = newCss; widget.css = newCss;
fixed.pack_start(widget, false, false, 0); fixed.pack_start(widget, false, false, 0);
@@ -224,12 +196,12 @@ export default () => {
move: (widget, x, y) => { move: (widget, x, y) => {
if (!widget) return; if (!widget) return;
if (!widget.attribute) 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 = ` const newCss = `
margin-left: ${Math.round(x)}px; margin-left: ${Math.round(x)}px;
margin-top: ${Math.round(y)}px; margin-top: ${Math.round(y)}px;
margin-right: -${Math.round(x + (widget.attribute.w * OVERVIEW_SCALE))}px; margin-right: -${Math.round(x + (widget.attribute.w * userOptions.overview.scale))}px;
margin-bottom: -${Math.round(y + (widget.attribute.h * OVERVIEW_SCALE))}px; margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px;
`; `;
widget.css = newCss; widget.css = newCss;
}, },
@@ -239,16 +211,16 @@ export default () => {
className: 'overview-tasks-workspace-number', className: 'overview-tasks-workspace-number',
label: `${index}`, label: `${index}`,
css: ` css: `
margin: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * OVERVIEW_SCALE * OVERVIEW_WS_NUM_MARGIN_SCALE}px; margin: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale * userOptions.overview.wsNumMarginScale}px;
font-size: ${SCREEN_HEIGHT * OVERVIEW_SCALE * OVERVIEW_WS_NUM_SCALE}px; font-size: ${SCREEN_HEIGHT * userOptions.overview.scale * userOptions.overview.wsNumScale}px;
`, `,
}) })
const widget = Widget.Box({ const widget = Widget.Box({
className: 'overview-tasks-workspace', className: 'overview-tasks-workspace',
vpack: 'center', vpack: 'center',
css: ` css: `
min-width: ${SCREEN_WIDTH * OVERVIEW_SCALE}px; min-width: ${SCREEN_WIDTH * userOptions.overview.scale}px;
min-height: ${SCREEN_HEIGHT * OVERVIEW_SCALE}px; min-height: ${SCREEN_HEIGHT * userOptions.overview.scale}px;
`, `,
children: [Widget.EventBox({ children: [Widget.EventBox({
hexpand: true, hexpand: true,
@@ -295,8 +267,8 @@ export default () => {
c.attribute.h = clientJson.size[1]; c.attribute.h = clientJson.size[1];
c.attribute.updateIconSize(c); c.attribute.updateIconSize(c);
fixed.attribute.move(c, fixed.attribute.move(c,
Math.max(0, clientJson.at[0] * OVERVIEW_SCALE), Math.max(0, clientJson.at[0] * userOptions.overview.scale),
Math.max(0, clientJson.at[1] * OVERVIEW_SCALE) Math.max(0, clientJson.at[1] * userOptions.overview.scale)
); );
return; return;
} }
@@ -305,8 +277,8 @@ export default () => {
if (newWindow === null) return; if (newWindow === null) return;
// clientMap.set(clientJson.address, newWindow); // clientMap.set(clientJson.address, newWindow);
fixed.attribute.put(newWindow, fixed.attribute.put(newWindow,
Math.max(0, newWindow.attribute.x * OVERVIEW_SCALE), Math.max(0, newWindow.attribute.x * userOptions.overview.scale),
Math.max(0, newWindow.attribute.y * OVERVIEW_SCALE) Math.max(0, newWindow.attribute.y * userOptions.overview.scale)
); );
clientMap.set(clientJson.address, newWindow); clientMap.set(clientJson.address, newWindow);
}; };
@@ -427,10 +399,10 @@ export default () => {
child: Widget.Box({ child: Widget.Box({
vertical: true, vertical: true,
className: 'overview-tasks', className: 'overview-tasks',
children: Array.from({ length: NUM_OF_WORKSPACE_ROWS }, (_, index) => children: Array.from({ length: userOptions.overview.numOfRows }, (_, index) =>
OverviewRow({ OverviewRow({
startWorkspace: 1 + index * NUM_OF_WORKSPACE_COLS, startWorkspace: 1 + index * userOptions.overview.numOfCols,
workspaces: NUM_OF_WORKSPACE_COLS, workspaces: userOptions.overview.numOfCols,
}) })
) )
}), }),
@@ -158,6 +158,6 @@ export const SearchButton = ({ text = '' }) => searchItem({
content: `${text}`, content: `${text}`,
onActivate: () => { onActivate: () => {
App.closeWindow('overview'); 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 { else {
App.closeWindow('overview'); 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 onChange: (entry) => { // this is when you type
+28 -40
View File
@@ -70,6 +70,32 @@ export default () => {
const shutdownButton = SessionButton('Shutdown', 'power_settings_new', () => { App.closeWindow('session'); execAsync('systemctl poweroff') }); 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 rebootButton = SessionButton('Reboot', 'restart_alt', () => { App.closeWindow('session'); execAsync('systemctl reboot') });
const cancelButton = SessionButton('Cancel', 'close', () => App.closeWindow('session'), { className: 'session-button-cancel' }); 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({ return Widget.Box({
className: 'session-bg', className: 'session-bg',
css: ` css: `
@@ -93,46 +119,8 @@ export default () => {
vertical: true, vertical: true,
className: 'spacing-v-15', className: 'spacing-v-15',
children: [ children: [
Widget.Box({ sessionDescription,
vertical: true, ...sessionButtonRows,
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,
]
}),
] ]
}) })
] ]
+27 -28
View File
@@ -1,30 +1,29 @@
$darkmode: true; $darkmode: true;
$primary: #e2e2e2; $primary: #ffb4a9;
$onPrimary: #000000; $onPrimary: #5f1410;
$primaryContainer: #6b6b6b; $primaryContainer: #7e2b24;
$onPrimaryContainer: #e2e2e2; $onPrimaryContainer: #ffdad4;
$secondary: #e2e2e2; $secondary: #e7bcb7;
$onSecondary: #000000; $onSecondary: #442926;
$secondaryContainer: #313131; $secondaryContainer: #5d3f3b;
$onSecondaryContainer: #e2e2e2; $onSecondaryContainer: #ffdad5;
$tertiary: #e2e2e2; $tertiary: #e0c38c;
$onTertiary: #000000; $onTertiary: #3f2e04;
$tertiaryContainer: #000000; $tertiaryContainer: #574419;
$onTertiaryContainer: #e2e2e2; $onTertiaryContainer: #fddfa6;
$error: #e2e2e2; $error: #ffb4a9;
$onError: #000000; $onError: #680003;
$errorContainer: #000000; $errorContainer: #930006;
$onErrorContainer: #e2e2e2; $onErrorContainer: #ffb4a9;
$colorbarbg: #000000; $colorbarbg: #130F0F;
$background: #000000; $background: #130F0F;
$onBackground: #e2e2e2; $onBackground: #ede0de;
$surface: #161616; $surface: #211a19;
$onSurface: #e2e2e2; $onSurface: #ede0de;
$surfaceVariant: #242424; $surfaceVariant: #534341;
$onSurfaceVariant: #e2e2e2; $onSurfaceVariant: #d8c2bf;
$outline: #a1a1a1; $outline: #a08c89;
$shadow: #000000; $shadow: #000000;
$inverseSurface: #e2e2e2; $inverseSurface: #ede0de;
$inverseOnSurface: #000000; $inverseOnSurface: #362f2e;
$inversePrimary: #e2e2e2; $inversePrimary: #9c4239;
+1
View File
@@ -0,0 +1 @@
+43
View 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;