From e5ca1b234fc5ca73c6d336216660f66fc74d56b0 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sun, 9 Jun 2024 21:25:40 +0700 Subject: [PATCH] ags: autogenerated keybind cheatsheet (#271(?)) --- .../modules/.commonwidgets/tabcontainer.js | 1 - .../modules/.configuration/user_options.js | 4 +- .config/ags/modules/cheatsheet/keybinds.js | 177 +++++---- .config/ags/scripts/hyprland/get_keybinds.py | 211 +++++++++++ .config/ags/scss/_cheatsheet.scss | 8 +- .config/ags/scss/_lib_classes.scss | 16 + .config/hypr/hyprland/keybinds.conf | 355 +++++++++--------- 7 files changed, 513 insertions(+), 259 deletions(-) create mode 100755 .config/ags/scripts/hyprland/get_keybinds.py diff --git a/.config/ags/modules/.commonwidgets/tabcontainer.js b/.config/ags/modules/.commonwidgets/tabcontainer.js index 93fa74d5..876875dd 100644 --- a/.config/ags/modules/.commonwidgets/tabcontainer.js +++ b/.config/ags/modules/.commonwidgets/tabcontainer.js @@ -103,7 +103,6 @@ export const IconTabContainer = ({ let previousShownIndex = 0; const count = Math.min(iconWidgets.length, names.length, children.length); const tabs = Box({ - homogeneous: true, hpack: tabsHpack, className: `spacing-h-5 ${tabSwitcherClassName}`, children: iconWidgets.map((icon, i) => Button({ diff --git a/.config/ags/modules/.configuration/user_options.js b/.config/ags/modules/.configuration/user_options.js index 781258aa..1ddfdbcd 100644 --- a/.config/ags/modules/.configuration/user_options.js +++ b/.config/ags/modules/.configuration/user_options.js @@ -185,8 +185,8 @@ let configOptions = { 'prevTab': "Ctrl+Page_Up", }, 'cheatsheet': { - 'nextTab': "Page_Down", - 'prevTab': "Page_Up", + 'nextTab': "Ctrl+Page_Down", + 'prevTab': "Ctrl+Page_Up", } }, } diff --git a/.config/ags/modules/cheatsheet/keybinds.js b/.config/ags/modules/cheatsheet/keybinds.js index a069f96d..42618c19 100644 --- a/.config/ags/modules/cheatsheet/keybinds.js +++ b/.config/ags/modules/cheatsheet/keybinds.js @@ -1,78 +1,115 @@ -const { Gtk } = imports.gi; -import Widget from 'resource:///com/github/Aylur/ags/widget.js'; -import { keybindList } from "./data_keybinds.js"; +const { GLib, Gtk } = imports.gi; +import App from "resource:///com/github/Aylur/ags/app.js"; +import * as Utils from "resource:///com/github/Aylur/ags/utils.js"; +import Widget from "resource:///com/github/Aylur/ags/widget.js"; +import { IconTabContainer } from "../.commonwidgets/tabcontainer.js"; +const { Box, Label, Scrollable } = Widget; -export default () => { - const Category = (category) => Widget.Box({ // Categories +const HYPRLAND_KEYBIND_CONFIG_FILE = `${GLib.get_user_config_dir()}/hypr/hyprland/keybinds.conf`; +const KEYBIND_SECTIONS_PER_PAGE = 3; +const keybindList = JSON.parse( + Utils.exec( + `${App.configDir}/scripts/hyprland/get_keybinds.py --path ${HYPRLAND_KEYBIND_CONFIG_FILE}`, + ), +); + +const keySubstitutions = { + "Super": "󰖳", + "mouse_up": "Scroll ↓", // ikr, weird + "mouse_down": "Scroll ↑", // trust me bro + "mouse:272": "LMB", + "mouse:273": "RMB", + "mouse:275": "MouseBack", +} + +const substituteKey = (key) => { + return keySubstitutions[key] || key; +} + +const Keybind = (keybindData, type) => { // type: either "keys" or "actions" + const Key = (key) => Label({ // Specific keys + vpack: 'center', + className: `${['OR', '+'].includes(key) ? 'cheatsheet-key-notkey' : 'cheatsheet-key'} txt-small`, + label: substituteKey(key), + }); + const Action = (text) => Label({ // Binds + xalign: 0, + label: text, + className: "txt txt-small cheatsheet-action", + }) + return Widget.Box({ + className: "spacing-h-10 cheatsheet-bind-lineheight", + children: type == "keys" ? [ + ...(keybindData.mods.length > 0 ? [ + ...keybindData.mods.map(Key), + Key("+"), + ] : []), + Key(keybindData.key), + ] : [Action(keybindData.comment)], + }) +} + +const Section = (sectionData, scope) => { + const keys = Box({ vertical: true, - className: "spacing-v-15", + className: 'spacing-v-5', + children: sectionData.keybinds.map((data) => Keybind(data, "keys")) + }) + const actions = Box({ + vertical: true, + className: 'spacing-v-5', + children: sectionData.keybinds.map((data) => Keybind(data, "actions")) + }) + const name = Label({ + xalign: 0, + className: "cheatsheet-category-title txt margin-bottom-10", + label: sectionData.name, + }) + const binds = Box({ + className: 'spacing-h-10', children: [ - Widget.Box({ // Category header - vertical: false, - className: "spacing-h-10", + keys, + actions, + ] + }) + const childrenSections = Box({ + vertical: true, + className: 'spacing-v-15', + children: sectionData.children.map((data) => Section(data, scope + 1)) + }) + return Box({ + vertical: true, + children: [ + ...((sectionData.name && sectionData.name.length > 0) ? [name] : []), + Box({ + className: 'spacing-v-10', children: [ - Widget.Label({ - xalign: 0, - className: `icon-material txt-larger cheatsheet-color-${category.id}`, - label: category.icon, - }), - Widget.Label({ - xalign: 0, - className: "cheatsheet-category-title txt", - label: category.name, - }), - ] - }), - Widget.Box({ - vertical: false, - className: "spacing-h-10", - children: [ - Widget.Box({ // Keys - vertical: true, - homogeneous: true, - children: category.binds.map((keybinds, _) => Widget.Box({ // Binds - vertical: false, - children: keybinds.keys.map((key, _) => Widget.Label({ // Specific keys - className: `${['OR', '+'].includes(key) ? 'cheatsheet-key-notkey' : 'cheatsheet-key cheatsheet-color-' + category.id} txt-small`, - label: key, - })) - })) - }), - Widget.Box({ // Actions - vertical: true, - homogeneous: true, - children: category.binds.map((keybinds, _) => Widget.Label({ // Binds - xalign: 0, - label: keybinds.action, - className: "txt chearsheet-action txt-small", - })) - }) + binds, + childrenSections, ] }) ] }) - const realKeybinds = Widget.Box({ - vertical: false, - className: "spacing-h-15", - homogeneous: true, - children: keybindList.map((group, _) => Widget.Box({ // Columns - vertical: true, - className: "spacing-v-15", - children: group.map((category, _) => Category(category)) - })), - }) - return Widget.Box({ - vertical: true, - className: "spacing-v-10", - children: [ - Widget.Label({ - useMarkup: true, - selectable: true, - justify: Gtk.Justification.CENTER, - className: 'txt-small txt', - label: 'Sheet data stored in ~/.config/ags/modules/cheatsheet/data_keybinds.js\nChange keybinds in ~/.config/hypr/hyprland/keybinds.conf' - }), - realKeybinds, - ] - }) -} \ No newline at end of file +}; + +export default () => { + const numOfTabs = Math.ceil(keybindList.children.length / KEYBIND_SECTIONS_PER_PAGE); + const keybindPages = Array.from({ length: numOfTabs }, (_, i) => ({ + iconWidget: Label({ + className: "txt txt-small", + label: `${i + 1}`, + }), + name: `${i + 1}`, + child: Box({ + className: 'spacing-h-30', + children: keybindList.children.slice( + KEYBIND_SECTIONS_PER_PAGE * i, 0 + KEYBIND_SECTIONS_PER_PAGE * (i + 1), + ).map(data => Section(data, 1)), + }), + })); + return IconTabContainer({ + iconWidgets: keybindPages.map((kbp) => kbp.iconWidget), + names: keybindPages.map((kbp) => kbp.name), + children: keybindPages.map((kbp) => kbp.child), + }); +}; diff --git a/.config/ags/scripts/hyprland/get_keybinds.py b/.config/ags/scripts/hyprland/get_keybinds.py new file mode 100755 index 00000000..00bacdc2 --- /dev/null +++ b/.config/ags/scripts/hyprland/get_keybinds.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 +import argparse +import re +from os.path import expandvars as os_expandvars +from typing import Dict, List + +TITLE_REGEX = "#+!" +HIDE_COMMENT = "[hidden]" +MOD_SEPARATORS = ['+', ' '] + +parser = argparse.ArgumentParser(description='Hyprland keybind reader') +parser.add_argument('--path', type=str, default="$HOME/.config/hypr/hyprland.conf", help='path to keybind file (sourcing isn\'t supported)') +args = parser.parse_args() +content_lines = [] +reading_line = 0 + +# Little Parser made for hyprland keybindings conf file +Variables: Dict[str, str] = {} + + +class KeyBinding(dict): + def __init__(self, mods, key, dispatcher, params, comment) -> None: + self["mods"] = mods + self["key"] = key + self["dispatcher"] = dispatcher + self["params"] = params + self["comment"] = comment + +class Section(dict): + def __init__(self, children, keybinds, name) -> None: + self["children"] = children + self["keybinds"] = keybinds + self["name"] = name + + +def read_content(path: str) -> str: + with open(os_expandvars(path), "r") as file: + return file.read() + + +def autogenerate_comment(dispatcher: str, params: str = "") -> str: + match dispatcher: + + case "resizewindow": + return "Resize window" + + case "movewindow": + if(params == ""): + return "Move window" + else: + return "Window: move in {} direction".format({ + "l": "left", + "r": "right", + "u": "up", + "d": "down", + }.get(params, "null")) + + case "pin": + return "Pin window" + + case "splitratio": + return "Window split ratio {}".format(params) + + case "togglefloating": + return "Float/unfloat window" + + case "resizeactive": + return "Resize window by {}".format(params) + + case "killactive": + return "Close window" + + case "fullscreen": + return "Toggle {}".format( + { + "0": "fullscreen", + "1": "maximization", + "2": "fullscreen on Hyprland's side", + }.get(params, "null") + ) + + case "fakefullscreen": + return "Toggle fake fullscreen" + + case "workspace": + if params == "+1": + return "Workspace: focus right" + elif params == "-1": + return "Workspace: focus left" + return "Focus workspace {}".format(params) + + case "movefocus": + return "Window: move focus {}".format( + { + "l": "left", + "r": "right", + "u": "up", + "d": "down", + }.get(params, "null") + ) + + case "swapwindow": + return "Window: swap in {} direction".format( + { + "l": "left", + "r": "right", + "u": "up", + "d": "down", + }.get(params, "null") + ) + + case "movetoworkspace": + if params == "+1": + return "Window: move to right workspace (non-silent)" + elif params == "-1": + return "Window: move to left workspace (non-silent)" + return "Window: move to workspace {} (non-silent)".format(params) + + case "movetoworkspacesilent": + if params == "+1": + return "Window: move to right workspace" + elif params == "-1": + return "Window: move to right workspace" + return "Window: move to workspace {}".format(params) + + case "togglespecialworkspace": + return "Toggle special workspace" + + case "exec": + return "Execute: {}".format(params) + + case _: + return "" + +def get_keybind_at_line(line_number): + global content_lines + line = content_lines[line_number] + _, keys = line.split("=", 1) + keys, *comment = keys.split("#", 1) + + mods, key, dispatcher, *params = list(map(str.strip, keys.split(",", 4))) + params = "".join(map(str.strip, params)) + + # Remove empty spaces + comment = list(map(str.strip, comment)) + # Add comment if it exists, else generate it + if comment: + comment = comment[0] + if comment.startswith("[hidden]"): + return None + else: + comment = autogenerate_comment(dispatcher, params) + + if mods: + modstring = mods + MOD_SEPARATORS[0] # Add separator at end to ensure last mod is read + mods = [] + p = 0 + for index, char in enumerate(modstring): + if(char in MOD_SEPARATORS): + if(index - p > 1): + mods.append(modstring[p:index]) + p = index+1 + else: + mods = [] + + return KeyBinding(mods, key, dispatcher, params, comment) + +def get_binds_recursive(current_content, scope): + global content_lines + global reading_line + # print("get_binds_recursive({0}, {1}) [@L{2}]".format(current_content, scope, reading_line + 1)) + while reading_line < len(content_lines): # TODO: Adjust condition + line = content_lines[reading_line] + heading_search_result = re.search(TITLE_REGEX, line) + # print("Read line {0}: {1}\tisHeading: {2}".format(reading_line + 1, content_lines[reading_line], "[{0}, {1}, {2}]".format(heading_search_result.start(), heading_search_result.start() == 0, ((heading_search_result != None) and (heading_search_result.start() == 0))) if heading_search_result != None else "No")) + if ((heading_search_result != None) and (heading_search_result.start() == 0)): # Found title + # Determine scope + heading_scope = line.find('!') + # Lower? Return + if(heading_scope <= scope): + reading_line -= 1 + return current_content + + section_name = line[(heading_scope+1):].strip() + # print("[[ Found h{0} at line {1} ]] {2}".format(heading_scope, reading_line+1, content_lines[reading_line])) + reading_line += 1 + current_content["children"].append(get_binds_recursive(Section([], [], section_name), heading_scope)) + + elif line == "" or line.startswith("$") or line.startswith("#"): # Comment, ignore + pass + + else: # Normal keybind + keybind = get_keybind_at_line(reading_line) + if(keybind != None): + current_content["keybinds"].append(keybind) + + reading_line += 1 + + return current_content; + +def parse_keys(path: str) -> Dict[str, List[KeyBinding]]: + global content_lines + content_lines = read_content(path).splitlines() + return get_binds_recursive(Section([], [], ""), 0) + + +if __name__ == "__main__": + import json + + ParsedKeys = parse_keys(args.path) + print(json.dumps(ParsedKeys)) diff --git a/.config/ags/scss/_cheatsheet.scss b/.config/ags/scss/_cheatsheet.scss index 336fd9a5..69c36a1e 100644 --- a/.config/ags/scss/_cheatsheet.scss +++ b/.config/ags/scss/_cheatsheet.scss @@ -119,6 +119,7 @@ $coloractinium: $term7; background-color: $colorlanthanum; color: $term0; } + .cheatsheet-periodictable-actinium { @include cheatsheet-periodictable-element; background-color: $coloractinium; @@ -141,17 +142,22 @@ $coloractinium: $term7; @include cheatsheet-periodictable-legend-color; background-color: $colormetal; } + .cheatsheet-periodictable-legend-color-nonmetal { @include cheatsheet-periodictable-legend-color; background-color: $colornonmetal; } + .cheatsheet-periodictable-legend-color-noblegas { @include cheatsheet-periodictable-legend-color; background-color: $colornoblegas; -}.cheatsheet-periodictable-legend-color-lanthanum { +} + +.cheatsheet-periodictable-legend-color-lanthanum { @include cheatsheet-periodictable-legend-color; background-color: $colorlanthanum; } + .cheatsheet-periodictable-legend-color-actinium { @include cheatsheet-periodictable-legend-color; background-color: $coloractinium; diff --git a/.config/ags/scss/_lib_classes.scss b/.config/ags/scss/_lib_classes.scss index 9c162633..50daefc7 100644 --- a/.config/ags/scss/_lib_classes.scss +++ b/.config/ags/scss/_lib_classes.scss @@ -374,6 +374,22 @@ margin-bottom: 0rem; } +.spacing-h-30>* { + margin-right: 1.364rem; +} + +.spacing-h-30>*:last-child { + margin-right: 0rem; +} + +.spacing-v-30>* { + margin-bottom: 1.364rem; +} + +.spacing-v-30>*:last-child { + margin-bottom: 0rem; +} + .anim-enter { @include anim-enter; } diff --git a/.config/hypr/hyprland/keybinds.conf b/.config/hypr/hyprland/keybinds.conf index 7e17ac5f..ea5af7be 100644 --- a/.config/hypr/hyprland/keybinds.conf +++ b/.config/hypr/hyprland/keybinds.conf @@ -1,208 +1,193 @@ -# ################### It just works™ keybinds ################### -# Volume -bindl = Super ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle -bindl = Alt ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle -bindl = ,XF86AudioMute, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0% -bindl = Super+Shift,M, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0% -bindle=, XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ -bindle=, XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- +# Lines ending with `# [hidden]` won't be shown on cheatsheet +# Lines starting with #! are section headings + +bindl = Alt ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden] +bindl = Super ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden] +bindl = ,XF86AudioMute, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0% # [hidden] +bindl = Super+Shift,M, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0% # [hidden] +bindle=, XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ # [hidden] +bindle=, XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- # [hidden] -# Brightness # Uncomment these if you can't get AGS to work #bindle=, XF86MonBrightnessUp, exec, brightnessctl set '12.75+' #bindle=, XF86MonBrightnessDown, exec, brightnessctl set '12.75-' -# ################################### Applications ################################### -# Apps: just normal apps -bind = Super, Z, exec, Zed -bind = Super, C, exec, code --password-store=gnome --enable-features=UseOzonePlatform --ozone-platform=wayland -bind = Super, T, exec, foot -# bind = Super, Return, exec, foot --override shell=fish -bind = Super, E, exec, nautilus --new-window -bind = Super+Alt, E, exec, thunar -bind = Super, W, exec, firefox -bind = Control+Super, W, exec, thorium-browser --ozone-platform-hint=wayland --gtk-version=4 --ignore-gpu-blocklist --enable-features=TouchpadOverscrollHistoryNavigation --enable-wayland-ime -bind = Super, X, exec, gnome-text-editor --new-window -bind = Super+Shift, W, exec, wps - -# Apps: Settings and config -bind = Super, I, exec, XDG_CURRENT_DESKTOP="gnome" gnome-control-center -bind = Control+Super, V, exec, pavucontrol -bind = Control+Super+Shift, V, exec, easyeffects -bind = Control+Shift, Escape, exec, gnome-system-monitor - -# Actions -bind = Super, Period, exec, pkill fuzzel || ~/.local/bin/fuzzel-emoji -bind = Super, Q, killactive, -bind = Super+Alt, Space, togglefloating, -bind = Shift+Super+Alt, Q, exec, hyprctl kill -bind = Control+Shift+Alt, Delete, exec, pkill wlogout || wlogout -p layer-shell -bind = Control+Shift+Alt+Super, Delete, exec, systemctl poweroff || loginctl poweroff - +#! +##! Essentials for beginners +bind = Super, T, exec, foot # Launch foot (terminal) +bind = Ctrl+Super, T, exec, ~/.config/ags/scripts/color_generation/switchwall.sh # Change wallpaper +##! Actions # Screenshot, Record, OCR, Color picker, Clipboard history -bind = Super+Shift+Alt, S, exec, grim -g "$(slurp)" - | swappy -f - -bindl=,Print,exec,grim - | wl-copy -bindl= Control,Print, exec, mkdir -p ~/Pictures/Screenshots && ~/.config/ags/scripts/grimblast.sh copysave screen ~/Pictures/Screenshots/Screenshot_"$(date '+%Y-%m-%d_%H.%M.%S')".png -bind = Super+Shift, S, exec, ~/.config/ags/scripts/grimblast.sh --freeze copy area -bind = Super+Alt, R, exec, ~/.config/ags/scripts/record-script.sh -bind = Control+Alt, R, exec, ~/.config/ags/scripts/record-script.sh --fullscreen -bind = Super+Shift+Alt, R, exec, ~/.config/ags/scripts/record-script.sh --fullscreen-sound -bind = Super+Shift, C, exec, hyprpicker -a -bind = Super, V, exec, pkill fuzzel || cliphist list | fuzzel --no-fuzzy --dmenu | cliphist decode | wl-copy +bind = Super, V, exec, pkill fuzzel || cliphist list | fuzzel --no-fuzzy --dmenu | cliphist decode | wl-copy # Clipboard history >> clipboard +bind = Super, Period, exec, pkill fuzzel || ~/.local/bin/fuzzel-emoji # Pick emoji >> clipboard +bind = Ctrl+Shift+Alt, Delete, exec, pkill wlogout || wlogout -p layer-shell # [hidden] +bind = Super+Shift, S, exec, ~/.config/ags/scripts/grimblast.sh --freeze copy area # Screen snip +bind = Super+Shift+Alt, S, exec, grim -g "$(slurp)" - | swappy -f - # Screen snip >> edit +# OCR +bind = Super+Shift,T,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract -l eng "tmp.png" - | wl-copy && rm "tmp.png" # Screen snip to text >> clipboard +bind = Ctrl+Super+Shift,S,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract "tmp.png" - | wl-copy && rm "tmp.png" # [hidden] +# Color picker +bind = Super+Shift, C, exec, hyprpicker -a # Pick color (Hex) >> clipboard +# Fullscreen screenshot +bindl=,Print,exec,grim - | wl-copy # Screenshot >> clipboard +bindl= Ctrl,Print, exec, mkdir -p ~/Pictures/Screenshots && ~/.config/ags/scripts/grimblast.sh copysave screen ~/Pictures/Screenshots/Screenshot_"$(date '+%Y-%m-%d_%H.%M.%S')".png # Screenshot >> clipboard & file +# Recording stuff +bind = Super+Alt, R, exec, ~/.config/ags/scripts/record-script.sh # Record region (no sound) +bind = Ctrl+Alt, R, exec, ~/.config/ags/scripts/record-script.sh --fullscreen # [hidden] Record screen (no sound) +bind = Super+Shift+Alt, R, exec, ~/.config/ags/scripts/record-script.sh --fullscreen-sound # Record screen (with sound) +##! Session +bind = Ctrl+Super, L, exec, ags run-js 'lock.lock()' # [hidden] +bind = Super, L, exec, loginctl lock-session # Lock +bind = Super+Shift, L, exec, loginctl lock-session # [hidden] +bindl = Super+Shift, L, exec, sleep 0.1 && systemctl suspend || loginctl suspend # Suspend system +bind = Ctrl+Shift+Alt+Super, Delete, exec, systemctl poweroff || loginctl poweroff # [hidden] Power off -# Text-to-image -# Normal -bind = Control+Super+Shift,S,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract "tmp.png" - | wl-copy && rm "tmp.png" -# English -bind = Super+Shift,T,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract -l eng "tmp.png" - | wl-copy && rm "tmp.png" -# Japanese -bind = Super+Shift,J,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract -l jpn "tmp.png" - | wl-copy && rm "tmp.png" - -# Media -bindl= Super+Shift, N, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` -bindl= ,XF86AudioNext, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` -bind = Super+Shift+Alt, mouse:275, exec, playerctl previous -bind = Super+Shift+Alt, mouse:276, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` -bindl= Super+Shift, B, exec, playerctl previous -bindl= Super+Shift, P, exec, playerctl play-pause -bindl= ,XF86AudioPlay, exec, playerctl play-pause - -# Lock screen -bind = Super, L, exec, loginctl lock-session -bind = Super+Shift, L, exec, loginctl lock-session -bindl = Super+Shift, L, exec, sleep 0.1 && systemctl suspend || loginctl suspend - -# App launcher -bind = Control+Super, Slash, exec, pkill anyrun || anyrun - -# ##################################### AGS keybinds ##################################### -bindr = Control+Super, R, exec, killall ags ydotool; ags & -bindr = Control+Super+Alt, R, exec, hyprctl reload; killall ags ydotool; ags & -bind = Control+Super, T, exec, ~/.config/ags/scripts/color_generation/switchwall.sh -bind = Control+Alt, Slash, exec, ags run-js 'cycleMode();' -bindir = Super, Super_L, exec, ags -t 'overview' -bind = Super, Tab, exec, ags -t 'overview' -bind = Super, Slash, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "cheatsheet""$i"; done -bind = Super, B, exec, ags -t 'sideleft' -bind = Super, A, exec, ags -t 'sideleft' -bind = Super, O, exec, ags -t 'sideleft' -bind = Super, N, exec, ags -t 'sideright' -bind = Super, M, exec, ags run-js 'openMusicControls.value = (!mpris.getPlayer() ? false : !openMusicControls.value);' -bind = Super, Comma, exec, ags run-js 'openColorScheme.value = true; Utils.timeout(2000, () => openColorScheme.value = false);' -bind = Super, K, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "osk""$i"; done -bind = Control+Alt, Delete, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "session""$i"; done -bind = Control+Super, G, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "crosshair""$i"; done -bindle=, XF86MonBrightnessUp, exec, ags run-js 'brightness.screen_value += 0.05; indicator.popup(1);' -bindle=, XF86MonBrightnessDown, exec, ags run-js 'brightness.screen_value -= 0.05; indicator.popup(1);' -bindl = , XF86AudioMute, exec, ags run-js 'indicator.popup(1);' -bindl = Super+Shift,M, exec, ags run-js 'indicator.popup(1);' - -# ##################################### Plugins ######################################### - -# Testing -# bind = SuperAlt, f12, exec, notify-send "Hyprland version: $(hyprctl version | head -2 | tail -1 | cut -f2 -d ' ')" "owo" -a 'Hyprland keybind' -# bind = Super+Alt, f12, exec, notify-send "Millis since epoch" "$(date +%s%N | cut -b1-13)" -a 'Hyprland keybind' -bind = Super+Alt, f12, exec, notify-send 'Test notification' "Here's a really long message to test truncation and wrapping\nYou can middle click or flick this notification to dismiss it!" -a 'Shell' -A "Test1=I got it!" -A "Test2=Another action" -t 5000 -bind = Super+Alt, Equal, exec, notify-send "Urgent notification" "Ah hell no" -u critical -a 'Hyprland keybind' - -# ########################### Keybinds for Hyprland ############################ -# Swap windows -bind = Super+Shift, left, movewindow, l -bind = Super+Shift, right, movewindow, r -bind = Super+Shift, up, movewindow, u -bind = Super+Shift, down, movewindow, d -bind = Super, P, pin +#! +##! Window management +bindm = Super, mouse:272, movewindow +bindm = Super, mouse:273, resizewindow +bind = Super, Q, killactive, +bind = Super+Shift+Alt, Q, exec, hyprctl kill # Pick and kill a window +bind = Super+Alt, Space, togglefloating, # Move focus -bind = Super, left, movefocus, l -bind = Super, right, movefocus, r -bind = Super, up, movefocus, u -bind = Super, down, movefocus, d -bind = Super, BracketLeft, movefocus, l -bind = Super, BracketRight, movefocus, r +bind = Super, Left, movefocus, l +bind = Super, Right, movefocus, r +bind = Super, Up, movefocus, u +bind = Super, Down, movefocus, d +bind = Super, BracketLeft, movefocus, l # [hidden] +bind = Super, BracketRight, movefocus, r # [hidden] +# Move windows +bind = Super+Shift, Left, movewindow, l +bind = Super+Shift, Right, movewindow, r +bind = Super+Shift, Up, movewindow, u +bind = Super+Shift, Down, movewindow, d +bind = Super, P, pin +# Window split ratio +binde = Super, Minus, splitratio, -0.1 +binde = Super, Equal, splitratio, +0.1 +binde = Super, Semicolon, splitratio, -0.1 # [hidden] +binde = Super, Apostrophe, splitratio, +0.1 # [hidden] +# Fullscreen +bind = Super, F, fullscreen, 0 +bind = Super+Alt, F, fakefullscreen, +bind = Super, D, fullscreen, 1 -# Workspace, window, tab switch with keyboard -bind = Control+Super, right, workspace, +1 -bind = Control+Super, left, workspace, -1 -bind = Super, mouse:275, workspace, -1 -bind = Super, mouse:276, workspace, +1 -bind = Control+Super, BracketLeft, workspace, -1 -bind = Control+Super, BracketRight, workspace, +1 -bind = Control+Super, up, workspace, -5 -bind = Control+Super, down, workspace, +5 -bind = Super, Page_Down, workspace, +1 -bind = Super, Page_Up, workspace, -1 -bind = Control+Super, Page_Down, workspace, +1 -bind = Control+Super, Page_Up, workspace, -1 -bind = Super+Alt, Page_Down, movetoworkspace, +1 -bind = Super+Alt, Page_Up, movetoworkspace, -1 -bind = Super+Shift, Page_Down, movetoworkspace, +1 -bind = Super+Shift, Page_Up, movetoworkspace, -1 -bind = Control+Super+Shift, Right, movetoworkspace, +1 -bind = Control+Super+Shift, Left, movetoworkspace, -1 +#! +##! Workspace management +# Mouse family +bind = Super, mouse_up, workspace, +1 +bind = Super, mouse_down, workspace, -1 +bind = Super, mouse:275, togglespecialworkspace, +bind = Ctrl+Super, mouse_up, workspace, +1 +bind = Ctrl+Super, mouse_down, workspace, -1 bind = Super+Shift, mouse_down, movetoworkspace, -1 bind = Super+Shift, mouse_up, movetoworkspace, +1 bind = Super+Alt, mouse_down, movetoworkspace, -1 bind = Super+Alt, mouse_up, movetoworkspace, +1 - -# Window split ratio -binde = Super, Minus, splitratio, -0.1 -binde = Super, Equal, splitratio, 0.1 -binde = Super, Semicolon, splitratio, -0.1 -binde = Super, Apostrophe, splitratio, 0.1 - -# Fullscreen -bind = Super, F, fullscreen, 0 -bind = Super, D, fullscreen, 1 -bind = Super_Alt, F, fakefullscreen, 0 +# Windows family +bind = Ctrl+Super, Right, workspace, +1 +bind = Ctrl+Super, Left, workspace, -1 +bind = Ctrl+Super+Shift, Right, movetoworkspace, +1 +bind = Ctrl+Super+Shift, Left, movetoworkspace, -1 +bind = Ctrl+Super, BracketLeft, workspace, -1 # [hidden] +bind = Ctrl+Super, BracketRight, workspace, +1 # [hidden] +bind = Ctrl+Super, Up, workspace, -5 # [hidden] +bind = Ctrl+Super, Down, workspace, +5 # [hidden] +# GNOME family +bind = Super, Page_Down, workspace, +1 +bind = Super, Page_Up, workspace, -1 +bind = Ctrl+Super, Page_Down, workspace, +1 # [hidden] +bind = Ctrl+Super, Page_Up, workspace, -1 # [hidden] +bind = Super+Alt, Page_Down, movetoworkspace, +1 # [hidden] +bind = Super+Alt, Page_Up, movetoworkspace, -1 # [hidden] +bind = Super+Shift, Page_Down, movetoworkspace, +1 +bind = Super+Shift, Page_Up, movetoworkspace, -1 # Switching -bind = Super, 1, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 1 -bind = Super, 2, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 2 -bind = Super, 3, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 3 -bind = Super, 4, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 4 -bind = Super, 5, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 5 -bind = Super, 6, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 6 -bind = Super, 7, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 7 -bind = Super, 8, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 8 -bind = Super, 9, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 9 -bind = Super, 0, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 10 +bind = Super, 1, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 1 # [hidden] +bind = Super, 2, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 2 # [hidden] +bind = Super, 3, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 3 # [hidden] +bind = Super, 4, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 4 # [hidden] +bind = Super, 5, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 5 # [hidden] +bind = Super, 6, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 6 # [hidden] +bind = Super, 7, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 7 # [hidden] +bind = Super, 8, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 8 # [hidden] +bind = Super, 9, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 9 # [hidden] +bind = Super, 0, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh workspace 10 # [hidden] bind = Super, S, togglespecialworkspace, -bind = Control+Super, S, togglespecialworkspace, -bind = Alt, Tab, cyclenext -bind = Alt, Tab, bringactivetotop, # bring it to the top +bind = Ctrl+Super, S, togglespecialworkspace, # [hidden] +bind = Alt, Tab, cyclenext # [hidden] sus keybind +bind = Alt, Tab, bringactivetotop, # [hidden] bring it to the top # Move window to workspace Super + Alt + [0-9] -bind = Super+Alt, 1, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 1 -bind = Super+Alt, 2, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 2 -bind = Super+Alt, 3, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 3 -bind = Super+Alt, 4, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 4 -bind = Super+Alt, 5, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 5 -bind = Super+Alt, 6, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 6 -bind = Super+Alt, 7, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 7 -bind = Super+Alt, 8, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 8 -bind = Super+Alt, 9, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 9 -bind = Super+Alt, 0, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 10 -bind = Control+Shift+Super, Up, movetoworkspacesilent, special +bind = Super+Alt, 1, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 1 # [hidden] +bind = Super+Alt, 2, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 2 # [hidden] +bind = Super+Alt, 3, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 3 # [hidden] +bind = Super+Alt, 4, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 4 # [hidden] +bind = Super+Alt, 5, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 5 # [hidden] +bind = Super+Alt, 6, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 6 # [hidden] +bind = Super+Alt, 7, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 7 # [hidden] +bind = Super+Alt, 8, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 8 # [hidden] +bind = Super+Alt, 9, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 9 # [hidden] +bind = Super+Alt, 0, exec, ~/.config/ags/scripts/hyprland/workspace_action.sh movetoworkspacesilent 10 # [hidden] +bind = Ctrl+Super+Shift, Up, movetoworkspacesilent, special # [hidden] bind = Super+Alt, S, movetoworkspacesilent, special -# Scroll through existing workspaces with (Control) + Super + scroll -bind = Super, mouse_up, workspace, +1 -bind = Super, mouse_down, workspace, -1 -bind = Control+Super, mouse_up, workspace, +1 -bind = Control+Super, mouse_down, workspace, -1 +#! +##! Widgets +bindr = Ctrl+Super, R, exec, killall ags ydotool; ags & # Restart widgets +bindr = Ctrl+Super+Alt, R, exec, hyprctl reload; killall ags ydotool; ags & # [hidden] +bind = Ctrl+Alt, Slash, exec, ags run-js 'cycleMode();' # Cycle bar mode (normal, focus) +bindir = Super, Super_L, exec, ags -t 'overview' # Toggle overview/launcher +bind = Super, Tab, exec, ags -t 'overview' # [hidden] +bind = Super, Slash, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "cheatsheet""$i"; done # Show cheatsheet +bind = Super, B, exec, ags -t 'sideleft' # Toggle left sidebar +bind = Super, A, exec, ags -t 'sideleft' # [hidden] +bind = Super, O, exec, ags -t 'sideleft' # [hidden] +bind = Super, N, exec, ags -t 'sideright' # Toggle right sidebar +bind = Super, M, exec, ags run-js 'openMusicControls.value = (!mpris.getPlayer() ? false : !openMusicControls.value);' # Toggle music controls +bind = Super, Comma, exec, ags run-js 'openColorScheme.value = true; Utils.timeout(2000, () => openColorScheme.value = false);' # View color scheme and options +bind = Super, K, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "osk""$i"; done # Toggle on-screen keyboard +bind = Ctrl+Alt, Delete, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "session""$i"; done # Toggle power menu +bind = Ctrl+Super, G, exec, for ((i=0; i<$(hyprctl monitors -j | jq length); i++)); do ags -t "crosshair""$i"; done # Toggle crosshair +bindle=, XF86MonBrightnessUp, exec, ags run-js 'brightness.screen_value += 0.05; indicator.popup(1);' # [hidden] +bindle=, XF86MonBrightnessDown, exec, ags run-js 'brightness.screen_value -= 0.05; indicator.popup(1);' # [hidden] +bindl = , XF86AudioMute, exec, ags run-js 'indicator.popup(1);' # [hidden] +bindl = Super+Shift,M, exec, ags run-js 'indicator.popup(1);' # [hidden] -# Move/resize windows with Super + LMB/RMB and dragging -bindm = Super, mouse:272, movewindow -bindm = Super, mouse:273, resizewindow -# bindm = Super, mouse:274, movewindow -bind = Control+Super, Backslash, resizeactive, exact 640 480 +# Testing +# bind = SuperAlt, f12, exec, notify-send "Hyprland version: $(hyprctl version | head -2 | tail -1 | cut -f2 -d ' ')" "owo" -a 'Hyprland keybind' +# bind = Super+Alt, f12, exec, notify-send "Millis since epoch" "$(date +%s%N | cut -b1-13)" -a 'Hyprland keybind' +bind = Super+Alt, f12, exec, notify-send 'Test notification' "Here's a really long message to test truncation and wrapping\nYou can middle click or flick this notification to dismiss it!" -a 'Shell' -A "Test1=I got it!" -A "Test2=Another action" -t 5000 # [hidden] +bind = Super+Alt, Equal, exec, notify-send "Urgent notification" "Ah hell no" -u critical -a 'Hyprland keybind' # [hidden] -# Arrow keys with IJKL -bindle = Alt, I, exec, ydotool key 103:1 103:0 -bindle = Alt, K, exec, ydotool key 108:1 108:0 -bindle = Alt, J, exec, ydotool key 105:1 105:0 -bindle = Alt, L, exec, ydotool key 106:1 106:0 -# Control + Side mouse btn for switching tabs (Ctrl+PgUp/PgDn) -# bind = Control, mouse:275, exec, ydotool key 29:1 104:1 104:0 29:0 -# bind = Control, mouse:276, exec, ydotool key 29:1 109:1 109:0 29:0 +##! Media +bindl= Super+Shift, N, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # Next track +bindl= ,XF86AudioNext, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # [hidden] +bind = Super+Shift+Alt, mouse:275, exec, playerctl previous # [hidden] +bind = Super+Shift+Alt, mouse:276, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # [hidden] +bindl= Super+Shift, B, exec, playerctl previous # Previous track +bindl= Super+Shift, P, exec, playerctl play-pause # Play/pause media +bindl= ,XF86AudioPlay, exec, playerctl play-pause # [hidden] + +#! +##! Apps +bind = Super, T, exec, # Launch foot (terminal) +bind = Super, Z, exec, Zed # Launch Zed (editor) +bind = Super, C, exec, code --password-store=gnome --enable-features=UseOzonePlatform --ozone-platform=wayland # Launch VSCode (editor) +bind = Super, E, exec, nautilus --new-window # Launch Nautilus (file manager) +bind = Super+Alt, E, exec, thunar # [hidden] +bind = Super, W, exec, google-chrome-stable --ozone-platform-hint=wayland --gtk-version=4 --ignore-gpu-blocklist --enable-features=TouchpadOverscrollHistoryNavigation --enable-wayland-ime # [hidden] Let's not give people (more) reason to shit on my rice +bind = Ctrl+Super, W, exec, firefox # Launch Firefox (browser) +bind = Super, X, exec, gnome-text-editor --new-window # Launch GNOME Text Editor +bind = Super+Shift, W, exec, wps # Launch WPS Office +bind = Super, I, exec, XDG_CURRENT_DESKTOP="gnome" gnome-control-center # Launch GNOME Settings +bind = Ctrl+Super, V, exec, pavucontrol # Launch pavucontrol (volume mixer) +bind = Ctrl+Super+Shift, V, exec, easyeffects # Launch EasyEffects (equalizer & other audio effects) +bind = Ctrl+Shift, Escape, exec, gnome-system-monitor # Launch GNOME System monitor +bind = Ctrl+Super, Slash, exec, pkill anyrun || anyrun # Toggle fallback launcher: anyrun + +# Cursed stuff +## Make window not amogus large +bind = Ctrl+Super, Backslash, resizeactive, exact 640 480 # [hidden]