21 changed files with 0 additions and 1777 deletions
@ -1,31 +0,0 @@
|
||||
"use strict"; |
||||
import GLib from 'gi://GLib'; |
||||
import App from 'resource:///com/github/Aylur/ags/app.js' |
||||
import userOptions from './modules/.configuration/user_options.js'; |
||||
import Overview from './modules/overview/main.js'; |
||||
|
||||
const COMPILED_STYLE_DIR = `${GLib.get_user_config_dir()}/ags/user/` |
||||
|
||||
async function applyStyle() { |
||||
|
||||
App.resetCss(); |
||||
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`); |
||||
console.log('[LOG] Styles loaded') |
||||
} |
||||
applyStyle().catch(print); |
||||
|
||||
const Windows = () => [ |
||||
Overview() |
||||
]; |
||||
const CLOSE_ANIM_TIME = 210; |
||||
App.config({ |
||||
css: `${COMPILED_STYLE_DIR}/style.css`, |
||||
stackTraceOnError: true, |
||||
closeWindowDelay: { |
||||
'sideright': CLOSE_ANIM_TIME, |
||||
'sideleft': CLOSE_ANIM_TIME, |
||||
'osk': CLOSE_ANIM_TIME, |
||||
}, |
||||
windows: Windows().flat(1), |
||||
}); |
||||
|
||||
@ -1,121 +0,0 @@
|
||||
|
||||
import userOverrides from '../../user_options.js'; |
||||
|
||||
// Defaults
|
||||
let configOptions = { |
||||
// General stuff
|
||||
'ai': { |
||||
'defaultGPTProvider': "openai", |
||||
'defaultTemperature': 0.9, |
||||
'enhancements': true, |
||||
'useHistory': true, |
||||
'writingCursor': " ...", // Warning: Using weird characters can mess up Markdown rendering
|
||||
}, |
||||
'animations': { |
||||
'choreographyDelay': 35, |
||||
'durationSmall': 110, |
||||
'durationLarge': 180, |
||||
}, |
||||
'appearance': { |
||||
'keyboardUseFlag': false, // Use flag emoji instead of abbreviation letters
|
||||
}, |
||||
'apps': { |
||||
'imageViewer': "loupe", |
||||
'terminal': "foot", // This is only for shell actions
|
||||
}, |
||||
'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, // Relative to screen size
|
||||
'numOfRows': 2, |
||||
'numOfCols': 5, |
||||
'wsNumScale': 0.09, |
||||
'wsNumMarginScale': 0.07, |
||||
}, |
||||
'sidebar': { |
||||
'imageColumns': 2, |
||||
'imageBooruCount': 20, |
||||
'imageAllowNsfw': false, |
||||
}, |
||||
'search': { |
||||
'engineBaseUrl': "https://www.google.com/search?q=", |
||||
'excludedSites': [], //add site to exclude from result. eg: "quora.com"
|
||||
}, |
||||
'time': { |
||||
// See https://docs.gtk.org/glib/method.DateTime.format.html
|
||||
// Here's the 12h format: "%I:%M%P"
|
||||
// For seconds, add "%S" and set interval to 1000
|
||||
'format': "%H:%M", |
||||
'interval': 5000, |
||||
'dateFormatLong': "%A, %d/%m", // On bar
|
||||
'dateInterval': 5000, |
||||
'dateFormat': "%d/%m", // On notif time
|
||||
}, |
||||
'weather': { |
||||
'city': "", |
||||
}, |
||||
'workspaces': { |
||||
'shown': 10, |
||||
}, |
||||
// Longer stuff
|
||||
'icons': { |
||||
substitutions: { |
||||
'code-url-handler': "visual-studio-code", |
||||
'Code': "visual-studio-code", |
||||
'GitHub Desktop': "github-desktop", |
||||
'Minecraft* 1.20.1': "minecraft", |
||||
'gnome-tweaks': "org.gnome.tweaks", |
||||
'pavucontrol-qt': "pavucontrol", |
||||
'wps': "wps-office2019-kprometheus", |
||||
'wpsoffice': "wps-office2019-kprometheus", |
||||
'': "image-missing", |
||||
} |
||||
}, |
||||
'keybinds': { |
||||
// Format: Mod1+Mod2+key. CaSe SeNsItIvE!
|
||||
// Modifiers: Shift Ctrl Alt Hyper Meta
|
||||
// See https://docs.gtk.org/gdk3/index.html#constants for the other keys (they are listed as KEY_key)
|
||||
'overview': { |
||||
'altMoveLeft': "Ctrl+b", |
||||
'altMoveRight': "Ctrl+f", |
||||
'deleteToEnd': "Ctrl+k", |
||||
}, |
||||
'sidebar': { |
||||
'apis': { |
||||
'nextTab': "Page_Down", |
||||
'prevTab': "Page_Up", |
||||
}, |
||||
'options': { // Right sidebar
|
||||
'nextTab': "Page_Down", |
||||
'prevTab': "Page_Up", |
||||
}, |
||||
'pin': "Ctrl+p", |
||||
'cycleTab': "Ctrl+Tab", |
||||
'nextTab': "Ctrl+Page_Down", |
||||
'prevTab': "Ctrl+Page_Up", |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
// Override defaults with user's options
|
||||
function overrideConfigRecursive(userOverrides, configOptions = {}) { |
||||
for (const [key, value] of Object.entries(userOverrides)) { |
||||
if (typeof value === 'object') { |
||||
overrideConfigRecursive(value, configOptions[key]); |
||||
} else { |
||||
configOptions[key] = value; |
||||
} |
||||
} |
||||
} |
||||
overrideConfigRecursive(userOverrides, configOptions); |
||||
|
||||
globalThis['userOptions'] = configOptions; |
||||
export default configOptions; |
||||
@ -1,13 +0,0 @@
|
||||
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; |
||||
} |
||||
@ -1,4 +0,0 @@
|
||||
|
||||
export function clamp(x, min, max) { |
||||
return Math.min(Math.max(x, min), max); |
||||
} |
||||
@ -1,54 +0,0 @@
|
||||
const { GLib } = imports.gi; |
||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js'; |
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; |
||||
const { execAsync, exec } = Utils; |
||||
|
||||
export const distroID = exec(`bash -c 'cat /etc/os-release | grep "^ID=" | cut -d "=" -f 2 | sed "s/\\"//g"'`).trim(); |
||||
export const isDebianDistro = (distroID == 'linuxmint' || distroID == 'ubuntu' || distroID == 'debian' || distroID == 'zorin' || distroID == 'popos' || distroID == 'raspbian' || distroID == 'kali'); |
||||
export const isArchDistro = (distroID == 'arch' || distroID == 'endeavouros' || distroID == 'cachyos'); |
||||
export const hasFlatpak = !!exec(`bash -c 'command -v flatpak'`); |
||||
|
||||
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_cache_dir()}/ags/user/colormode.txt`; |
||||
const colorMode = Utils.exec('bash -c "sed -n \'1p\' $HOME/.cache/ags/user/colormode.txt"'); |
||||
export let darkMode = Variable(!(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light')); |
||||
export const hasPlasmaIntegration = !!Utils.exec('bash -c "command -v plasma-browser-integration-host"'); |
||||
|
||||
export const getDistroIcon = () => { |
||||
// Arches
|
||||
if(distroID == 'arch') return 'arch-symbolic'; |
||||
if(distroID == 'endeavouros') return 'endeavouros-symbolic'; |
||||
if(distroID == 'cachyos') return 'cachyos-symbolic'; |
||||
// Funny flake
|
||||
if(distroID == 'nixos') return 'nixos-symbolic'; |
||||
// Cool thing
|
||||
if(distroID == 'fedora') return 'fedora-symbolic'; |
||||
// Debians
|
||||
if(distroID == 'linuxmint') return 'ubuntu-symbolic'; |
||||
if(distroID == 'ubuntu') return 'ubuntu-symbolic'; |
||||
if(distroID == 'debian') return 'debian-symbolic'; |
||||
if(distroID == 'zorin') return 'ubuntu-symbolic'; |
||||
if(distroID == 'popos') return 'ubuntu-symbolic'; |
||||
if(distroID == 'raspbian') return 'debian-symbolic'; |
||||
if(distroID == 'kali') return 'debian-symbolic'; |
||||
return 'linux-symbolic'; |
||||
} |
||||
|
||||
export const getDistroName = () => { |
||||
// Arches
|
||||
if(distroID == 'arch') return 'Arch Linux'; |
||||
if(distroID == 'endeavouros') return 'EndeavourOS'; |
||||
if(distroID == 'cachyos') return 'CachyOS'; |
||||
// Funny flake
|
||||
if(distroID == 'nixos') return 'NixOS'; |
||||
// Cool thing
|
||||
if(distroID == 'fedora') return 'Fedora'; |
||||
// Debians
|
||||
if(distroID == 'linuxmint') return 'Linux Mint'; |
||||
if(distroID == 'ubuntu') return 'Ubuntu'; |
||||
if(distroID == 'debian') return 'Debian'; |
||||
if(distroID == 'zorin') return 'Zorin'; |
||||
if(distroID == 'popos') return 'Pop!_OS'; |
||||
if(distroID == 'raspbian') return 'Raspbian'; |
||||
if(distroID == 'kali') return 'Kali Linux'; |
||||
return 'Linux'; |
||||
} |
||||
@ -1,86 +0,0 @@
|
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; |
||||
|
||||
const { Revealer, Scrollable } = Widget; |
||||
|
||||
export const MarginRevealer = ({ |
||||
transition = 'slide_down', |
||||
child, |
||||
revealChild, |
||||
showClass = 'element-show', // These are for animation curve, they don't really hide
|
||||
hideClass = 'element-hide', // Don't put margins in these classes!
|
||||
extraSetup = () => { }, |
||||
...rest |
||||
}) => { |
||||
const widget = Scrollable({ |
||||
...rest, |
||||
attribute: { |
||||
'revealChild': true, // It'll be set to false after init if it's supposed to hide
|
||||
'transition': transition, |
||||
'show': () => { |
||||
if (widget.attribute.revealChild) return; |
||||
widget.hscroll = 'never'; |
||||
widget.vscroll = 'never'; |
||||
child.toggleClassName(hideClass, false); |
||||
child.toggleClassName(showClass, true); |
||||
widget.attribute.revealChild = true; |
||||
child.css = 'margin: 0px;'; |
||||
}, |
||||
'hide': () => { |
||||
if (!widget.attribute.revealChild) return; |
||||
child.toggleClassName(hideClass, true); |
||||
child.toggleClassName(showClass, false); |
||||
widget.attribute.revealChild = false; |
||||
if (widget.attribute.transition == 'slide_left') |
||||
child.css = `margin-right: -${child.get_allocated_width()}px;`; |
||||
else if (widget.attribute.transition == 'slide_right') |
||||
child.css = `margin-left: -${child.get_allocated_width()}px;`; |
||||
else if (widget.attribute.transition == 'slide_up') |
||||
child.css = `margin-bottom: -${child.get_allocated_height()}px;`; |
||||
else if (widget.attribute.transition == 'slide_down') |
||||
child.css = `margin-top: -${child.get_allocated_height()}px;`; |
||||
}, |
||||
'toggle': () => { |
||||
if (widget.attribute.revealChild) widget.attribute.hide(); |
||||
else widget.attribute.show(); |
||||
}, |
||||
}, |
||||
child: child, |
||||
hscroll: `${revealChild ? 'never' : 'always'}`, |
||||
vscroll: `${revealChild ? 'never' : 'always'}`, |
||||
setup: (self) => { |
||||
extraSetup(self); |
||||
} |
||||
}); |
||||
child.toggleClassName(`${revealChild ? showClass : hideClass}`, true); |
||||
return widget; |
||||
} |
||||
|
||||
// TODO: Allow reveal update. Currently this just helps at declaration
|
||||
export const DoubleRevealer = ({ |
||||
transition1 = 'slide_right', |
||||
transition2 = 'slide_left', |
||||
duration1 = 150, |
||||
duration2 = 150, |
||||
child, |
||||
revealChild, |
||||
...rest |
||||
}) => { |
||||
const r2 = Revealer({ |
||||
transition: transition2, |
||||
transitionDuration: duration2, |
||||
revealChild: revealChild, |
||||
child: child, |
||||
}); |
||||
const r1 = Revealer({ |
||||
transition: transition1, |
||||
transitionDuration: duration1, |
||||
revealChild: revealChild, |
||||
child: r2, |
||||
...rest, |
||||
}) |
||||
r1.toggleRevealChild = (value) => { |
||||
r1.revealChild = value; |
||||
r2.revealChild = value; |
||||
} |
||||
return r1; |
||||
} |
||||
@ -1,32 +0,0 @@
|
||||
import App from 'resource:///com/github/Aylur/ags/app.js'; |
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; |
||||
const { Box, Window } = Widget; |
||||
|
||||
|
||||
export default ({ |
||||
name, |
||||
child, |
||||
showClassName = "", |
||||
hideClassName = "", |
||||
...props |
||||
}) => { |
||||
return Window({ |
||||
name, |
||||
visible: false, |
||||
layer: 'overlay', |
||||
...props, |
||||
|
||||
child: Box({ |
||||
setup: (self) => { |
||||
self.hook(App, (self, currentName, visible) => { |
||||
if (currentName === name) { |
||||
self.toggleClassName(hideClassName, !visible); |
||||
} |
||||
}).keybind("Escape", () => App.closeWindow(name)) |
||||
if (showClassName !== "" && hideClassName !== "") |
||||
self.className = `${showClassName} ${hideClassName}`; |
||||
}, |
||||
child: child, |
||||
}), |
||||
}); |
||||
} |
||||
@ -1,4 +0,0 @@
|
||||
import Cairo from 'gi://cairo?version=1.0'; |
||||
|
||||
export const dummyRegion = new Cairo.Region(); |
||||
export const enableClickthrough = (self) => self.input_shape_combine_region(dummyRegion); |
||||
@ -1,57 +0,0 @@
|
||||
const { Gdk } = imports.gi; |
||||
|
||||
export function setupCursorHover(button) { // Hand pointing cursor on hover
|
||||
const display = Gdk.Display.get_default(); |
||||
button.connect('enter-notify-event', () => { |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'pointer'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
|
||||
button.connect('leave-notify-event', () => { |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
|
||||
} |
||||
|
||||
export function setupCursorHoverAim(button) { // Crosshair cursor on hover
|
||||
button.connect('enter-notify-event', () => { |
||||
const display = Gdk.Display.get_default(); |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'crosshair'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
|
||||
button.connect('leave-notify-event', () => { |
||||
const display = Gdk.Display.get_default(); |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
} |
||||
|
||||
export function setupCursorHoverGrab(button) { // Hand ready to grab on hover
|
||||
button.connect('enter-notify-event', () => { |
||||
const display = Gdk.Display.get_default(); |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'grab'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
|
||||
button.connect('leave-notify-event', () => { |
||||
const display = Gdk.Display.get_default(); |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
} |
||||
|
||||
export function setupCursorHoverInfo(button) { // "?" mark cursor on hover
|
||||
const display = Gdk.Display.get_default(); |
||||
button.connect('enter-notify-event', () => { |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'help'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
|
||||
button.connect('leave-notify-event', () => { |
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default'); |
||||
button.get_window().set_cursor(cursor); |
||||
}); |
||||
} |
||||
|
||||
@ -1,25 +0,0 @@
|
||||
const { Gdk } = imports.gi; |
||||
|
||||
const MODS = { |
||||
'Shift': Gdk.ModifierType.SHIFT_MASK, |
||||
'Ctrl': Gdk.ModifierType.CONTROL_MASK, |
||||
'Alt': Gdk.ModifierType.ALT_MASK, |
||||
'Hyper': Gdk.ModifierType.HYPER_MASK, |
||||
'Meta': Gdk.ModifierType.META_MASK |
||||
} |
||||
|
||||
export const checkKeybind = (event, keybind) => { |
||||
const pressedModMask = event.get_state()[1]; |
||||
const pressedKey = event.get_keyval()[1]; |
||||
const keys = keybind.split('+'); |
||||
for (let i = 0; i < keys.length; i++) { |
||||
if (keys[i] in MODS) { |
||||
if (!(pressedModMask & MODS[keys[i]])) { |
||||
return false; |
||||
} |
||||
} else if (pressedKey !== Gdk[`KEY_${keys[i]}`]) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
@ -1,28 +0,0 @@
|
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; |
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js'; |
||||
|
||||
function moveClientToWorkspace(address, workspace) { |
||||
Utils.execAsync(['bash', '-c', `hyprctl dispatch movetoworkspacesilent ${workspace},address:${address} &`]); |
||||
} |
||||
|
||||
export function dumpToWorkspace(from, to) { |
||||
if (from == to) return; |
||||
Hyprland.clients.forEach(client => { |
||||
if (client.workspace.id == from) { |
||||
moveClientToWorkspace(client.address, to); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
export function swapWorkspace(workspaceA, workspaceB) { |
||||
if (workspaceA == workspaceB) return; |
||||
const clientsA = []; |
||||
const clientsB = []; |
||||
Hyprland.clients.forEach(client => { |
||||
if (client.workspace.id == workspaceA) clientsA.push(client.address); |
||||
if (client.workspace.id == workspaceB) clientsB.push(client.address); |
||||
}); |
||||
|
||||
clientsA.forEach((address) => moveClientToWorkspace(address, workspaceB)); |
||||
clientsB.forEach((address) => moveClientToWorkspace(address, workspaceA)); |
||||
} |
||||
@ -1,18 +0,0 @@
|
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; |
||||
import { SearchAndWindows } from "./windowcontent.js"; |
||||
import PopupWindow from '../.widgethacks/popupwindow.js'; |
||||
|
||||
export default (id = '') => PopupWindow({ |
||||
name: `overview${id}`, |
||||
exclusivity: 'ignore', |
||||
keymode: 'exclusive', |
||||
visible: false, |
||||
// anchor: ['middle'],
|
||||
layer: 'overlay', |
||||
child: Widget.Box({ |
||||
vertical: true, |
||||
children: [ |
||||
SearchAndWindows(), |
||||
] |
||||
}), |
||||
}) |
||||
@ -1,155 +0,0 @@
|
||||
const { Gio, GLib } = imports.gi; |
||||
import App from 'resource:///com/github/Aylur/ags/app.js'; |
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; |
||||
const { execAsync, exec } = Utils; |
||||
// import Todo from "../../services/todo.js";
|
||||
import { darkMode } from '../.miscutils/system.js'; |
||||
|
||||
export function hasUnterminatedBackslash(inputString) { |
||||
// Use a regular expression to match a trailing odd number of backslashes
|
||||
const regex = /\\+$/; |
||||
return regex.test(inputString); |
||||
} |
||||
|
||||
export function launchCustomCommand(command) { |
||||
const args = command.toLowerCase().split(' '); |
||||
if (args[0] == '>raw') { // Mouse raw input
|
||||
Utils.execAsync('hyprctl -j getoption input:accel_profile') |
||||
.then((output) => { |
||||
const value = JSON.parse(output)["str"].trim(); |
||||
if (value != "[[EMPTY]]" && value != "") { |
||||
execAsync(['bash', '-c', `hyprctl keyword input:accel_profile '[[EMPTY]]'`]).catch(print); |
||||
} |
||||
else { |
||||
execAsync(['bash', '-c', `hyprctl keyword input:accel_profile flat`]).catch(print); |
||||
} |
||||
}) |
||||
} |
||||
else if (args[0] == '>img') { // Change wallpaper
|
||||
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchwall.sh`, `&`]).catch(print); |
||||
} |
||||
else if (args[0] == '>color') { // Generate colorscheme from color picker
|
||||
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh --pick`, `&`]).catch(print); |
||||
} |
||||
else if (args[0] == '>light') { // Light mode
|
||||
darkMode.value = false; |
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "1s/.*/light/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`]) |
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`])) |
||||
.catch(print); |
||||
} |
||||
else if (args[0] == '>dark') { // Dark mode
|
||||
darkMode.value = true; |
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "1s/.*/dark/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`]) |
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`])) |
||||
.catch(print); |
||||
} |
||||
else if (args[0] == '>badapple') { // Black and white
|
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "3s/.*/monochrome/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`]) |
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`])) |
||||
.catch(print); |
||||
} |
||||
else if (args[0] == '>material') { // Use material colors
|
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && echo "material" > ${GLib.get_user_cache_dir()}/ags/user/colorbackend.txt`]).catch(print) |
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchwall.sh --noswitch`]).catch(print)) |
||||
.catch(print); |
||||
} |
||||
else if (args[0] == '>pywal') { // Use Pywal (ik it looks shit but I'm not removing)
|
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && echo "pywal" > ${GLib.get_user_cache_dir()}/ags/user/colorbackend.txt`]).catch(print) |
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchwall.sh --noswitch`]).catch(print)) |
||||
.catch(print); |
||||
} |
||||
else if (args[0] == '>todo') { // Todo
|
||||
Todo.add(args.slice(1).join(' ')); |
||||
} |
||||
else if (args[0] == '>shutdown') { // Shut down
|
||||
execAsync([`bash`, `-c`, `systemctl poweroff || loginctl poweroff`]).catch(print); |
||||
} |
||||
else if (args[0] == '>reboot') { // Reboot
|
||||
execAsync([`bash`, `-c`, `systemctl reboot || loginctl reboot`]).catch(print); |
||||
} |
||||
else if (args[0] == '>sleep') { // Sleep
|
||||
execAsync([`bash`, `-c`, `systemctl suspend || loginctl suspend`]).catch(print); |
||||
} |
||||
else if (args[0] == '>logout') { // Log out
|
||||
execAsync([`bash`, `-c`, `pkill Hyprland || pkill sway`]).catch(print); |
||||
} |
||||
} |
||||
|
||||
export function execAndClose(command, terminal) { |
||||
App.closeWindow('overview'); |
||||
if (terminal) { |
||||
execAsync([`bash`, `-c`, `${userOptions.apps.terminal} fish -C "${command}"`, `&`]).catch(print); |
||||
} |
||||
else |
||||
execAsync(command).catch(print); |
||||
} |
||||
|
||||
export function couldBeMath(str) { |
||||
const regex = /^[0-9.+*/-]/; |
||||
return regex.test(str); |
||||
} |
||||
|
||||
export function expandTilde(path) { |
||||
if (path.startsWith('~')) { |
||||
return GLib.get_home_dir() + path.slice(1); |
||||
} else { |
||||
return path; |
||||
} |
||||
} |
||||
|
||||
function getFileIcon(fileInfo) { |
||||
let icon = fileInfo.get_icon(); |
||||
if (icon) { |
||||
// Get the icon's name
|
||||
return icon.get_names()[0]; |
||||
} else { |
||||
// Default icon for files
|
||||
return 'text-x-generic'; |
||||
} |
||||
} |
||||
|
||||
export function ls({ path = '~', silent = false }) { |
||||
let contents = []; |
||||
try { |
||||
let expandedPath = expandTilde(path); |
||||
if (expandedPath.endsWith('/')) |
||||
expandedPath = expandedPath.slice(0, -1); |
||||
let folder = Gio.File.new_for_path(expandedPath); |
||||
|
||||
let enumerator = folder.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null); |
||||
let fileInfo; |
||||
while ((fileInfo = enumerator.next_file(null)) !== null) { |
||||
let fileName = fileInfo.get_display_name(); |
||||
let fileType = fileInfo.get_file_type(); |
||||
|
||||
let item = { |
||||
parentPath: expandedPath, |
||||
name: fileName, |
||||
type: fileType === Gio.FileType.DIRECTORY ? 'folder' : 'file', |
||||
icon: getFileIcon(fileInfo), |
||||
}; |
||||
|
||||
// Add file extension for files
|
||||
if (fileType === Gio.FileType.REGULAR) { |
||||
let fileExtension = fileName.split('.').pop(); |
||||
item.type = `${fileExtension}`; |
||||
} |
||||
|
||||
contents.push(item); |
||||
contents.sort((a, b) => { |
||||
const aIsFolder = a.type.startsWith('folder'); |
||||
const bIsFolder = b.type.startsWith('folder'); |
||||
if (aIsFolder && !bIsFolder) { |
||||
return -1; |
||||
} else if (!aIsFolder && bIsFolder) { |
||||
return 1; |
||||
} else { |
||||
return a.name.localeCompare(b.name); // Sort alphabetically within folders and files
|
||||
} |
||||
}); |
||||
} |
||||
} catch (e) { |
||||
if (!silent) console.log(e); |
||||
} |
||||
return contents; |
||||
} |
||||
@ -1,423 +0,0 @@
|
||||
// TODO
|
||||
// - Make client destroy/create not destroy and recreate the whole thing
|
||||
// - Active ws hook optimization: only update when moving to next group
|
||||
//
|
||||
const { Gdk, Gtk } = imports.gi; |
||||
const { Gravity } = imports.gi.Gdk; |
||||
import { SCREEN_HEIGHT, SCREEN_WIDTH } from '../../variables.js'; |
||||
import App from 'resource:///com/github/Aylur/ags/app.js'; |
||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js'; |
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; |
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; |
||||
|
||||
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 NUM_OF_WORKSPACES_SHOWN = userOptions.overview.numOfCols * userOptions.overview.numOfRows; |
||||
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)]; |
||||
const POPUP_CLOSE_TIME = 100; // ms
|
||||
|
||||
const overviewTick = Variable(false); |
||||
|
||||
export default () => { |
||||
const clientMap = new Map(); |
||||
let workspaceGroup = 0; |
||||
const ContextMenuWorkspaceArray = ({ label, actionFunc, thisWorkspace }) => Widget.MenuItem({ |
||||
label: `${label}`, |
||||
setup: (menuItem) => { |
||||
let submenu = new Gtk.Menu(); |
||||
submenu.className = 'menu'; |
||||
|
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
const startWorkspace = offset + 1; |
||||
const endWorkspace = startWorkspace + NUM_OF_WORKSPACES_SHOWN - 1; |
||||
for (let i = startWorkspace; i <= endWorkspace; i++) { |
||||
let button = new Gtk.MenuItem({ |
||||
label: `Workspace ${i}` |
||||
}); |
||||
button.connect("activate", () => { |
||||
// execAsync([`${onClickBinary}`, `${thisWorkspace}`, `${i}`]).catch(print);
|
||||
actionFunc(thisWorkspace, i); |
||||
overviewTick.setValue(!overviewTick.value); |
||||
}); |
||||
submenu.append(button); |
||||
} |
||||
menuItem.set_reserve_indicator(true); |
||||
menuItem.set_submenu(submenu); |
||||
} |
||||
}) |
||||
|
||||
const Window = ({ address, at: [x, y], size: [w, h], workspace: { id, name }, class: c, title, xwayland }, screenCoords) => { |
||||
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; |
||||
if (screenCoords.y != 0) y -= screenCoords.y; |
||||
// Other offscreen adjustments
|
||||
if (x + w <= 0) x += (Math.floor(x / SCREEN_WIDTH) * SCREEN_WIDTH); |
||||
else if (x < 0) { w = x + w; x = 0; } |
||||
if (y + h <= 0) x += (Math.floor(y / SCREEN_HEIGHT) * SCREEN_HEIGHT); |
||||
else if (y < 0) { h = y + h; y = 0; } |
||||
// Truncate if offscreen
|
||||
if (x + w > SCREEN_WIDTH) w = SCREEN_WIDTH - x; |
||||
if (y + h > SCREEN_HEIGHT) h = SCREEN_HEIGHT - y; |
||||
|
||||
const appIcon = Widget.Icon({ |
||||
icon: substitute(c), |
||||
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) * userOptions.overview.scale / 2.5; |
||||
}, |
||||
}, |
||||
className: 'overview-tasks-window', |
||||
hpack: 'start', |
||||
vpack: 'start', |
||||
css: ` |
||||
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'); |
||||
Utils.timeout(POPUP_CLOSE_TIME, () => Hyprland.messageAsync(`dispatch focuswindow address:${address}`)); |
||||
}, |
||||
onMiddleClickRelease: () => Hyprland.messageAsync(`dispatch closewindow address:${address}`), |
||||
onSecondaryClick: (button) => { |
||||
button.toggleClassName('overview-tasks-window-selected', true); |
||||
const menu = Widget.Menu({ |
||||
className: 'menu', |
||||
children: [ |
||||
Widget.MenuItem({ |
||||
child: Widget.Label({ |
||||
xalign: 0, |
||||
label: "Close (Middle-click)", |
||||
}), |
||||
onActivate: () => Hyprland.messageAsync(`dispatch closewindow address:${address}`), |
||||
}), |
||||
ContextMenuWorkspaceArray({ |
||||
label: "Dump windows to workspace", |
||||
actionFunc: dumpToWorkspace, |
||||
thisWorkspace: Number(id) |
||||
}), |
||||
ContextMenuWorkspaceArray({ |
||||
label: "Swap windows with workspace", |
||||
actionFunc: swapWorkspace, |
||||
thisWorkspace: Number(id) |
||||
}), |
||||
], |
||||
}); |
||||
menu.connect("deactivate", () => { |
||||
button.toggleClassName('overview-tasks-window-selected', false); |
||||
}) |
||||
menu.connect("selection-done", () => { |
||||
button.toggleClassName('overview-tasks-window-selected', false); |
||||
}) |
||||
menu.popup_at_widget(button.get_parent(), Gravity.SOUTH, Gravity.NORTH, null); // Show menu below the button
|
||||
button.connect("destroy", () => menu.destroy()); |
||||
}, |
||||
child: Widget.Box({ |
||||
homogeneous: true, |
||||
child: Widget.Box({ |
||||
vertical: true, |
||||
vpack: 'center', |
||||
className: 'spacing-v-5', |
||||
children: [ |
||||
appIcon, |
||||
// TODO: Add xwayland tag instead of just having italics
|
||||
Widget.Revealer({ |
||||
transition: 'slide_down', |
||||
revealChild: revealInfoCondition, |
||||
child: Widget.Label({ |
||||
maxWidthChars: 10, // Doesn't matter what number
|
||||
truncate: 'end', |
||||
className: `${xwayland ? 'txt txt-italic' : 'txt'}`, |
||||
css: ` |
||||
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), |
||||
}) |
||||
}) |
||||
] |
||||
}) |
||||
}), |
||||
tooltipText: `${c}: ${title}`, |
||||
setup: (button) => { |
||||
setupCursorHoverGrab(button); |
||||
|
||||
button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.MOVE); |
||||
button.drag_source_set_icon_name(substitute(c)); |
||||
// button.drag_source_set_icon_gicon(icon);
|
||||
|
||||
button.connect('drag-begin', (button) => { // On drag start, add the dragging class
|
||||
button.toggleClassName('overview-tasks-window-dragging', true); |
||||
}); |
||||
button.connect('drag-data-get', (_w, _c, data) => { // On drag finish, give address
|
||||
data.set_text(address, address.length); |
||||
button.toggleClassName('overview-tasks-window-dragging', false); |
||||
}); |
||||
}, |
||||
}); |
||||
} |
||||
|
||||
const Workspace = (index) => { |
||||
// const fixed = Widget.Fixed({
|
||||
// attribute: {
|
||||
// put: (widget, x, y) => {
|
||||
// fixed.put(widget, x, y);
|
||||
// },
|
||||
// move: (widget, x, y) => {
|
||||
// fixed.move(widget, x, y);
|
||||
// },
|
||||
// }
|
||||
// });
|
||||
const fixed = Widget.Box({ |
||||
attribute: { |
||||
put: (widget, x, y) => { |
||||
if (!widget.attribute) return; |
||||
// 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 * 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); |
||||
}, |
||||
move: (widget, x, y) => { |
||||
if (!widget) return; |
||||
if (!widget.attribute) return; |
||||
// 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 * userOptions.overview.scale))}px; |
||||
margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px; |
||||
`;
|
||||
widget.css = newCss; |
||||
}, |
||||
} |
||||
}) |
||||
const WorkspaceNumber = ({ index, ...rest }) => Widget.Label({ |
||||
className: 'overview-tasks-workspace-number', |
||||
label: `${index}`, |
||||
css: ` |
||||
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; |
||||
`,
|
||||
setup: (self) => self.hook(Hyprland.active.workspace, (self) => { |
||||
// Update when going to new ws group
|
||||
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN); |
||||
self.label = `${currentGroup * NUM_OF_WORKSPACES_SHOWN + index}`; |
||||
}), |
||||
...rest, |
||||
}) |
||||
const widget = Widget.Box({ |
||||
className: 'overview-tasks-workspace', |
||||
vpack: 'center', |
||||
css: ` |
||||
min-width: ${SCREEN_WIDTH * userOptions.overview.scale}px; |
||||
min-height: ${SCREEN_HEIGHT * userOptions.overview.scale}px; |
||||
`,
|
||||
children: [Widget.EventBox({ |
||||
hexpand: true, |
||||
vexpand: true, |
||||
onPrimaryClick: () => { |
||||
App.closeWindow('overview'); |
||||
Utils.timeout(POPUP_CLOSE_TIME, () => Hyprland.messageAsync(`dispatch workspace ${index}`)); |
||||
}, |
||||
setup: (eventbox) => { |
||||
eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY); |
||||
eventbox.connect('drag-data-received', (_w, _c, _x, _y, data) => { |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
Hyprland.messageAsync(`dispatch movetoworkspacesilent ${index + offset},address:${data.get_text()}`) |
||||
overviewTick.setValue(!overviewTick.value); |
||||
}); |
||||
}, |
||||
child: Widget.Overlay({ |
||||
child: Widget.Box({}), |
||||
overlays: [ |
||||
WorkspaceNumber({ index: index, hpack: 'start', vpack: 'start' }), |
||||
fixed |
||||
] |
||||
}), |
||||
})], |
||||
}); |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
fixed.attribute.put(WorkspaceNumber(offset + index), 0, 0); |
||||
widget.clear = () => { |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
clientMap.forEach((client, address) => { |
||||
if (!client) return; |
||||
if ((client.attribute.ws <= offset || client.attribute.ws > offset + NUM_OF_WORKSPACES_SHOWN) || |
||||
(client.attribute.ws == offset + index)) { |
||||
client.destroy(); |
||||
client = null; |
||||
clientMap.delete(address); |
||||
} |
||||
}); |
||||
} |
||||
widget.set = (clientJson, screenCoords) => { |
||||
let c = clientMap.get(clientJson.address); |
||||
if (c) { |
||||
if (c.attribute?.ws !== clientJson.workspace.id) { |
||||
c.destroy(); |
||||
c = null; |
||||
clientMap.delete(clientJson.address); |
||||
} |
||||
else if (c) { |
||||
c.attribute.w = clientJson.size[0]; |
||||
c.attribute.h = clientJson.size[1]; |
||||
c.attribute.updateIconSize(c); |
||||
fixed.attribute.move(c, |
||||
Math.max(0, clientJson.at[0] * userOptions.overview.scale), |
||||
Math.max(0, clientJson.at[1] * userOptions.overview.scale) |
||||
); |
||||
return; |
||||
} |
||||
} |
||||
const newWindow = Window(clientJson, screenCoords); |
||||
if (newWindow === null) return; |
||||
// clientMap.set(clientJson.address, newWindow);
|
||||
fixed.attribute.put(newWindow, |
||||
Math.max(0, newWindow.attribute.x * userOptions.overview.scale), |
||||
Math.max(0, newWindow.attribute.y * userOptions.overview.scale) |
||||
); |
||||
clientMap.set(clientJson.address, newWindow); |
||||
}; |
||||
widget.unset = (clientAddress) => { |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
let c = clientMap.get(clientAddress); |
||||
if (!c) return; |
||||
c.destroy(); |
||||
c = null; |
||||
clientMap.delete(clientAddress); |
||||
}; |
||||
widget.show = () => { |
||||
fixed.show_all(); |
||||
} |
||||
return widget; |
||||
}; |
||||
|
||||
const arr = (s, n) => { |
||||
const array = []; |
||||
for (let i = 0; i < n; i++) |
||||
array.push(s + i); |
||||
|
||||
return array; |
||||
}; |
||||
|
||||
const OverviewRow = ({ startWorkspace, workspaces, windowName = 'overview' }) => Widget.Box({ |
||||
children: arr(startWorkspace, workspaces).map(Workspace), |
||||
attribute: { |
||||
monitorMap: [], |
||||
getMonitorMap: (box) => { |
||||
execAsync('hyprctl -j monitors').then(monitors => { |
||||
box.attribute.monitorMap = JSON.parse(monitors).reduce((acc, item) => { |
||||
acc[item.id] = { x: item.x, y: item.y }; |
||||
return acc; |
||||
}, {}); |
||||
}); |
||||
}, |
||||
update: (box) => { |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
if (!App.getWindow(windowName).visible) return; |
||||
Hyprland.messageAsync('j/clients').then(clients => { |
||||
const allClients = JSON.parse(clients); |
||||
const kids = box.get_children(); |
||||
kids.forEach(kid => kid.clear()); |
||||
for (let i = 0; i < allClients.length; i++) { |
||||
const client = allClients[i]; |
||||
const childID = client.workspace.id - (offset + startWorkspace); |
||||
if (offset + startWorkspace <= client.workspace.id && |
||||
client.workspace.id <= offset + startWorkspace + workspaces) { |
||||
const screenCoords = box.attribute.monitorMap[client.monitor]; |
||||
if (kids[childID]) { |
||||
kids[childID].set(client, screenCoords); |
||||
} |
||||
continue; |
||||
} |
||||
} |
||||
kids.forEach(kid => kid.show()); |
||||
}).catch(print); |
||||
}, |
||||
updateWorkspace: (box, id) => { |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
if (!( // Not in range, ignore
|
||||
offset + startWorkspace <= id && |
||||
id <= offset + startWorkspace + workspaces |
||||
)) return; |
||||
// if (!App.getWindow(windowName).visible) return;
|
||||
Hyprland.messageAsync('j/clients').then(clients => { |
||||
const allClients = JSON.parse(clients); |
||||
const kids = box.get_children(); |
||||
for (let i = 0; i < allClients.length; i++) { |
||||
const client = allClients[i]; |
||||
if (client.workspace.id != id) continue; |
||||
const screenCoords = box.attribute.monitorMap[client.monitor]; |
||||
kids[id - (offset + startWorkspace)]?.set(client, screenCoords); |
||||
} |
||||
kids[id - (offset + startWorkspace)]?.show(); |
||||
}).catch(print); |
||||
}, |
||||
}, |
||||
setup: (box) => { |
||||
box.attribute.getMonitorMap(box); |
||||
box |
||||
.hook(overviewTick, (box) => box.attribute.update(box)) |
||||
.hook(Hyprland, (box, clientAddress) => { |
||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN; |
||||
const kids = box.get_children(); |
||||
const client = Hyprland.getClient(clientAddress); |
||||
if (!client) return; |
||||
const id = client.workspace.id; |
||||
|
||||
box.attribute.updateWorkspace(box, id); |
||||
kids[id - (offset + startWorkspace)]?.unset(clientAddress); |
||||
}, 'client-removed') |
||||
.hook(Hyprland, (box, clientAddress) => { |
||||
const client = Hyprland.getClient(clientAddress); |
||||
if (!client) return; |
||||
box.attribute.updateWorkspace(box, client.workspace.id); |
||||
}, 'client-added') |
||||
.hook(Hyprland.active.workspace, (box) => { |
||||
// Full update when going to new ws group
|
||||
const previousGroup = box.attribute.workspaceGroup; |
||||
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN); |
||||
if (currentGroup !== previousGroup) { |
||||
box.attribute.update(box); |
||||
box.attribute.workspaceGroup = currentGroup; |
||||
} |
||||
}) |
||||
.hook(App, (box, name, visible) => { // Update on open
|
||||
if (name == 'overview' && visible) box.attribute.update(box); |
||||
}) |
||||
}, |
||||
}); |
||||
|
||||
return Widget.Revealer({ |
||||
revealChild: true, |
||||
transition: 'slide_down', |
||||
transitionDuration: userOptions.animations.durationLarge, |
||||
child: Widget.Box({ |
||||
vertical: true, |
||||
className: 'overview-tasks', |
||||
children: Array.from({ length: userOptions.overview.numOfRows }, (_, index) => |
||||
OverviewRow({ |
||||
startWorkspace: 1 + index * userOptions.overview.numOfCols, |
||||
workspaces: userOptions.overview.numOfCols, |
||||
}) |
||||
) |
||||
}), |
||||
}); |
||||
} |
||||
@ -1,65 +0,0 @@
|
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; |
||||
|
||||
export const searchItem = ({ materialIconName, name, actionName, content, onActivate, extraClassName = '', ...rest }) => { |
||||
const actionText = Widget.Revealer({ |
||||
revealChild: false, |
||||
transition: "crossfade", |
||||
transitionDuration: userOptions.animations.durationLarge, |
||||
child: Widget.Label({ |
||||
className: 'overview-search-results-txt txt txt-small txt-action', |
||||
label: `${actionName}`, |
||||
}) |
||||
}); |
||||
const actionTextRevealer = Widget.Revealer({ |
||||
revealChild: false, |
||||
transition: "slide_left", |
||||
transitionDuration: userOptions.animations.durationSmall, |
||||
child: actionText, |
||||
}) |
||||
return Widget.Button({ |
||||
className: `overview-search-result-btn txt ${extraClassName}`, |
||||
onClicked: onActivate, |
||||
child: Widget.Box({ |
||||
children: [ |
||||
Widget.Box({ |
||||
vertical: false, |
||||
children: [ |
||||
Widget.Label({ |
||||
className: `icon-material overview-search-results-icon`, |
||||
label: `${materialIconName}`, |
||||
}), |
||||
Widget.Box({ |
||||
vertical: true, |
||||
children: [ |
||||
Widget.Label({ |
||||
hpack: 'start', |
||||
className: 'overview-search-results-txt txt-smallie txt-subtext', |
||||
label: `${name}`, |
||||
truncate: "end", |
||||
}), |
||||
Widget.Label({ |
||||
hpack: 'start', |
||||
className: 'overview-search-results-txt txt-norm', |
||||
label: `${content}`, |
||||
truncate: "end", |
||||
}), |
||||
] |
||||
}), |
||||
Widget.Box({ hexpand: true }), |
||||
actionTextRevealer, |
||||
], |
||||
}) |
||||
] |
||||
}), |
||||
setup: (self) => self |
||||
.on('focus-in-event', (button) => { |
||||
actionText.revealChild = true; |
||||
actionTextRevealer.revealChild = true; |
||||
}) |
||||
.on('focus-out-event', (button) => { |
||||
actionText.revealChild = false; |
||||
actionTextRevealer.revealChild = false; |
||||
}) |
||||
, |
||||
}); |
||||
} |
||||
@ -1,192 +0,0 @@
|
||||
*:not(popover) { |
||||
all: unset; |
||||
} |
||||
|
||||
@import '../../../.cache/wal/colors-waybar.css'; |
||||
/* @import '../../../.cache/wal/colors-waybar-rgba.css'; */ |
||||
|
||||
|
||||
widget { |
||||
border-radius: 0.818rem; |
||||
-gtk-outline-radius: 0.818rem; |
||||
} |
||||
|
||||
.overview-window { |
||||
margin-top: 2.727rem; |
||||
} |
||||
|
||||
.overview-search-box { |
||||
transition: 300ms cubic-bezier(0, 0.55, 0.45, 1); |
||||
border-radius: 1.705rem; |
||||
-gtk-outline-radius: 1.705rem; |
||||
border-top: 1px solid @color7; |
||||
border-left: 1px solid @color7; |
||||
border-right: 1px solid @color7; |
||||
border-bottom: 1px solid @color7; |
||||
/* box-shadow: 0px 2px 3px alpha(@color0, 0.45); */ |
||||
margin: 0.476rem; |
||||
min-width: 13.636rem; |
||||
min-height: 3.409rem; |
||||
padding: 0rem 1.364rem; |
||||
padding-right: 2.864rem; |
||||
background-color: alpha(@color0, 0.5); |
||||
color: alpha(@color7, 0.9); |
||||
caret-color: transparent; |
||||
font-weight: bold; |
||||
} |
||||
.overview-search-box selection { |
||||
background-color: #DEBCDF; |
||||
color: #402843; |
||||
} |
||||
|
||||
.overview-search-box-extended { |
||||
min-width: 25.909rem; |
||||
caret-color: #FDD9FD; |
||||
} |
||||
|
||||
.overview-search-prompt { |
||||
color: alpha(@color7, 0.9); |
||||
} |
||||
|
||||
.overview-search-icon { |
||||
margin: 0rem 1.023rem; |
||||
} |
||||
|
||||
.overview-search-prompt-box { |
||||
margin-left: -18.545rem; |
||||
margin-right: 0.544rem; |
||||
} |
||||
|
||||
.overview-search-icon-box { |
||||
margin-left: -18.545rem; |
||||
margin-right: 0.544rem; |
||||
} |
||||
|
||||
.overview-search-results { |
||||
border-radius: 1.705rem; |
||||
-gtk-outline-radius: 1.705rem; |
||||
border-top: 1px solid @color7; |
||||
border-left: 1px solid @color7; |
||||
border-right: 1px solid @color7; |
||||
border-bottom: 1px solid @color7; |
||||
box-shadow: 0px 2px 3px @color9; |
||||
margin: 0.476rem; |
||||
min-width: 28.773rem; |
||||
padding: 0.682rem; |
||||
background-color: alpha(@color2, 0.5); |
||||
color: alpha(@color7, 1.5); |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.overview-search-results-icon { |
||||
margin: 0rem 0.682rem; |
||||
font-size: 2.386rem; |
||||
min-width: 2.386rem; |
||||
min-height: 2.386rem; |
||||
} |
||||
|
||||
.overview-search-results-txt { |
||||
margin-right: 0.682rem; |
||||
} |
||||
|
||||
.overview-search-results-txt-cmd { |
||||
margin-right: 0.682rem; |
||||
font-family: "JetBrains Mono NF", "JetBrains Mono Nerd Font", "JetBrains Mono NL", "SpaceMono NF", "SpaceMono Nerd Font", monospace; |
||||
font-size: 1.227rem; |
||||
} |
||||
|
||||
.overview-search-result-btn { |
||||
border-radius: 1.159rem; |
||||
-gtk-outline-radius: 1.159rem; |
||||
padding: 0.341rem; |
||||
min-width: 2.386rem; |
||||
min-height: 2.386rem; |
||||
caret-color: transparent; |
||||
} |
||||
|
||||
.overview-search-result-btn:hover, |
||||
.overview-search-result-btn:focus { |
||||
background-color: alpha(@color7, 0.4); |
||||
color: alpha(@color0, 0.7); |
||||
} |
||||
|
||||
.overview-search-result-btn:active { |
||||
background-color: alpha(@color7, 0.4); |
||||
color: @color4; |
||||
} |
||||
|
||||
.overview-tasks { |
||||
border-radius: 1.705rem; |
||||
-gtk-outline-radius: 1.705rem; |
||||
border-top: 1px solid @color7; |
||||
border-left: 1px solid @color7; |
||||
border-right: 1px solid @color7; |
||||
border-bottom: 1px solid @color7; |
||||
box-shadow: 0px 2px 3px @color5; |
||||
margin: 0.476rem; |
||||
padding: 0.341rem; |
||||
/* background-color: rgba(49, 50, 68, 0.8); */ |
||||
background-color: alpha(@color0, 0.6); |
||||
color: #EBDFED; |
||||
} |
||||
|
||||
.overview-tasks-workspace { |
||||
border-radius: 1.159rem; |
||||
-gtk-outline-radius: 1.159rem; |
||||
margin: 0.341rem; |
||||
/* background-color: #26233A; */ |
||||
background-image: url('../../rofi/.current_wallpaper'); |
||||
background-size: cover; |
||||
background-position: center; |
||||
border: 0.068rem solid alpha(@color4, 0.5); |
||||
} |
||||
|
||||
.overview-tasks-workspace-number { |
||||
font-family: "Open Sans", "Noto Sans", sans-serif; |
||||
color: #CFC2D3; |
||||
} |
||||
|
||||
.overview-tasks-window { |
||||
border-radius: 1.159rem; |
||||
-gtk-outline-radius: 1.159rem; |
||||
transition: 300ms cubic-bezier(0.1, 1, 0, 1); |
||||
background-color: alpha(@color3, .7); |
||||
/* background-color: @color_a3; */ |
||||
/* background-color: rgba(46, 40, 50, 0.8); */ |
||||
color: #EBDFED; |
||||
border: 0.068rem solid @color7; |
||||
} |
||||
|
||||
.overview-tasks-window:hover, |
||||
.overview-tasks-window:focus { |
||||
background-color: alpha(@color9, 0.8); |
||||
} |
||||
|
||||
.overview-tasks-window:active { |
||||
background-color: alpha(@color9, 0.8); |
||||
} |
||||
|
||||
.overview-tasks-window-selected { |
||||
background-color: alpha(@color9, 0.8); |
||||
} |
||||
|
||||
.overview-tasks-window-dragging { |
||||
opacity: 0.2; |
||||
} |
||||
|
||||
.growingRadial { |
||||
transition: 300ms cubic-bezier(0.2, 0, 0, 1); |
||||
} |
||||
|
||||
.fadingRadial { |
||||
transition: 50ms cubic-bezier(0.2, 0, 0, 1); |
||||
} |
||||
|
||||
.sidebar-pinned { |
||||
margin: 0rem; |
||||
border-radius: 0rem; |
||||
border-bottom-right-radius: 1.705rem; |
||||
border: 0rem solid; |
||||
} |
||||
|
||||
/*# sourceMappingURL=style.css.map */ |
||||
@ -1,21 +0,0 @@
|
||||
|
||||
const userConfigOptions = { |
||||
// For every option, see ~/.config/ags/modules/.configuration/user_options.js
|
||||
// (vscode users ctrl+click this: file://./modules/.configuration/user_options.js)
|
||||
// (vim users: `:vsp` to split window, move cursor to this path, press `gf`. `Ctrl-w` twice to switch between)
|
||||
// options listed in this file will override the default ones in the above file
|
||||
// Here's an example
|
||||
'overview':{ |
||||
'scale': 0.15, |
||||
'numOfRows': 2 |
||||
}, |
||||
'keybinds': { |
||||
'sidebar': { |
||||
'pin': "Ctrl+p", |
||||
'nextTab': "Ctrl+Page_Down", |
||||
'prevTab': "Ctrl+Page_Up", |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
export default userConfigOptions; |
||||
@ -1,21 +0,0 @@
|
||||
const { Gtk } = imports.gi; |
||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js'; |
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; |
||||
const { exec, execAsync } = Utils; |
||||
|
||||
Gtk.IconTheme.get_default().append_search_path(`${App.configDir}/assets/icons`); |
||||
|
||||
// Screen size
|
||||
export const SCREEN_WIDTH = Number(exec(`bash -c "xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f1 | head -1" | awk '{print $1}'`)); |
||||
export const SCREEN_HEIGHT = Number(exec(`bash -c "xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f2 | head -1" | awk '{print $1}'`)); |
||||
|
||||
// Mode switching
|
||||
export const currentShellMode = Variable('normal', {}) // normal, focus
|
||||
globalThis['currentMode'] = currentShellMode; |
||||
globalThis['cycleMode'] = () => { |
||||
if (currentShellMode.value === 'normal') { |
||||
currentShellMode.value = 'focus'; |
||||
} else { |
||||
currentShellMode.value = 'normal'; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue