feat: Add a ton of updates

This commit is contained in:
2025-09-25 19:53:01 +10:00
parent f1d33ebd85
commit 3db24e33d4
30 changed files with 452 additions and 104 deletions

6
.config/hypr/README.md Normal file
View File

@@ -0,0 +1,6 @@
# Hyprland README
After updating you need to update hyprland packages to the latest version.
```sh
hyprpm update
```

View File

@@ -29,6 +29,9 @@ env = XDG_MENU_PREFIX,arch-
env = XCURSOR_SIZE,24
env = QT_QPA_PLATFORMTHEME,qt5ct # change to qt6ct if you have that
# Try to fix some electron apps
env = ELECTRON_OZONE_PLATFORM_HINT,auto
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
kb_layout = us
@@ -130,8 +133,12 @@ master {
}
gestures {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
workspace_swipe = true
# See https://wiki.hyprland.org/Configuring/Guestures/ for more
# hyprlang noerror true
gesture = 3, right, dispatcher, prevdesk
gesture = 3, left, dispatcher, nextdesk
# hyprlang noerror false
}
cursor {
@@ -144,6 +151,9 @@ misc {
disable_hyprland_logo = 1
focus_on_activate = 0 # This breaks vdesks
}
ecosystem {
no_donation_nag = 1
}
# hyprlang noerror true
plugin {
@@ -162,7 +172,7 @@ plugin {
bg_col = rgb(111111)
workspace_method = first 1 # [center/first] [workspace] e.g. first 1 or center m+1
enable_gesture = true # laptop touchpad
enable_gesture = false # laptop touchpad
gesture_fingers = 3 # 3 or 4
gesture_distance = 300 # how far is the "max"
gesture_positive = true # positive = swipe down. Negative = swipe up.

View File

@@ -2,6 +2,8 @@
$terminal = alacritty
$fileManager = dolphin
$menu = pgrep -x tofi-drun && pkill -x tofi-drun || tofi-drun --drun-launch=true > ~/.logs/tofi-drun.log 2>&1 &
$clipboard = /home/nathan/.local/bin/clipse
$StartWallpaperTimer = systemctl --user start wallpaper.timer && WallRizz -r -n -d ~/.config/backgrounds
@@ -14,16 +16,16 @@ bind = $mainMod, Q, killactive,
bind = $mainMod, F, togglefloating,
bind = $mainMod, space, exec, $menu
bind = ALT, SPACE, exec, ~/.config/hypr/scripts/search-windows.sh
bind = CTRL ALT, Delete, exit
bind = $mainMod, L, exec, hyprlock
bind = $mainMod, H, exec, alacritty --class float -e ~/.config/hypr/scripts/help.py
#bind = $mainMod, V, exec, [float] alacritty --class clipse -e /home/nathan/.local/bin/clipse
bind = $mainMod, V, exec, [float] kitty --class float-80 -e /home/nathan/.local/bin/clipse
bind = $mainMod, V, exec, [float] kitty --class float-80 -e $clipboard
# bind = $mainMod, P, pseudo, # dwindle
bind = $mainMod, J, togglesplit, # dwindle
bind = $mainMod, J, togglesplit,
# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
@@ -74,13 +76,6 @@ bind = $mainMod CTRL, S, movetoworkspace, special:terminal
bind = $mainMod SHIFT, S, exec, hyprshot -m region
bind = $mainMod CTRL SHIFT, S, exec, hyprshot -m window -m active
# Scroll through existing workspaces with mainMod + scroll
# bind = $mainMod, mouse_down, workspace, e+1
# bind = $mainMod, mouse_up, workspace, e-1
## Custom hyprland module keybinds
# hyprlang noerror true
@@ -113,8 +108,8 @@ bindl=, XF86AudioPrev, exec, playerctl previous
bindl= $mainMod CTRL, XF86TouchpadToggle, exec, hyprctl notify -1 2000 -1 "TODO Touchpad Toggle"
bind = $mainMod, P, exec, hyprctl notify -1 2000 -1 "TODO Screen Settings"
bindl = , Print, exec, hyprshot -m output -m active
bindl = $mainMod, Print, exec, hyprshot -m window -m active
bindl = $mainMod CTRL, Print, exec, hyprshot -m region
bind = $mainMod, Print, exec, hyprshot -m window -m active
bind = $mainMod CTRL, Print, exec, hyprshot -m region
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
@@ -135,7 +130,7 @@ bind = $mainMod, T, exec, alacritty --config-file ~/dotfiles/.alacritty-nozellij
bind = $mainMod, W, exec, ~/.config/hypr/scripts/wallpaper.sh
bind = $mainMod CTRL, W, exec, systemctl --user start wallpaper.timer && WallRizz -r -n -d ~/.config/backgrounds
bind = $mainMod CTRL, W, exec, $StartWallpaperTimer
# Capslock toggle submap
@@ -145,32 +140,21 @@ submap = capsmode
# Bindings for submap
bind = , 1, exec, hyprctl notify 5 2000 0 "Opening Brave Browser"
bind = , 1, exec,brave --proxy-pac-url="https://pac.cn01.woodburn.au/proxy.pac" --enable-features=UseOzonePlatform --ozone-platform=wayland --use-gl=angle --ignore-gpu-blocklist --enable-features=VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization,VaapiIgnoreDriverChecks,VaapiVideoDecodeLinuxGL,AcceleratedVideoEncoder,Vulkan,DefaultANGLEVulkan,VulkanFromANGLE --disable-gpu-memory-buffer-video-frames
bind = , 1, exec, brave --proxy-pac-url="https://pac.cn01.woodburn.au/proxy.pac" --enable-features=UseOzonePlatform --ozone-platform=wayland --use-gl=angle --ignore-gpu-blocklist --enable-features=VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization,VaapiIgnoreDriverChecks,VaapiVideoDecodeLinuxGL,AcceleratedVideoEncoder,Vulkan,DefaultANGLEVulkan,VulkanFromANGLE --disable-gpu-memory-buffer-video-frames
bind = , 1, submap, reset
bind = , 2, togglespecialworkspace, c2
bind = SHIFT, 2, movetoworkspace, special:c2
bind = , 3, togglespecialworkspace, c3
bind = SHIFT, 3, movetoworkspace, special:c3
bind = , 4, togglespecialworkspace, c4
bind = SHIFT, 4, movetoworkspace, special:c4
bind = , 5, togglespecialworkspace, c5
bind = SHIFT, 5, movetoworkspace, special:c5
bind = , 6, togglespecialworkspace, c6
bind = SHIFT, 6, movetoworkspace, special:c6
bind = , 2, exec, hyprpanel -q
bind = , 2, exec, hyprpanel
bind = , 2, submap, reset
bind = , 0, exec, hyprctl notify 5 2000 0 "Restarting hyprpaper"
bind = , 0, exec, hyprpaper >> ~/.logs/hyprpaper.log
bind = , 0, submap, reset
# Disable errors for this plugin
# hyprlang noerror true
bind = , I, invertactivewindow
bind = , I, submap, reset
# hyprlang noerror false
bind = , V, exec, hyprctl notify 5 2000 0 "Resetting Virtual Desks..."
bind = , V, exec, hyprctl dispatch vdeskreset
bind = , V, submap, reset
@@ -181,22 +165,27 @@ bind = , K, submap, reset
bind = , O, exec, hyprctl notify 2 2000 0 "Set Opacity..."
bind = , O, submap, opacity
# Help information
bind = , H, exec, alacritty --class float -e ~/.config/hypr/scripts/help.py
bind = , H, submap, reset
bind = , catchall, submap, reset
# Opacity submap
submap = opacity
bind = , 1, exec, ~/.config/hypr/scripts/opacity.sh 0.1
bind = , 2, exec, ~/.config/hypr/scripts/opacity.sh 0.2
bind = , 3, exec, ~/.config/hypr/scripts/opacity.sh 0.3
bind = , 4, exec, ~/.config/hypr/scripts/opacity.sh 0.4
bind = , 5, exec, ~/.config/hypr/scripts/opacity.sh 0.5
bind = , 6, exec, ~/.config/hypr/scripts/opacity.sh 0.6
bind = , 7, exec, ~/.config/hypr/scripts/opacity.sh 0.7
bind = , 8, exec, ~/.config/hypr/scripts/opacity.sh 0.8
bind = , 9, exec, ~/.config/hypr/scripts/opacity.sh 0.9
bind = , 0, exec, ~/.config/hypr/scripts/opacity.sh 1
bind = , C, exec, ~/.config/hypr/scripts/opacity.sh -1
bind = , 1, exec, ~/.config/hypr/scripts/opacity.py 0.1
bind = , 2, exec, ~/.config/hypr/scripts/opacity.py 0.2
bind = , 3, exec, ~/.config/hypr/scripts/opacity.py 0.3
bind = , 4, exec, ~/.config/hypr/scripts/opacity.py 0.4
bind = , 5, exec, ~/.config/hypr/scripts/opacity.py 0.5
bind = , 6, exec, ~/.config/hypr/scripts/opacity.py 0.6
bind = , 7, exec, ~/.config/hypr/scripts/opacity.py 0.7
bind = , 8, exec, ~/.config/hypr/scripts/opacity.py 0.8
bind = , 9, exec, ~/.config/hypr/scripts/opacity.py 0.9
bind = , 0, exec, ~/.config/hypr/scripts/opacity.py 1
bind = , C, exec, ~/.config/hypr/scripts/opacity.py -1
bind = , code:20, exec, ~/.config/hypr/scripts/opacity.py -1
bind = , catchall, submap, reset

View File

@@ -12,8 +12,8 @@ nextcloud &
sleep 2
vesktop --start-minimized &
kdeconnect-indicator
# slack -U &
kdeconnect-indicator &
WallRizz -r -n -d ~/.config/backgrounds
# Misc

260
.config/hypr/scripts/help.py Executable file
View File

@@ -0,0 +1,260 @@
#!/usr/bin/env python3
# This script is used to display help information for Hyprland keybinds.
import os
import sys
import re
import subprocess
HARDCODED_VARIABLES = {
"exec, ": "",
"VoidSymbol": "CAPS",
"brave --proxy-pac-url=\"https://pac.cn01.woodburn.au/proxy.pac\" --enable-features=UseOzonePlatform --ozone-platform=wayland --use-gl=angle --ignore-gpu-blocklist --enable-features=VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization,VaapiIgnoreDriverChecks,VaapiVideoDecodeLinuxGL,AcceleratedVideoEncoder,Vulkan,DefaultANGLEVulkan,VulkanFromANGLE --disable-gpu-memory-buffer-video-frames": "brave",
"~/.config/hypr/scripts/":"󰯂 ",
".sh": "",
".py": "",
"alacritty --config-file ~/dotfiles/.alacritty-nozellij.toml": "Terminal (No Zellij)",
"ydotool key 56:1 105:1 105:0 56:0":"Back",
"ydotool key 56:1 106:1 106:0 56:0":"Forward",
"mouse_left":"Left Tilt",
"mouse_right":"Right Tilt",
"[float] kitty --class float-80 -e":"",
"alacritty --class float-80 -e":"",
"alacritty --class float -e":"",
"$":"",
"mouse:272": "Left Drag",
"mouse:273": "Right Drag",
"hyprctl": "",
"dispatch ": "",
"vdesk,": "󰧨",
"vdeskreset": "󰧨 Reset",
"movetodesk": "󰶭 󰧨",
"movetoworkspace": "󰶭 󰧨",
"togglespecialworkspace": "󰔡 󰧨",
"special:":"",
"lastdesk": "󰧨 Last Active",
}
IGNORED_ACTIONS = [
"hyprctl notify",
"submap, reset",
"hyprpanel -q"
]
TYPE_MAP = {
'bind': ' ',
'bindl': '',
'bindle': 'Lock',
'bindm': '󰍽',
}
SUBMAP_MAP ={
"main": "",
"capsmode": "󰚟󰌎",
"opacity": "󰚟󱡔",
}
KEYCODES = {
20: "-"
}
# Read the keybinds.conf file
def read_keybinds(file_path = os.path.expanduser('~/.config/hypr/keybinds.conf')):
if not os.path.exists(file_path):
print(f"Error: The file {file_path} does not exist.")
sys.exit(1)
with open(file_path, 'r') as file:
lines = file.readlines()
return lines
def parse_keybinds(lines):
"""Parse keybinds from the configuration file and return a list of structured keybind information."""
keybinds = []
variables = {}
current_submap = "main"
for line_num, line in enumerate(lines, 1):
line = line.strip()
# Skip empty lines and comments
if not line or line.startswith('#'):
continue
# Handle variable definitions
if line.startswith('$'):
var_match = re.match(r'\$(\w+)\s*=\s*(.+)', line)
if var_match:
variables[var_match.group(1)] = var_match.group(2)
continue
# Handle submap declarations
if line.startswith('submap ='):
submap_match = re.match(r'submap\s*=\s*(\w+)', line)
if submap_match:
current_submap = submap_match.group(1)
continue
# Handle bind declarations
if line.startswith('bind') or line.startswith('bindle') or line.startswith('bindl') or line.startswith('bindm'):
bind_match = re.match(r'(bind[lme]?)\s*=\s*([^,]+),\s*([^,]+),\s*(.+)', line)
if bind_match:
bind_type = bind_match.group(1)
modifiers = bind_match.group(2).strip()
key = bind_match.group(3).strip()
action = bind_match.group(4).strip()
# Ignore certain actions
if any(ignored in action for ignored in IGNORED_ACTIONS):
continue
# Replace variables in the key, modifiers, and action
for var_name, var_value in variables.items():
modifiers = modifiers.replace(f'${var_name}', var_value)
key = key.replace(f'${var_name}', var_value)
# action = action.replace(f'${var_name}', var_value)
# Update for HARDCODED
for var_name, var_value in HARDCODED_VARIABLES.items():
modifiers = modifiers.replace(f'{var_name}', var_value)
key = key.replace(f'{var_name}', var_value)
action = action.replace(f'{var_name}', var_value)
if action.startswith('submap,'):
smap = action.split(',')[1].strip()
action = SUBMAP_MAP.get(smap, smap)
# Convert any 'code:<number>' in key to the corresponding Unicode character
code_match = re.match(r'code:(\d+)', key)
if code_match:
code_num = int(code_match.group(1))
key = KEYCODES[code_num] if code_num in KEYCODES else f"code:{code_num}"
# Add icon for logging
if ">>" in action:
log_action = action.split('>>')[0].strip()
action = f"{log_action}"
# Cleanup action
action = action.strip(',')
action = action.replace(',', '')
# Format the keybind description
key_combo = f"{modifiers} + {key}" if modifiers else key
keybind_info = {
'type': bind_type,
'submap': current_submap,
'key_combo': key_combo,
'action': action,
'line_num': line_num,
'raw_line': line
}
keybinds.append(keybind_info)
return keybinds
def format_keybind_for_display(keybind):
"""Format a keybind for display in fzf or terminal."""
submap_prefix = f"{SUBMAP_MAP.get(keybind['submap'], keybind['submap'].upper())} " if keybind['submap'] in SUBMAP_MAP else f"{keybind['submap'].upper()} "
type_prefix = f"{TYPE_MAP.get(keybind['type'], 'Unknown')} " if keybind['type'] in TYPE_MAP else f"{keybind['type']} "
# Clean up the action for display
action = keybind['action']
return f"{submap_prefix:3}{type_prefix}{keybind['key_combo']:30}{action}"
def run_fzf_search(keybinds):
"""Run fzf with the keybinds for interactive searching."""
try:
# Prepare the input for fzf
fzf_input = []
for keybind in keybinds:
formatted = format_keybind_for_display(keybind)
fzf_input.append(formatted)
# Run fzf
process = subprocess.Popen(
['fzf', '--reverse', '--border', '--preview-window=up:3',
'--header=Hyprland Keybinds - Press Enter or Esc to exit',
],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
stdout, stderr = process.communicate(input='\n'.join(fzf_input))
if process.returncode == 0 and stdout.strip():
# Find the selected keybind
selected_line = stdout.strip()
for keybind in keybinds:
if format_keybind_for_display(keybind) == selected_line:
print(f"\nSelected Keybind Details:")
print(f"Key Combination: {keybind['key_combo']}")
print(f"Action: {keybind['action']}")
print(f"Type: {keybind['type']}")
print(f"Submap: {keybind['submap']}")
print(f"Line: {keybind['line_num']}")
print(f"Raw: {keybind['raw_line']}")
break
except FileNotFoundError:
print("Error: fzf is not installed. Please install fzf to use interactive search.")
print("On most distributions: sudo pacman -S fzf # or apt install fzf")
return False
except Exception as e:
print(f"Error running fzf: {e}")
return False
return True
if __name__ == "__main__":
# Parse command line arguments - default to fzf unless --no-fzf is specified
use_fzf = not (len(sys.argv) > 1 and sys.argv[1] in ['--no-fzf', '-n', 'no-fzf'])
# Read and parse keybinds
raw_lines = read_keybinds()
parsed_keybinds = parse_keybinds(raw_lines)
if use_fzf:
# Use fzf for interactive searching
if not run_fzf_search(parsed_keybinds):
# Fallback to regular display if fzf fails
use_fzf = False
if not use_fzf:
print("Hyprland Keybinds Help:")
print("=" * 50)
print(f"Found {len(parsed_keybinds)} keybinds\n")
# Group by submap for better organization
submaps = {}
for keybind in parsed_keybinds:
submap = keybind['submap']
if submap not in submaps:
submaps[submap] = []
submaps[submap].append(keybind)
# Display keybinds grouped by submap
for submap_name, submap_keybinds in submaps.items():
if submap_name != 'main':
print(f"\n[{submap_name.upper()} SUBMAP]")
print("-" * 30)
else:
print("[MAIN KEYBINDS]")
print("-" * 30)
for keybind in submap_keybinds:
print(format_keybind_for_display(keybind))
print(f"\n{'-' * 50}")
print("Usage: python help.py [--no-fzf] to disable interactive search")
print("For more information, refer to the Hyprland documentation.")
print("You can also customize your keybinds in the keybinds.conf file.")
# Wait for user input before exiting
input("\nPress Enter to exit...")

47
.config/hypr/scripts/opacity.py Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env python3
import sys
import subprocess
import os
def tag_window(tag:str):
"""
Tags the currently focused window with the specified tag.
"""
command = f"hyprctl dispatch tagwindow {tag}"
subprocess.run(command, shell=True)
def notify(message: str):
"""
Displays a notification with the specified message.
"""
command = f'hyprctl notify 1 1000 0 "{message}"';
subprocess.run(command, shell=True)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 opacity.py <opacity_value>")
sys.exit(1)
opacity_value = sys.argv[1]
# Validate the opacity value
valid_opacities = ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']
if opacity_value not in valid_opacities and opacity_value != '-1':
print(f"Invalid opacity value: {opacity_value}. Valid values are: {', '.join(valid_opacities)}")
sys.exit(1)
# If the opacity value is -1, reset to default
if opacity_value == '-1':
notify("Resetting opacity to default")
for op in valid_opacities:
tag_window(f'-- -opacity:{op}')
else:
notify(f"Setting opacity to {opacity_value}")
for op in valid_opacities:
if op == opacity_value:
tag_window(f'opacity:{op}')
else:
tag_window(f'-- -opacity:{op}')

View File

@@ -1,38 +0,0 @@
#!/bin/bash
# Check if arg is passed
if [ -z "$1" ]; then
echo "Usage: $0 <opacity>"
echo "Example: $0 0.8"
exit 1
fi
# Validate opacity value (0.0 to 1.0 or -1)
if ! [[ "$1" =~ ^(-1|0(\.[0-9]+)?|1(\.0)?)$ ]]; then
echo "Error: Opacity must be a number between 0 and 1 or -1 for default."
exit 1
fi
# Get the opacity value
opacity="$1"
# Clear existing opacity settings
hyprctl dispatch tagwindow -- -opacity:0.1
hyprctl dispatch tagwindow -- -opacity:0.2
hyprctl dispatch tagwindow -- -opacity:0.3
hyprctl dispatch tagwindow -- -opacity:0.4
hyprctl dispatch tagwindow -- -opacity:0.5
hyprctl dispatch tagwindow -- -opacity:0.6
hyprctl dispatch tagwindow -- -opacity:0.7
hyprctl dispatch tagwindow -- -opacity:0.8
hyprctl dispatch tagwindow -- -opacity:0.9
hyprctl dispatch tagwindow -- -opacity:1
# Exit if opacity is -1 (default)
if [ "$opacity" == "-1" ]; then
hyprctl notify 1 1000 0 "Resetting opacity to default"
exit 0
fi
hyprctl notify 1 1000 0 "Setting opacity to $opacity"
hyprctl dispatch tagwindow opacity:"$opacity"

View File

@@ -8,4 +8,4 @@ exec-once = systemctl --user start hyprpolkitagent
exec-once = ~/.config/hypr/scripts/exec-once.sh > ~/.logs/exec-once.log 2>&1
# Random wallpaper
exec-once = WallRizz -r -n -d ~/.config/backgrounds
exec-once = wl-clip-persist --clipboard regular

View File

@@ -2,6 +2,9 @@
# Default floating rules to stop windows being too large or small
windowrulev2 = size <80% <80%,floating:1
windowrulev2 = size >50% >75%, class:(^org.kde.kdenlive$)
windowrule = float, class:(^xdg-desktop-portal-gtk$)
windowrule = size <80% <80%, class:(^xdg-desktop-portal-gtk$)
# windowrulev2 = size >50% >50%,floating:1
@@ -45,8 +48,15 @@ windowrule = size 100% 100%, class:^(Gromit-mpx)$
windowrule = opacity 1 override 1 override class:^(xdg-desktop-portal-gtk)$
windowrule = stayfocused, class:^(xdg-desktop-portal-gtk)$
windowrule = stayfocused, class:^(soffice)$
windowrule = stayfocused, class:^(virt-manager)$, title:^$
#windowrule = float 1, class:^(xdg-desktop-portal-gtk)$
windowrulev2 = stayfocused, class:^(Sparrow)$, title:^$, xwayland:1
windowrulev2 = focusonactivate 1, class:^(Sparrow)$, title:^$, xwayland:1
windowrulev2 = allowsinput 1, class:^(Sparrow)$, title:^$, xwayland:1
windowrulev2 = stayfocused, class:^(Sparrow)$, title:^$, xwayland:1
# No Opacity windowrules
@@ -57,6 +67,7 @@ windowrule = opacity 1 override 1 override class:^(Bootstrap Studio)$
windowrule = opacity 1 override 1 override class:^(Minecraft)(.*)$
windowrule = opacity 1 override 1 override class:^(gimp)$
windowrule = opacity 1 override 1 override class:^(com.obsproject.Studio)$
windowrule = opacity 1 override 1 override class:^$
# Disable opacity for Alacritty (as it already has a transparent background)
@@ -78,3 +89,13 @@ windowrule = opacity 0.8 override 0.8 override, tag:opacity:0.8
windowrule = opacity 0.9 override 0.9 override, tag:opacity:0.9
windowrule = opacity 1 override 1 override, tag:opacity:1
#! (Still doesn't work) Add org.kde.kdeconnect.daemon for KDE connect pointer
windowrule = noblur, class:^(org.kde.kdeconnect.daemon)$ #As it is transparent it will prevent it blurring so you can see what you are ponting at
windowrule = nofocus,class:^(org.kde.kdeconnect.daemon)$ # Disables focus so if you have the option to dim on focus it will not dim the window behind it
windowrule = nodim,class:^(org.kde.kdeconnect.daemon)$ # As it is out of focus it will prevent it from diming, so its brighter if you have window dimming on
windowrule = noshadow,class:^(org.kde.kdeconnect.daemon)$ # Preents it having a shadow if you have window shadows on
windowrule = idleinhibit,class:^(org.kde.kdeconnect.daemon)$ # Will prevent your computer from idling if this is in use
windowrule = float,class:^(org.kde.kdeconnect.daemon)$
# windowrule = maximize,class:^(org.kde.kdeconnect.daemon)$
# windowrule = move 0 0,class:^(org.kde.kdeconnect.daemon)$