feat: Emacs shell compatibility and SCAD mode #10

Closed
aniva wants to merge 0 commits from emacs into main
20 changed files with 383 additions and 1148 deletions

View File

@ -22,7 +22,8 @@ recommended.
* Status Bar and Tray * Status Bar and Tray
- ~eww-wayland~: Requires ~socat~ to listen for hyprland events. - ~waybar~: Status bar, use ~waybar-hyprland-git~ AUR repo to enable clicking!
- ~eww-wayland~: Another status bar, requires ~socat~ to listen for hyprland events.
* Sway * Sway
@ -56,6 +57,7 @@ This is another choice of a compositor.
Note: Setup does not work with NVIDIA GPU without some tweaks. Note: Setup does not work with NVIDIA GPU without some tweaks.
- [[https://wiki.archlinux.org/title/Hyprland][hyprland]]: window manager - [[https://wiki.archlinux.org/title/Hyprland][hyprland]]: window manager
Until [[https://github.com/elkowar/eww/issues/111][tray support]] has been added to ~eww~ in a stable manner, tray will be handled with waybar.
- ~hyprpaper~: Wallpaper engine - ~hyprpaper~: Wallpaper engine
The command to set a wallpaper: The command to set a wallpaper:
@ -77,14 +79,12 @@ convert $IN \
#+end_src #+end_src
- ~swaync~: Notification server - ~swaync~: Notification server
- ~wofi~: finding programs, drop in replacement for ~rofi~ - ~wofi~: finding programs, drop in replacement for ~rofi~
- ~grimblast~: Screenshot engine
- ~dolphin~: File explorer - ~dolphin~: File explorer
- ~swaylock-effects~: A simple lockscreen - ~swaylock-effects~: A simple lockscreen
- ~wl-clipboard~: Provides copying - ~wl-clipboard~: Provides copying
- ~blueman~: Bluetooth connector - ~blueman~: Bluetooth connector
- ~grim~: Screenshot engine
- ~flameshot~: Screenshot utility; On Arch Linux, install ~flameshot-git~.
** Configuration ** Configuration
- ~lxappearance~: Used to configure GTK3 themes - ~lxappearance~: Used to configure GTK3 themes

View File

@ -28,12 +28,6 @@ Install and set the default shell to ~fish~.
** Utilities ** Utilities
- ~kando~: Pie menu
Note the complicated key binding in the ~kando~ menu configuration. This is
used for MacOS and desktop environments where some keys cannot bind to a
command (e.g. Wacom tablets)
- ~alacritty~: terminal emulator - ~alacritty~: terminal emulator
Note that in order to set this as the default terminal, you may need to put Note that in order to set this as the default terminal, you may need to put

View File

@ -1,17 +0,0 @@
#+title: System
Helpful guides for system installation.
* Partition Schemes
Recommended partition scheme for directories:
#+begin_src
/
├ /boot # Same drive
├ /nix
├ /home # Different drive
#+end_src
** Encrypted Partitions
See [[https://wiki.archlinux.org/title/Dm-crypt/Mounting_at_login][DM-Crypt on Arch Wiki]]

View File

@ -257,13 +257,8 @@ numbers are disabled. For relative line numbers, set this to ~relative~.
(setq whitespace-line-column nil) (setq whitespace-line-column nil)
(display-line-numbers-mode) (display-line-numbers-mode)
) )
(add-hook 'text-mode-hook #'custom/common-richtext-hook) (add-hook 'text-mode-hook #'custom/common-richtext-hook)
(setq
typescript-indent-level 3
css-indent-offset 3
sh-indentation 3
nxml-indent-offset 3
)
#+end_src #+end_src
** Shells ** Shells
@ -648,6 +643,47 @@ Add the necessary hooks for LilyPond mode.
(setq rustic-indent-offset standard-indent)) (setq rustic-indent-offset standard-indent))
#+end_src #+end_src
*** SCAD
#+begin_src emacs-lisp :tangle packages.el
(package! scad-mode)
#+end_src
#+begin_src emacs-lisp
(use-package! scad-mode
:after-call scad-mode
:config
(add-hook 'scad-mode-hook #'custom/common-program-hook))
(map! :after scad-mode
:localleader
:map scad-mode-map
:desc "Open" "o" #'scad-open
:desc "Export" "e" #'scad-export
:desc "Preview" "p" #'scad-preview
)
(map! :after scad-mode
:mode scad-preview-mode
:map scad-preview-mode-map
:desc "Size+" "+" #'scad-preview-size+
:desc "Size-" "-" #'scad-preview-size-
:desc "Distance+" "[" #'scad-preview-distance+
:desc "Distance-" "]" #'scad-preview-distance-
:desc "Toggle Projection" "p" #'scad-preview-projection
:desc "Translate x-" "h" #'scad-preview-translate-x-
:desc "Translate x+" "l" #'scad-preview-translate-x+
:desc "Translate y-" "j" #'scad-preview-translate-y-
:desc "Translate y+" "k" #'scad-preview-translate-y+
:desc "Translate z-" "n" #'scad-preview-translate-z-
:desc "Translate z+" "m" #'scad-preview-translate-z+
:desc "Rotate x-" "H" #'scad-preview-rotate-x-
:desc "Rotate x+" "L" #'scad-preview-rotate-x+
:desc "Rotate y-" "J" #'scad-preview-rotate-y-
:desc "Rotate y+" "K" #'scad-preview-rotate-y+
:desc "Rotate z-" "N" #'scad-preview-rotate-z-
:desc "Rotate z+" "M" #'scad-preview-rotate-z+
)
#+end_src
** Tools ** Tools
*** Language Server Protocol (LSP) *** Language Server Protocol (LSP)
@ -656,7 +692,7 @@ File path is removed from breadcrumb since it is provided by ~doom-modeline~ and
since it clutters the header-line. since it clutters the header-line.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setq-hook! 'lsp-mode-hook (setq-hook! lsp-mode
lsp-headerline-breadcrumb-enable t lsp-headerline-breadcrumb-enable t
lsp-headerline-breadcrumb-enable-symbol-numbers nil lsp-headerline-breadcrumb-enable-symbol-numbers nil
lsp-headerline-breadcrumb-segments '(symbols) lsp-headerline-breadcrumb-segments '(symbols)
@ -786,26 +822,3 @@ FIXME: Cleanup ~ein:markdown-mode-map~.
:desc "Move cell up" "M-k" 'ein:worksheet-move-cell-up :desc "Move cell up" "M-k" 'ein:worksheet-move-cell-up
) )
#+end_src #+end_src
*** Telegram
#+begin_src emacs-lisp :tangle packages.el
(package! telega)
#+end_src
On Arch Linux, ~telegram-tdlib~ installs to
#+begin_src text :tangle no
telegram-tdlib /usr/
telegram-tdlib /usr/include/
telegram-tdlib /usr/include/td/...
telegram-tdlib /usr/lib/
telegram-tdlib /usr/lib/cmake/
telegram-tdlib /usr/lib/cmake/...
telegram-tdlib /usr/lib/libtdactor.a
telegram-tdlib /usr/lib/...
telegram-tdlib /usr/lib/pkgconfig/...
#+end_src
#+begin_src emacs-lisp
(setq telega-server-libs-prefix "/usr")
#+end_src

View File

@ -63,7 +63,7 @@
;;objed ; text object editing for the innocent ;;objed ; text object editing for the innocent
;;parinfer ; turn lisp into python, sort of ;;parinfer ; turn lisp into python, sort of
;;rotate-text ; cycle region at point between text candidates ;;rotate-text ; cycle region at point between text candidates
;;snippets ; my elves. They type so I don't have to snippets ; my elves. They type so I don't have to
;;word-wrap ; soft wrapping with language-aware indent ;;word-wrap ; soft wrapping with language-aware indent
:emacs :emacs
@ -95,8 +95,8 @@
(eval +overlay) ; run code, run (also, repls) (eval +overlay) ; run code, run (also, repls)
;;gist ; interacting with github gists ;;gist ; interacting with github gists
lookup ; navigate your code and its documentation lookup ; navigate your code and its documentation
(lsp +peek +eglot) ; M-x vscode (lsp +peek) ; M-x vscode
(magit +forge) ; a git porcelain for Emacs magit ; a git porcelain for Emacs
make ; run make tasks from Emacs make ; run make tasks from Emacs
pass ; password manager for nerds pass ; password manager for nerds
pdf ; pdf enhancements pdf ; pdf enhancements
@ -161,7 +161,7 @@
;;qt ; the 'cutest' gui framework ever ;;qt ; the 'cutest' gui framework ever
;;racket ; a DSL for DSLs ;;racket ; a DSL for DSLs
;;raku ; the artist formerly known as perl6 ;;raku ; the artist formerly known as perl6
rest ; Emacs as a REST client ;;rest ; Emacs as a REST client
;;rst ; ReST in peace ;;rst ; ReST in peace
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
(rust +lsp +tree-sitter) ; Fe2O3.unwrap().unwrap().unwrap().unwrap() (rust +lsp +tree-sitter) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()

View File

@ -12,76 +12,32 @@ $workspace_hover: #2E5DFF;
$widget_bg: rgba(40, 40, 40, 0.5); $widget_bg: rgba(40, 40, 40, 0.5);
$weather: rgba(180, 220, 235, 0.8); $weather: rgba(180, 220, 235, 0.8);
$weather_end: rgba(171, 233, 179, 0.8); $weather_end: rgba(171, 233, 179, 0.8);
$clock: rgba(171, 233, 179, 1.0);
$trough: rgba(0, 0, 0, 0.5); $media: rgba(224, 232, 224, 0.7);
$media-progress-bg: rgba(224, 232, 224, 0.1); $tray_background: rgba(204, 204, 204, 0.1);
$media-paused-progress-bg: rgba(224, 200, 200, 0.1);
$media: rgba(224, 232, 224, 0.7);
$media-paused: rgba(224, 200, 200, 0.7);
$media-stopped: rgba(200, 200, 200, 0.5);
// Dims the desktop background so status icons can be seen against darker wallpapers
$status_bg: rgba(0, 0, 0, 0.3);
$tray-bg: rgba(204, 204, 204, 0.3);
$tray: #c9cbff; $tray: #c9cbff;
$keyboard: #f2cdcd; $keyboard: #f2cdcd;
$language: #e8a2af;
$idle_inhibitor: #f28fad; $idle_inhibitor: #f28fad;
$volume: #fae3b0; $audio: #fae3b0;
$microphone: #e8a2af; $backlight: #f8bd96;
$network: #f8bd96; $bluetooth: #caa9c7;
$backlight: #bd93f9; $network: #bd93f9;
// Unused in favour of bluetooth widget
$bluetooth: #88bbeb;
$cpu: #96cdfb; $cpu: #96cdfb;
$cpu-bg: rgba(150, 205, 251, 0.3); $memory: #88bbeb;
// previously bluetooth colour $temperature: #ddb6f2;
$memory: #caa9c7; $temperature_critical: #ff6666;
$memory-bg: rgba(202, 169, 199, 0.3); $battery: #b6b2b3;
$temperature-bg: rgba(180, 180, 180, 0.5);
$temperature: #b6b2b3;
$temperature-critical: #ff6666;
$battery: #ddb6f2;
$clock: rgba(171, 233, 179, 1.0);
// Styles all scales * { all: unset; }
progressbar trough {
all: unset;
background-color: $trough;
border-radius: 5px;
min-height: 80px;
min-width: 2px;
//margin: .3rem 0 .3rem 0;
}
trough progress {
all: unset;
background-color: #00ff00; // Diagnostics colour
border-radius: 5px;
min-width: 2px;
}
scale trough {
all: unset;
background-color: $trough;
border-radius: 5px;
min-height: 80px;
min-width: 2px;
}
trough highlight {
all: unset;
background-color: #ff0000; // Diagnostics colour
border-radius: 5px;
}
trough slider {
background-color: transparent;
border-width: 0px;
border-radius: 10px;
}
.vbar { .bar {
background-color: transparent; //background-color: transparent;
font-size: 20px; margin-left: 5px;
font-size: 15px;
font-family: monospace; font-family: monospace;
} }
@ -90,16 +46,13 @@ trough slider {
} }
.launcher { .launcher {
all: unset;
font-size: 40px; font-size: 40px;
margin: -2px -5px 5px 0px; margin: -7px -5px 15px -5px;
} }
box .workspaces { box .workspaces {
all: unset;
border-radius: 10px; border-radius: 10px;
button { button {
all: unset;
font-size: 30px; font-size: 30px;
padding-left: 2px; padding-left: 2px;
margin: -5px -5px -5px -5px; margin: -5px -5px -5px -5px;
@ -122,11 +75,6 @@ box .workspaces {
} }
} }
box .status {
background-color: $status_bg;
border-radius: 5px;
}
box .weather { box .weather {
color: $weather; color: $weather;
margin-left: 2px; margin-left: 2px;
@ -157,112 +105,63 @@ box .weather {
color: mix($weather_end, $weather, 100%); color: mix($weather_end, $weather, 100%);
} }
} }
.volume { box .clock {
background-color: transparent; background-color: $widget_bg;
color: $volume; border-radius: 5;
border-left: 2px solid $volume; color: $clock;
margin-bottom: 1px; margin-bottom: 30px;
margin-top: 1px; padding: 2pt 2pt 2pt 2pt;
highlight {
background-color: $volume;
}
}
.microphone {
background-color: transparent;
color: $microphone;
border-left: 2px solid $microphone;
margin-bottom: 1px;
margin-top: 1px;
highlight {
background-color: $microphone;
}
} }
.media { .media {
font-family: "Noto Serif"; font-family: "Noto Serif";
min-height: 15px; padding-left: 5px;
min-width: 15px; padding-right: 5px;
font-size: 15px;
color: $media; color: $media;
border: none; border: none;
.media-text-playing {
padding-left: 10px;
}
.media-text-paused {
padding-left: 10px;
color: $media-paused;
}
.media-text-stopped {
padding-left: 10px;
color: $media-stopped;
}
.media-playing {
background-color: $media-progress-bg;
}
.media-paused {
background-color: $media-paused-progress-bg;
color: $media-paused;
}
.media-stopped {
background-color: $media-paused-progress-bg;
color: $media-stopped;
}
} }
box .temperature { .status {
color: $temperature; font-family: monospace;
border-left: 2px solid $temperature-bg;
margin-bottom: 1px;
margin-top: 1px;
}
.temperature-icon {
padding-left: 5px;
font-size: 20px;
color: mix($temperature, transparent, 70%);
}
.temperature-progress-cpu trough progress {
background-color: mix($cpu, $temperature, 50%);
}
.temperature-progress-gpu trough progress {
background-color: $temperature;
}
.temperature-progress-critical trough progress {
background-color: $temperature-critical;
} }
box .cpu { // Styles on classes (see eww.yuck for more information)
.progress {
background-color: $cpu-bg; .status slider {
} all: unset;
color: $cpu; color: #ffd5cd;
border-left: 2px solid $cpu;
margin-bottom: 1px;
margin-top: 1px;
} }
box .memory {
.progress { .metric scale trough highlight {
background-color: $memory-bg; all: unset;
} background-color: #D35D6E;
color: $memory; color: #000000;
border-left: 2px solid $memory; border-radius: 10px;
margin-bottom: 1px;
margin-top: 1px;
} }
box .clock { .metric scale trough {
background-color: transparent; all: unset;
color: $clock; background-color: #4e4e4e;
margin-top: 1px; border-radius: 50px;
font-family: Ariel; min-height: 3px;
border-left: 2px solid $clock; min-width: 50px;
.icon { margin-left: 10px;
color: mix($clock, transparent, 50%); margin-right: 20px;
}
} }
.systray { .metric scale trough highlight {
//background-color: $tray_bg; all: unset;
color: $tray; background-color: #D35D6E;
border-left: 2px dotted $tray; color: #000000;
border-bottom: 2px dotted $tray-bg; border-radius: 10px;
}
.metric scale trough {
all: unset;
background-color: #4e4e4e;
border-radius: 50px;
min-height: 3px;
min-width: 50px;
margin-left: 10px;
margin-right: 20px;
}
.label-ram {
font-size: large;
} }

View File

@ -1,257 +1,95 @@
(defvar amixer "amixer -D pulse") (defvar eww "eww --config $HOME/.config/eww/bar")
(defvar temperature-monitor "psensor")
(defwindow vbar (defwindow bar
:exclusive true :exclusive true
:monitor 0 :monitor 0
:windowtype "dock" :windowtype "dock"
:geometry (geometry :geometry (geometry
:x "0%" :x "0%"
:y "0%" :y "0%"
:width "25px" :width "20px"
:height "99%" :height "100%"
:anchor "center left" :anchor "center left"
) )
:reserve (struts :side "left" :distance "20px") :reserve (struts :side "left" :distance "20px")
(centerbox (widget_bar))
:orientation "v" (defwidget widget_bar []
(box (centerbox :orientation "v"
:orientation "v" :space-evenly false :valign "start" (box :orientation "v" :space-evenly false :valign "start"
(label (box :class "launcher" :valign "start" "☯")
:class "launcher" (widget_workspaces)
:valign "start"
:width "20px" :height "20px"
:unindent true
:tooltip active-window-title
:text "☯")
(widget-workspaces)
)
(widget-media)
(box
:class "status"
:orientation "v" :space-evenly false :valign "end"
(widget-tray)
(widget-volume)
(widget-microphone)
(widget-temperature)
(widget-cpu)
(widget-memory)
(widget-clock)
) )
(widget_weather :orientation "v")
(widget_clock)
;(media)
;(widget_status)
)) ))
(defwidget widget-workspaces [] (defwidget widget_workspaces []
(box (box
:class "workspaces" :class "workspaces"
:orientation "v" :orientation "v"
:space-evenly true :space-evenly true
:spacing 10 :valign "start" :spacing 10
:valign "start"
:halign "center" :halign "center"
(for workspace in workspaces (for workspace in workspaces
(button (button
:class "${workspace.class}" :class "${workspace.class}"
:onclick "scripts/compositor-control set-workspace ${workspace.id}" :onclick "scripts/workspace.sh ${workspace.id}"
"${workspace.text}")) "${workspace.text}"))
)) ))
(deflisten workspaces :initial "[]" (deflisten workspaces :initial "[]"
"scripts/compositor-control workspaces") "scripts/get-workspaces")
(deflisten active-window-title :initial ""
"scripts/compositor-control active-title")
(defwidget widget-media [] ; Weather
(defwidget widget_weather [orientation]
(box (box
:class "media" :class "weather"
:orientation "v" :orientation orientation
:space-evenly false :space-evenly false
:valign "end" :valign "start"
:tooltip "${media-status == 'Paused' ? '' : media-status == 'Playing' ? '' : ''} ${media-position-text}" :halign "center"
(eventbox :spacing 10
:onclick "playerctl play-pause" (button :onclick "scripts/popup weather" "W")
(circular-progress
:class { media-status == "Paused" ? "media-paused" : media-status == "Stopped" ? "media-stopped" : "media-playing" }
:width 20
:height 20
:thickness 5
:value {100.0 * media-position / (media-length / 1000000.0)}
:visible {media-current != "" && media-status != "Stopped"}
))
(label
:class { media-status == "Paused" ? "media-text-paused" : media-status == "Stopped" ? "media-text-stopped" : "media-text-playing" }
:angle 270
:xalign 0.5
:yalign 0.5
:justify "center"
:limit-width 120
:text "『${media-current}』"
)))
(deflisten media-current :initial ""
"playerctl --follow metadata --format '{{ artist }} / {{album}} / {{ title }}' || true")
(deflisten media-position-text :initial ""
"playerctl --follow metadata --format '{{duration(position)}} / {{duration(mpris:length)}}' || true")
(defpoll media-position
:interval "1s" :run-while {media-current != ""}
"playerctl position")
(deflisten media-length :initial 1
"playerctl --follow metadata mpris:length")
(deflisten media-status :initial "Stopped"
"playerctl --follow status")
(defwidget widget-volume []
(eventbox
:onhover "${EWW_CMD} update show-volume=true"
:onhoverlost "${EWW_CMD} update show-volume=false"
:onclick "${amixer} sset Master toggle"
(box
:class "volume"
:orientation "v"
:space-evenly "false"
:spacing "2"
:tooltip "Volume: ${current-volume}% [${current-volume-state}]"
(revealer :transition "slideup" :reveal show-volume
(scale
:class "scale"
:value current-volume
:orientation "v"
:flipped true
:marks true
:max 101
:min 0
:onchange "${amixer} sset Master {}%" ))
(label
:class "icon"
:width 25 :height 20
:xalign 0.5 :yalign 0.5
:noindent true
:text { current-volume-state == "off" ? "" : (current-volume > 50 ? "" : "") }))))
(defwidget widget-microphone []
(eventbox
:onhover "${EWW_CMD} update show-microphone=true"
:onhoverlost "${EWW_CMD} update show-microphone=false"
:onclick "${amixer} sset Capture toggle"
(box
:class "microphone"
:orientation "v"
:space-evenly "false"
:spacing "2"
:tooltip "Capture : ${current-microphone}% [${current-microphone-state}]"
(revealer :transition "slideup" :reveal show-microphone
(scale
:class "scale"
:value current-microphone
:orientation "v"
:flipped true
:marks true
:max 101
:min 0
:onchange "${amixer} sset Capture {}%" ))
(label
:class "icon"
:width 25 :height 20
:xalign 0.5 :yalign 0.5
:noindent true
:text { current-microphone-state == "off" ? "" : "" }))))
(defpoll current-volume :interval "1s" "amixer sget Master | grep 'Left:' | awk -F'[][]' '{ print $2 }' | tr -d '%'")
(defpoll current-volume-state :interval "1s" "amixer sget Master | grep 'Left:' | awk -F'[][]' '{ print $4 }'")
(defpoll current-microphone :interval "1s" "amixer sget Capture | grep 'Left:' | awk -F'[][]' '{ print $2 }' | tr -d '%'")
(defpoll current-microphone-state :interval "1s" "amixer sget Capture | grep 'Left:' | awk -F'[][]' '{ print $4 }'")
(defvar show-volume false)
(defvar show-microphone false)
; FIXME: Maybe use a env var here instead
(defvar cpu-temp-key "ASUS_WMI_SENSORS_CPU_TEMPERATURE")
(defvar gpu-temp-key "AMDGPU_MEM")
(defvar temperature-threshold 80)
(defwidget widget-temperature []
(eventbox
:onclick temperature-monitor
(overlay
(box
:class "temperature"
:orientation "h"
:tooltip "CPU ${EWW_TEMPS[cpu-temp-key]}°C; GPU ${EWW_TEMPS[gpu-temp-key]}°C"
:space-evenly true
:width 25
:halign "" :valign "center"
(progress
:class { EWW_TEMPS[cpu-temp-key] > temperature-threshold ? "temperature-progress-critical" : "temperature-progress-cpu" }
:halign "center" :valign "center"
:flipped "true"
:width 3
:orientation "v"
:value {EWW_TEMPS[cpu-temp-key]}
)
(progress
:class { EWW_TEMPS[gpu-temp-key] > temperature-threshold ? "temperature-progress-critical" : "temperature-progress-gpu" }
:halign "center" :valign "center"
:flipped "true"
:width 3
:orientation "v"
:value {EWW_TEMPS[gpu-temp-key]}
)
)
(label
:valign "end"
:class "temperature-icon"
:text "")
)))
(defwidget widget-cpu []
(box
:class "cpu"
:orientation "v"
(circular-progress
:class "progress"
:width 25
:height 25
:thickness 4
:tooltip " ${round(EWW_CPU.avg, 2)}%"
:value {EWW_CPU.avg}
)))
(defwidget widget-memory []
(box
:class "memory"
:orientation "v"
(circular-progress
:class "progress"
:width 25
:height 25
:thickness 4
:tooltip " ${round(100 * EWW_RAM.used_mem / EWW_RAM.total_mem, 2)}%"
:value {EWW_RAM.used_mem_perc}
)))
(defwidget widget-tray []
(systray
:class "systray"
:orientation "v"
:space-evenly true
:icon-size 25
:prepend-new true
)) ))
(defwidget widget-clock [] (defpoll weather_text :initial "" :interval "180s"
"curl --max-time 2 wttr.in")
(defwindow weather
:geometry (geometry :x "70px"
:y "50%"
:width "270px"
:height "60px")
(box weather_text))
(defwindow calendar
:geometry (geometry :x "70px"
:y "65%"
:width "270px"
:height "60px")
(cal))
(defwidget widget_clock []
(box (box
:class "clock" :class "clock"
:orientation "v" :orientation "v"
:valign "end" :valign "end"
:spacing 1 :spacing 1
:width 20 (box :class "icon" "")
:tooltip {formattime(EWW_TIME, "%F (%a) %T [%Z]")} "${clock.H}" "${clock.M}"
;(box :class "icon" "") (box :class "icon" "")
(label :text "${clock.m}") "${clock.m}" "${clock.d}"
(label :text "${clock.d}")
(label :class "icon" :text "")
(label :text "${clock.H}")
(label :text "${clock.M}")
)) ))
(defpoll clock :initial "{}" :interval "10s" (defpoll clock :initial "{}" :interval "10s"
"date '+{\"H\":\"%H\", \"M\":\"%M\", \"d\":\"%d\", \"m\":\"%m\", \"b\":\"%b\", \"Y\":\"%Y\"}'") "date '+{\"H\":\"%H\", \"M\":\"%M\", \"d\":\"%d\", \"m\":\"%m\", \"b\":\"%b\", \"Y\":\"%Y\"}'")
; Calendar ; Calendar
(defwindow calendar (defwindow calendar
@ -259,7 +97,7 @@
:y "65%" :y "65%"
:width "270px" :width "270px"
:height "60px") :height "60px")
(cal)) (cal))
(defwidget cal [] (defwidget cal []
@ -277,25 +115,56 @@
(defpoll calendar_year :interval "10h" (defpoll calendar_year :interval "10h"
"date '+%Y'") "date '+%Y'")
; Weather ; Unused widgets
(defwidget widget-weather [orientation] (defwidget widget_status []
(box (box
:class "weather" :class "status"
:orientation orientation :orientation "v"
:space-evenly false :space-evenly false
:valign "start" :valign "end"
:halign "center" (metric :label ""
:spacing 10 :value volume
(button :onclick "scripts/popup weather" "W") :onchange "amixer -D pulse sset Master {}%")
(metric :label ""
:value {EWW_RAM.used_mem_perc}
:onchange "")
(widget_clock)))
(defwidget widget_media []
(box :class "media"
:orientation "v"
:space-evenly false
:valign "center"
{music_listener != "" ? "『${music_listener}』" : ""}
(box :class "music_status"
:orientation "h"
:space-evenly false
:halign "center"
{music_listener != "" ? "${music_status_listener}" : ""})
)) ))
(defpoll weather-text :initial "" :interval "180s" (deflisten music_listener :initial ""
"curl --max-time 2 wttr.in") "playerctl --follow metadata --format '{{ artist }} / {{album}} / {{ title }}' || true")
(deflisten music_status_listener :initial ""
"playerctl --follow metadata --format '{{duration(position)}}/{{duration(mpris:length)}}' || true")
(defwindow weather
:geometry (geometry :x "70px" (defwidget metric [label value onchange]
:y "50%" (box
:width "270px" :orientation "v"
:height "60px") :class "metric"
(box weather-text)) :space-evenly false
(box :class "label" label)
(circular-progress :value value)
;(scale
; :min 0 :max 101
; :active {onchange != ""}
; :orientation "v"
; :value value
; :onchange onchange)
))
(defpoll volume :initial 0 :interval "1s"
"scripts/get-volume.sh")

View File

@ -1,193 +0,0 @@
#!/usr/bin/env python
"""
Utility to generate the workspace buttons for eww bar widget.
Currently it fetches information from monitor 0. If all monitors have
synchronised workspaces this should not be a problem.
"""
import os, sys, socket, json, subprocess
from typing import Optional, Self, override
WORKSPACE_ICONS = [
(1, "☱"),
(2, "☲"),
(3, "☳"),
(4, "☴"),
(5, "☵"),
(6, "☶"),
(7, "☷"),
(8, "☰"),
]
EXTRA_WORKSPACE_ICONS = [
(0, "⚌"),
(1, "⚍"),
(2, "⚎"),
(3, "⚏"),
]
Workspaces = dict[int, bool]
def get_widgets(workspaces: Workspaces) -> str:
"""
Create widget sexp from workspace information
"""
def get_class(k):
key = workspaces.get(k, None)
if key is None:
return "inactive"
elif key:
return "focused"
else:
return "active"
buttons = [
f'"id": "{k}", "text": "{icon}", "class": "{get_class(k)}"'
for k, icon in WORKSPACE_ICONS
]
buttons = ", ".join(["{" + b + "}" for b in buttons])
return "[" + buttons + "]"
class CompositorHandler:
@staticmethod
def create() -> Optional[Self]:
"""
Main entry point, detects the type of compositor used
"""
if signature := os.environ.get("HYPRLAND_INSTANCE_SIGNATURE", None):
# See https://wiki.hyprland.org/IPC/
xdg_runtime_dir = os.environ["XDG_RUNTIME_DIR"]
socket_addr = f"/{xdg_runtime_dir}/hypr/{signature}/.socket2.sock"
return HyprlandHandler(socket_addr)
if signature := os.environ.get("SWAYSOCK", None):
return SwayHandler()
return None
def listen_workspaces(self):
pass
def listen_active_window_title(self):
pass
def set_workspace(self, i):
pass
class HyprlandHandler(CompositorHandler):
def __init__(self, socket_addr):
self.socket_addr = socket_addr
def listen(self, callback):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
sock.connect(self.socket_addr)
except Exception as e:
print(f"Could not connect to {self.socket_addr}", file=sys.stderr)
raise e
callback(data=None)
while sock:
data = sock.recv(1024)
callback(data)
@staticmethod
def get_workspace_info() -> Workspaces:
workspaces = json.loads(os.popen("hyprctl workspaces -j").read())
monitors = json.loads(os.popen("hyprctl monitors -j").read())
if not monitors:
print("No monitor found!", file=sys.stderr)
return []
monitor, active = [
(m["name"], m["activeWorkspace"]["id"]) for m in monitors if m["id"] == 0
][0]
workspaces = {
w["id"]: w["id"] == active
for w in workspaces if w["monitor"] == monitor
}
return workspaces
@override
def listen_workspaces(self):
def callback(data):
if data is None or b"workspace" in data:
workspace_info = HyprlandHandler.get_workspace_info()
print(get_widgets(workspace_info), flush=True)
self.listen(callback)
@override
def listen_active_window_title(self):
def callback(data):
if data is None:
active_window = json.loads(os.popen("hyprctl activewindow -j").read())
print(active_window["title"], flush=True)
return
prefix = b"activewindow>>"
payload = next((l[len(prefix):]
for l in reversed(data.split(b'\n'))
if l.startswith(prefix)), None)
if payload is None:
return
if b',' in payload:
_, title = payload.decode('utf-8').split(',', 1)
print(title, flush=True)
else:
print("", flush=True)
self.listen(callback)
@override
def set_workspace(self, i):
result = os.popen(f"hyprctl dispatch workspace {i}").read()
if result != "ok\n":
raise RuntimeError(f"Failed to set workspace: {result}")
# FIXME: Set the wallpaper too.
# ~/.config/hypr/wallpaper.sh $1
class SwayHandler(CompositorHandler):
@staticmethod
def get_workspace_info() -> Workspaces:
workspaces = json.loads(os.popen("swaymsg --raw -t get_workspaces").read())
# REVIEW: This has not been tested on a multi-monitor setup.
workspaces = {
int(w["num"]): w["focused"]
for w in workspaces
}
return workspaces
def listen_workspaces(self):
with subprocess.Popen(["swaymsg", "-t", "subscribe", "-m", '["workspace"]'], stdout=subprocess.PIPE) as proc:
workspace_info = SwayHandler.get_workspace_info()
print(get_widgets(workspace_info), flush=True)
while line := proc.stdout.readline():
# FIXME: Use the swaymsg subscribe output
# Not needed
#info = json.loads(line)
workspace_info = SwayHandler.get_workspace_info()
print(get_widgets(workspace_info), flush=True)
if __name__ == "__main__":
if len(sys.argv) == 1:
print("Usage: wm-control workspaces|title")
handler = CompositorHandler.create()
if handler is None:
print("No compositor found.", file=sys.stderr)
key = sys.argv[1]
if key == "workspaces":
handler.listen_workspaces()
elif key == "active-title":
handler.listen_active_window_title()
elif key == "set-workspace":
if len(sys.argv) != 3:
print(f"Set workspace must be accompanied by an argument", file=sys.stderr)
arg = sys.argv[2]
handler.set_workspace(arg)
else:
print(f"Unknown key: {key}", file=sys.stderr)

3
eww/bar/scripts/get-volume.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
amixer -D pulse sget Master | grep 'Left:' | awk -F'[][]' '{ print $2 }' | tr -d '%' | head -1

126
eww/bar/scripts/get-workspaces Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/env python
"""
Utility to generate the workspace buttons for eww bar widget.
Currently it fetches information from monitor 0. If all monitors have
synchronised workspaces this should not be a problem.
"""
import os, sys, socket, json, subprocess
from typing import Optional
WORKSPACE_ICONS = [
(1, "☱"),
(2, "☲"),
(3, "☳"),
(4, "☴"),
(5, "☵"),
(6, "☶"),
(7, "☷"),
(8, "☰"),
]
EXTRA_WORKSPACE_ICONS = [
(0, "⚌"),
(1, "⚍"),
(2, "⚎"),
(3, "⚏"),
]
Workspaces = dict[int, bool]
def get_widgets(workspaces: Workspaces) -> str:
"""
Create widget sexp from workspace information
"""
def get_class(k):
key = workspaces.get(k, None)
if key is None:
return "inactive"
elif key:
return "focused"
else:
return "active"
buttons = [
f'"id": "{k}", "text": "{icon}", "class": "{get_class(k)}"'
for k, icon in WORKSPACE_ICONS
]
buttons = ", ".join(["{" + b + "}" for b in buttons])
return "[" + buttons + "]"
# Compositor specific information
def hypr_get_workspace_info() -> Workspaces:
workspaces = json.loads(os.popen("hyprctl workspaces -j").read())
monitors = json.loads(os.popen("hyprctl monitors -j").read())
if not monitors:
print("No monitor found!", file=sys.stderr)
return []
monitor, active = [
(m["name"], m["activeWorkspace"]["id"]) for m in monitors if m["id"] == 0
][0]
workspaces = {
w["id"]: w["id"] == active
for w in workspaces if w["monitor"] == monitor
}
return workspaces
def hypr_listen(socket_addr: str):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
sock.connect(socket_addr)
except:
print(f"Could not connect to {socket_addr}", file=sys.stderr)
raise
# The flush here is very important since python by default buffers!
workspace_info = hypr_get_workspace_info()
print(get_widgets(workspace_info), flush=True)
while sock:
data = sock.recv(1024)
if b"workspace" in data:
workspace_info = hypr_get_workspace_info()
print(get_widgets(workspace_info), flush=True)
def sway_get_workspace_info() -> Workspaces:
workspaces = json.loads(os.popen("swaymsg --raw -t get_workspaces").read())
# REVIEW: This has not been tested on a multi-monitor setup.
workspaces = {
int(w["num"]): w["focused"]
for w in workspaces
}
return workspaces
def sway_listen():
proc = subprocess.Popen(
["swaymsg", "-t", "subscribe", "-m", '["workspace"]'], stdout=subprocess.PIPE
)
workspace_info = sway_get_workspace_info()
print(get_widgets(workspace_info), flush=True)
while line := proc.stdout.readline():
# Not needed
info = json.loads(line)
workspace_info = sway_get_workspace_info()
print(get_widgets(workspace_info), flush=True)
def detect():
"""
Main entry point, detects the type of compositor used
"""
if signature := os.environ.get("HYPRLAND_INSTANCE_SIGNATURE", None):
socket_addr = f"/tmp/hypr/{signature}/.socket2.sock"
return hypr_listen(socket_addr)
if signature := os.environ.get("SWAYSOCK", None):
return sway_listen()
print("No compositor found.", file=sys.stderr)
return None
if __name__ == "__main__":
detect()

4
eww/bar/scripts/workspace.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
hyprctl dispatch workspace $1
~/.config/hypr/wallpaper.sh $1

View File

@ -40,54 +40,39 @@ end
function fish_prompt function fish_prompt
# set_color white # set_color white
# printf '[' # echo -n '['
set -l FishStatusCodeCache $status set -l FishStatusCodeCache $status
set_color -o 00FF00 -b 333333 set_color -o 00FF00
printf (whoami) echo -n (whoami)
set_color normal set_color normal
set_color -b 333333 echo -n '@'
printf '@'
set_color AFD75F set_color AFD75F
printf (prompt_hostname) echo -n (hostname)
set_color white set_color white
printf ':' echo -n ':'
set_color 8787FF set_color 8787FF
printf (prompt_abbr $PWD) echo -n (prompt_abbr $PWD)
set -l vcs_prompt (fish_vcs_prompt) set_color 5F87D7
if test -n "$vcs_prompt" echo -n (__fish_vcs_prompt)
printf " "
set_color 5F87D7
printf '\uf126'
printf (fish_vcs_prompt)
end
if test $FishStatusCodeCache -eq 0 if test $FishStatusCodeCache -eq 0
#set_color 18C412 #set_color 18C412
else else
set_color E84505 set_color E84505
printf " [$FishStatusCodeCache]" echo -n " [$FishStatusCodeCache]"
end end
# set_color white # set_color white
# printf "]" # echo -n "]"
set_color 999999 set_color -o white
printf " " echo -n "> "
printf (date '+%Y/%m/%d %H:%M:%S')
printf "\n"
#set_color -o white
#printf "> "
set_color normal
set_color -o green
printf "⮀ "
set_color normal set_color normal
end end

View File

@ -0,0 +1,8 @@
#!/bin/fish
function fish_right_prompt
set_color grey
printf (date '+%H:%M:%S')
set_color normal
end

View File

@ -10,7 +10,8 @@ monitor=,preferred,auto,auto
# See https://wiki.hyprland.org/Configuring/Keywords/ for more # See https://wiki.hyprland.org/Configuring/Keywords/ for more
exec-once = hyprpaper & swaync & fcitx5 & flameshot & eww --config ~/.config/eww/bar open vbar & kando # waybar is executed after eww to have the intersection effect at top left
exec-once = hyprpaper & swaync & fcitx5 & eww --config ~/.config/eww/bar open bar & waybar
# Source a file (multi-file configs) # Source a file (multi-file configs)
# source = ~/.config/hypr/myColors.conf # source = ~/.config/hypr/myColors.conf
@ -51,6 +52,10 @@ decoration {
# See https://wiki.hyprland.org/Configuring/Variables/ for more # See https://wiki.hyprland.org/Configuring/Variables/ for more
rounding = 10 rounding = 10
blur = yes
blur_size = 3
blur_passes = 1
blur_new_optimizations = on
drop_shadow = yes drop_shadow = yes
shadow_range = 4 shadow_range = 4
@ -84,7 +89,7 @@ dwindle {
master { master {
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
#new_is_master = true new_is_master = true
} }
gestures { gestures {
@ -130,8 +135,8 @@ bind = $mainMod, space, exec, wofi --show drun -I -G
#bind = $mainMod, X, exec, hyprctl switchxkblayout wooting-wootingtwo next #bind = $mainMod, X, exec, hyprctl switchxkblayout wooting-wootingtwo next
# code:107 = PrintSc # code:107 = PrintSc
bind = $mainMod, code:107, exec, flameshot gui bind = $mainMod, code:107, exec, grimblast copy screen
#bind = $mainMod SHIFT, code:107, exec, grimblast copy area bind = $mainMod SHIFT, code:107, exec, grimblast copy area
# Move focus with mainMod + arrow keys # Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l bind = $mainMod, left, movefocus, l
@ -142,9 +147,6 @@ bind = $mainMod SHIFT, left, movewindow, l
bind = $mainMod SHIFT, right, movewindow, r bind = $mainMod SHIFT, right, movewindow, r
bind = $mainMod SHIFT, up, movewindow, u bind = $mainMod SHIFT, up, movewindow, u
bind = $mainMod SHIFT, down, movewindow, d bind = $mainMod SHIFT, down, movewindow, d
bind = , SUPER_R, global, kando:main
# F13
bind = , code:191, global, kando:edit
# Workspaces # Workspaces
$w1 = ~/.config/hypr/wallpaper.sh 1 $w1 = ~/.config/hypr/wallpaper.sh 1
@ -197,12 +199,3 @@ bind = $mainMod, mouse_up, workspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging # Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow bindm = $mainMod, mouse:273, resizewindow
bind = SUPER,Tab,cyclenext, # change focus to another window
bind = SUPER,Tab,bringactivetotop, # bring it to the top
# Functional keys
bindl=, XF86AudioMute, exec, amixer set Master toggle
bindl=, XF86AudioPlay, exec, playerctl play-pause
bindl=, XF86AudioNext, exec, playerctl next
bindl=, XF86AudioPrev, exec, playerctl previous

2
kando/.gitignore vendored
View File

@ -1,2 +0,0 @@
/Singleton*
/session

View File

@ -1,15 +0,0 @@
{
"menuTheme": "neon-lights",
"darkMenuTheme": "default",
"menuThemeColors": {
"neon-lights": {
"glow-color": "rgba(168, 255, 196, 1)",
"connector-color": "rgba(173, 222, 255, 0.75)"
}
},
"darkMenuThemeColors": {},
"enableDarkModeForMenuThemes": false,
"sidebarVisible": false,
"enableVersionCheck": true,
"zoomFactor": 1
}

View File

@ -1,429 +0,0 @@
{
"menus": [
{
"shortcut": "Control+Alt+Shift+U",
"shortcutID": "main",
"centered": false,
"root": {
"type": "submenu",
"name": "Main",
"icon": "award_star",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "submenu",
"name": "Apps",
"icon": "apps",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "command",
"data": {
"command": "x-www-browser"
},
"name": "Web Browser",
"icon": "globe",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-email"
},
"name": "E-Mail",
"icon": "mail",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "gimp"
},
"name": "GIMP",
"icon": "gimp",
"iconTheme": "simple-icons"
},
{
"type": "command",
"data": {
"command": "xdg-open ~"
},
"name": "File Browser",
"icon": "folder_shared",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "x-terminal-emulator"
},
"name": "Terminal",
"icon": "terminal",
"iconTheme": "material-symbols-rounded"
}
]
},
{
"type": "submenu",
"name": "Web Links",
"icon": "public",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "uri",
"data": {
"uri": "https://www.google.com"
},
"name": "Google",
"icon": "google",
"iconTheme": "simple-icons"
},
{
"type": "uri",
"data": {
"uri": "https://github.com/kando-menu/kando"
},
"name": "Kando on GitHub",
"icon": "github",
"iconTheme": "simple-icons"
},
{
"type": "uri",
"data": {
"uri": "https://ko-fi.com/schneegans"
},
"name": "Kando on Ko-fi",
"icon": "kofi",
"iconTheme": "simple-icons"
},
{
"type": "uri",
"data": {
"uri": "https://www.youtube.com/@simonschneegans"
},
"name": "Kando on YouTube",
"icon": "youtube",
"iconTheme": "simple-icons"
},
{
"type": "uri",
"data": {
"uri": "https://discord.gg/hZwbVSDkhy"
},
"name": "Kando on Discord",
"icon": "discord",
"iconTheme": "simple-icons"
}
]
},
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+AltLeft+ArrowRight",
"delayed": false
},
"name": "Next Workspace",
"icon": "arrow_forward",
"iconTheme": "material-symbols-rounded"
},
{
"type": "submenu",
"name": "Clipboard",
"icon": "assignment",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+KeyV",
"delayed": true
},
"name": "Paste",
"icon": "content_paste_go",
"iconTheme": "material-symbols-rounded",
"angle": 90
},
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+KeyC",
"delayed": true
},
"name": "Copy",
"icon": "content_copy",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+KeyX",
"delayed": true
},
"name": "Cut",
"icon": "cut",
"iconTheme": "material-symbols-rounded"
}
]
},
{
"type": "submenu",
"name": "Audio",
"icon": "play_circle",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "hotkey",
"data": {
"hotkey": "MediaTrackNext",
"delayed": false
},
"name": "Next Track",
"icon": "skip_next",
"iconTheme": "material-symbols-rounded",
"angle": 90
},
{
"type": "hotkey",
"data": {
"hotkey": "MediaPlayPause",
"delayed": false
},
"name": "Play / Pause",
"icon": "play_pause",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "AudioVolumeMute",
"delayed": false
},
"name": "Mute",
"icon": "music_off",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "MediaTrackPrevious",
"delayed": false
},
"name": "Previous Track",
"icon": "skip_previous",
"iconTheme": "material-symbols-rounded",
"angle": 270
}
]
},
{
"type": "submenu",
"name": "Windows",
"icon": "select_window",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "hotkey",
"data": {
"hotkey": "MetaLeft+ArrowUp",
"delayed": true
},
"name": "Toggle Maximize",
"icon": "open_in_full",
"iconTheme": "material-symbols-rounded",
"angle": 0
},
{
"type": "hotkey",
"data": {
"hotkey": "MetaLeft+ArrowRight",
"delayed": true
},
"name": "Tile Right",
"icon": "text_select_jump_to_end",
"iconTheme": "material-symbols-rounded",
"angle": 90
},
{
"type": "hotkey",
"data": {
"hotkey": "AltLeft+F4",
"delayed": true
},
"name": "Close Window",
"icon": "cancel_presentation",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "MetaLeft+ArrowLeft",
"delayed": true
},
"name": "Tile Left",
"icon": "text_select_jump_to_beginning",
"iconTheme": "material-symbols-rounded",
"angle": 270
}
]
},
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+AltLeft+ArrowLeft",
"delayed": false
},
"name": "Previous Workspace",
"icon": "arrow_back",
"iconTheme": "material-symbols-rounded"
},
{
"type": "submenu",
"name": "Bookmarks",
"icon": "folder_special",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "command",
"data": {
"command": "xdg-open \"$(xdg-user-dir DOWNLOAD)\""
},
"name": "Downloads",
"icon": "download",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-open \"$(xdg-user-dir VIDEOS)\""
},
"name": "Videos",
"icon": "video_camera_front",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-open \"$(xdg-user-dir PICTURES)\""
},
"name": "Pictures",
"icon": "imagesmode",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-open \"$(xdg-user-dir DOCUMENTS)\""
},
"name": "Documents",
"icon": "text_ad",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-open \"$(xdg-user-dir DESKTOP)\""
},
"name": "Desktop",
"icon": "desktop_windows",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-open ~"
},
"name": "Home",
"icon": "home",
"iconTheme": "material-symbols-rounded"
},
{
"type": "command",
"data": {
"command": "xdg-open \"$(xdg-user-dir MUSIC)\""
},
"name": "Music",
"icon": "music_note",
"iconTheme": "material-symbols-rounded"
}
]
}
]
}
},
{
"root": {
"type": "submenu",
"name": "Edit",
"icon": "trip_origin",
"iconTheme": "material-symbols-rounded",
"children": [
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+KeyZ",
"delayed": true
},
"name": "Undo",
"icon": "undo",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+ShiftLeft+KeyZ",
"delayed": true
},
"name": "Redo",
"icon": "redo",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "ControlLeft+KeyR",
"delayed": true
},
"name": "Remesh",
"icon": "background_grid_small",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "F3",
"delayed": true
},
"name": "Search",
"icon": "search",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "ShiftLeft+Space",
"delayed": true
},
"name": "Brush",
"icon": "brush",
"iconTheme": "material-symbols-rounded"
},
{
"type": "hotkey",
"data": {
"hotkey": "",
"delayed": true
},
"name": "Save",
"icon": "save",
"iconTheme": "material-symbols-rounded"
}
]
},
"shortcut": "Control+Alt+Shift+Y",
"shortcutID": "edit",
"centered": false,
"anchored": false
}
],
"templates": []
}

View File

@ -3,7 +3,7 @@ set $term alacritty
# Launcher # Launcher
set $menu wofi --show drun -I -G set $menu wofi --show drun -I -G
set $lock swaylock set $lock swaylock
set $screenshot_full gscreenshot -s -c set $screenshot_full gscreenshot -s
set $screenshot_area /usr/share/swayfx/scripts/grimshot copy area set $screenshot_area /usr/share/swayfx/scripts/grimshot copy area
xwayland enable xwayland enable

View File

@ -61,6 +61,3 @@ bindsym $mod+Shift+5 move container to workspace number 5; workspace number 5
bindsym $mod+Shift+6 move container to workspace number 6; workspace number 6 bindsym $mod+Shift+6 move container to workspace number 6; workspace number 6
bindsym $mod+Shift+7 move container to workspace number 7; workspace number 7 bindsym $mod+Shift+7 move container to workspace number 7; workspace number 7
bindsym $mod+Shift+8 move container to workspace number 8; workspace number 8 bindsym $mod+Shift+8 move container to workspace number 8; workspace number 8
bindsym $mod+Shift+f opacity 1.0
bindsym $mod+Shift+g opacity 0.9

View File

@ -1,9 +1,9 @@
exec /usr/share/swayfx/scripts/inactive-windows-transparency --opacity 0.8 exec /usr/share/swayfx/scripts/inactive-windows-transparency --opacity 0.8
exec_always eww --config ~/.config/eww/bar open vbar exec_always eww --config ~/.config/eww/bar open bar
#bar { bar {
# position top position top
# swaybar_command waybar swaybar_command waybar
#} }
exec_always multibg-sway ~/.config/sway/wallpapers exec_always multibg-sway ~/.config/sway/wallpapers
exec swaync exec swaync
exec fcitx5 exec fcitx5