summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hypr/dynamic-cursor.conf139
-rw-r--r--hypr/hyprland.conf10
-rw-r--r--hypr/hyprlock.conf2
-rwxr-xr-xhypr/scripts/waybar_peek.py193
-rw-r--r--kitty/current-theme.conf2
-rw-r--r--kitty/kitty.conf2
-rw-r--r--waybar/config7
7 files changed, 350 insertions, 5 deletions
diff --git a/hypr/dynamic-cursor.conf b/hypr/dynamic-cursor.conf
new file mode 100644
index 0000000..f343737
--- /dev/null
+++ b/hypr/dynamic-cursor.conf
@@ -0,0 +1,139 @@
+plugin:dynamic-cursors {
+
+ # enables the plugin
+ enabled = true
+
+ # sets the cursor behaviour, supports these values:
+ # tilt - tilt the cursor based on x-velocity
+ # rotate - rotate the cursor based on movement direction
+ # stretch - stretch the cursor shape based on direction and velocity
+ # none - do not change the cursors behaviour
+ mode = stretch
+
+ # minimum angle difference in degrees after which the shape is changed
+ # smaller values are smoother, but more expensive for hw cursors
+ threshold = 2
+
+ # override the mode behaviour per shape
+ # this is a keyword and can be repeated many times
+ # by default, there are no rules added
+ # see the dedicated `shape rules` section below!
+ #shaperule = <shape-name>, <mode> (optional), <property>: <value>, ...
+ # shaperule = <shape-name>, <mode> (optional), <property>: <value>, ...
+
+ # for mode = rotate
+ rotate {
+
+ # length in px of the simulated stick used to rotate the cursor
+ # most realistic if this is your actual cursor size
+ length = 20
+
+ # clockwise offset applied to the angle in degrees
+ # this will apply to ALL shapes
+ offset = 0.0
+ }
+
+ # for mode = tilt
+ tilt {
+
+ # controls how powerful the tilt is, the lower, the more power
+ # this value controls at which speed (px/s) the full tilt is reached
+ limit = 5000
+
+ # relationship between speed and tilt, supports these values:
+ # linear - a linear function is used
+ # quadratic - a quadratic function is used (most realistic to actual air drag)
+ # negative_quadratic - negative version of the quadratic one, feels more aggressive
+ # see `activation` in `src/mode/utils.cpp` for how exactly the calculation is done
+ function = quadratic
+
+ # time window (ms) over which the speed is calculated
+ # higher values will make slow motions smoother but more delayed
+ window = 100
+
+ # full tilt for each side (°)
+ full_tilt = 60
+ }
+
+ # for mode = stretch
+ stretch {
+
+ # controls how much the cursor is stretched
+ # this value controls at which speed (px/s) the full stretch is reached
+ # the full stretch being twice the original length
+ limit = 4000
+
+ # relationship between speed and stretch amount, supports these values:
+ # linear - a linear function is used
+ # quadratic - a quadratic function is used
+ # negative_quadratic - negative version of the quadratic one, feels more aggressive
+ # see `activation` in `src/mode/utils.cpp` for how exactly the calculation is done
+ function = negative_quadratic
+
+ # time window (ms) over which the speed is calculated
+ # higher values will make slow motions smoother but more delayed
+ window = 100
+ }
+
+ # configure shake to find
+ # magnifies the cursor if its is being shaken
+ shake {
+
+ # enables shake to find
+ enabled = true
+
+ # use nearest-neighbour (pixelated) scaling when shaking
+ # may look weird when effects are enabled
+ nearest = true
+
+ # controls how soon a shake is detected
+ # lower values mean sooner
+ threshold = 6.0
+
+ # magnification level immediately after shake start
+ base = 4.0
+ # magnification increase per second when continuing to shake
+ speed = 4.0
+ # how much the speed is influenced by the current shake intensitiy
+ influence = 0.0
+
+ # maximal magnification the cursor can reach
+ # values below 1 disable the limit (e.g. 0)
+ limit = 0.0
+
+ # time in millseconds the cursor will stay magnified after a shake has ended
+ timeout = 2000
+
+ # show cursor behaviour `tilt`, `rotate`, etc. while shaking
+ effects = false
+
+ # enable ipc events for shake
+ # see the `ipc` section below
+ ipc = false
+ }
+
+ # use hyprcursor to get a higher resolution texture when the cursor is magnified
+ # see the `hyprcursor` section below
+ hyprcursor {
+
+ # use nearest-neighbour (pixelated) scaling when magnifing beyond texture size
+ # this will also have effect without hyprcursor support being enabled
+ # 0 / false - never use pixelated scaling
+ # 1 / true - use pixelated when no highres image
+ # 2 - always use pixleated scaling
+ nearest = true
+
+ # enable dedicated hyprcursor support
+ enabled = true
+
+ # resolution in pixels to load the magnified shapes at
+ # be warned that loading a very high-resolution image will take a long time and might impact memory consumption
+ # -1 means we use [normal cursor size] * [shake:base option]
+ resolution = -1
+
+ # shape to use when clientside cursors are being magnified
+ # see the shape-name property of shape rules for possible names
+ # specifying clientside will use the actual shape, but will be pixelated
+ fallback = clientside
+ }
+}
diff --git a/hypr/hyprland.conf b/hypr/hyprland.conf
index 3120920..1c4354f 100644
--- a/hypr/hyprland.conf
+++ b/hypr/hyprland.conf
@@ -2,11 +2,12 @@
### ENVIRONMENT VARIABLES ###
#############################
+
# See https://wiki.hypr.land/Configuring/Environment-variables/
#These are some of the environment variables suggested by the Hyprland wiki.
env = HYPRCURSOR_SIZE,24
-#env = HYPRCURSOR_THEME,rose-pine-cursor
+env = HYPRCURSOR_THEME,notawita-gray
# Enables hyrpland traces for debugging.
env = HYPRLAND_TRACE,1
@@ -71,6 +72,9 @@ $menu = rofi -show drun
# Or execute your favorite apps at launch like this:
exec-once = dunst
+exec-once = hyprpm reload
+# To toggle on and off waybar
+exec-once = ~/.config/hypr/scripts/waybar_peek.py &
# Forces applications to require a password prompt to elevate priviliges.
exec-once = systemctl --user start hyprpolkitagent
@@ -331,6 +335,8 @@ bindl = , XF86AudioPause, exec, playerctl play-pause
bindl = , XF86AudioPlay, exec, playerctl play-pause
bindl = , XF86AudioPrev, exec, playerctl previous
+bind = , xf86poweroff , exec, hyprlock
+
##############################
### WINDOWS AND WORKSPACES ###
##############################
@@ -346,3 +352,5 @@ bindl = , XF86AudioPrev, exec, playerctl previous
# Fix some dragging issues with XWayland
# windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
+
+source = ~/.config/hypr/dynamic-cursor.conf
diff --git a/hypr/hyprlock.conf b/hypr/hyprlock.conf
index ee67978..e700fea 100644
--- a/hypr/hyprlock.conf
+++ b/hypr/hyprlock.conf
@@ -35,7 +35,7 @@ animations {
background {
monitor =
- color = rgba(120, 120, 120, 1)
+ color = rgba(148, 148, 148, 1)
}
auth {
diff --git a/hypr/scripts/waybar_peek.py b/hypr/scripts/waybar_peek.py
new file mode 100755
index 0000000..227b425
--- /dev/null
+++ b/hypr/scripts/waybar_peek.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python3
+"""
+Waybar Peek - Auto-hide for Hyprland (Multi-monitor)
+Shows waybar when cursor is at top edge, hides when workspace has windows.
+
+Toggle auto-hide: pkill -HUP -f waybar_peek
+"""
+
+import json
+import os
+import signal
+import socket
+import time
+from pathlib import Path
+
+# Configuration
+PIXEL_THRESHOLD = 5 # Show bar when within 5px of top
+PIXEL_THRESHOLD_HIDE = 50 # Hide when cursor goes below 50px
+POLL_INTERVAL = 0.1 # Poll every 100ms
+
+class WaybarPeek:
+ def __init__(self):
+ self.xdg_runtime = os.environ.get("XDG_RUNTIME_DIR", f"/run/user/{os.getuid()}")
+ self.hypr_sig = os.environ.get("HYPRLAND_INSTANCE_SIGNATURE", "")
+ self.socket_path = f"{self.xdg_runtime}/hypr/{self.hypr_sig}/.socket.sock"
+
+ self.cursor_at_top = False
+ self.last_visibility = None
+ self.waybar_pid = None
+ self.enabled = True # Auto-hide enabled by default
+
+ # Setup signal handler for toggle
+ signal.signal(signal.SIGHUP, self.toggle_handler)
+
+ def toggle_handler(self, signum, frame):
+ """Handle SIGHUP to toggle auto-hide on/off"""
+ self.enabled = not self.enabled
+ status = "enabled" if self.enabled else "disabled"
+ print(f"Auto-hide {status}")
+
+ if not self.enabled:
+ # When disabled, always show the bar
+ self.set_waybar_visible(True)
+ self.last_visibility = True
+ else:
+ # When re-enabled, force state recalculation
+ self.last_visibility = None
+
+ def hypr_query(self, cmd: str) -> str:
+ """Query Hyprland via socket"""
+ try:
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.connect(self.socket_path)
+ sock.send(cmd.encode())
+ response = b""
+ while True:
+ chunk = sock.recv(4096)
+ if not chunk:
+ break
+ response += chunk
+ sock.close()
+ return response.decode()
+ except Exception:
+ return ""
+
+ def get_cursor_pos(self) -> tuple:
+ """Get cursor position as (x, y)"""
+ try:
+ data = json.loads(self.hypr_query("j/cursorpos"))
+ return (data.get("x", 0), data.get("y", 0))
+ except Exception:
+ return (0, 0)
+
+ def get_monitors(self) -> list:
+ """Get all monitors with their bounds"""
+ try:
+ return json.loads(self.hypr_query("j/monitors"))
+ except Exception:
+ return []
+
+ def check_windows(self) -> bool:
+ """Check if active workspace has windows"""
+ try:
+ data = json.loads(self.hypr_query("j/activeworkspace"))
+ return data.get("windows", 0) > 0
+ except Exception:
+ return False
+
+ def find_waybar_pid(self) -> int:
+ """Find waybar process ID"""
+ try:
+ for entry in Path("/proc").iterdir():
+ if not entry.is_dir() or not entry.name.isdigit():
+ continue
+ comm_file = entry / "comm"
+ if comm_file.exists():
+ comm = comm_file.read_text().strip()
+ if comm in ("waybar", ".waybar-wrapped"):
+ return int(entry.name)
+ except Exception:
+ pass
+ return None
+
+ def set_waybar_visible(self, visible: bool) -> bool:
+ """Send signal to waybar to show/hide"""
+ if self.waybar_pid is None:
+ self.waybar_pid = self.find_waybar_pid()
+
+ if self.waybar_pid is None:
+ return False
+
+ try:
+ sig = signal.SIGUSR2 if visible else signal.SIGUSR1
+ os.kill(self.waybar_pid, sig)
+ return True
+ except ProcessLookupError:
+ self.waybar_pid = self.find_waybar_pid()
+ if self.waybar_pid:
+ try:
+ sig = signal.SIGUSR2 if visible else signal.SIGUSR1
+ os.kill(self.waybar_pid, sig)
+ return True
+ except Exception:
+ pass
+ except Exception:
+ pass
+ return False
+
+ def is_cursor_at_top(self) -> bool:
+ """Check if cursor is at top edge of any monitor"""
+ cursor_x, cursor_y = self.get_cursor_pos()
+ monitors = self.get_monitors()
+
+ for m in monitors:
+ mx, my = m.get("x", 0), m.get("y", 0)
+ mw, mh = m.get("width", 0), m.get("height", 0)
+
+ # Check if cursor is on this monitor
+ if mx <= cursor_x <= mx + mw and my <= cursor_y <= my + mh:
+ # Calculate local Y position relative to this monitor
+ local_y = cursor_y - my
+
+ # Use different thresholds based on current state
+ threshold = PIXEL_THRESHOLD_HIDE if self.cursor_at_top else PIXEL_THRESHOLD
+ return local_y <= threshold
+
+ return False
+
+ def run(self):
+ """Main loop"""
+ print(f"waybar-peek started (PID: {os.getpid()})")
+ print(f"Socket: {self.socket_path}")
+ print(f"Toggle auto-hide: pkill -HUP -f waybar_peek")
+
+ # Initial state
+ windows_opened = self.check_windows()
+ self.last_visibility = not windows_opened
+
+ while True:
+ try:
+ # Skip auto-hide logic if disabled
+ if not self.enabled:
+ time.sleep(POLL_INTERVAL)
+ continue
+
+ # Check cursor position
+ new_cursor_at_top = self.is_cursor_at_top()
+ if new_cursor_at_top != self.cursor_at_top:
+ self.cursor_at_top = new_cursor_at_top
+
+ # Check windows
+ windows_opened = self.check_windows()
+
+ # Determine visibility: show if cursor at top OR no windows
+ should_be_visible = self.cursor_at_top or not windows_opened
+
+ # Update waybar if state changed
+ if should_be_visible != self.last_visibility:
+ self.set_waybar_visible(should_be_visible)
+ self.last_visibility = should_be_visible
+
+ time.sleep(POLL_INTERVAL)
+
+ except KeyboardInterrupt:
+ print("\nExiting...")
+ break
+ except Exception as e:
+ print(f"Error: {e}")
+ time.sleep(1)
+
+if __name__ == "__main__":
+ app = WaybarPeek()
+ app.run()
diff --git a/kitty/current-theme.conf b/kitty/current-theme.conf
index 1fa7062..b10d8e3 100644
--- a/kitty/current-theme.conf
+++ b/kitty/current-theme.conf
@@ -14,7 +14,7 @@ selection_background #ffffff
# Cursor colors
-cursor #ffffff
+cursor #ababab
cursor_text_color #000000
diff --git a/kitty/kitty.conf b/kitty/kitty.conf
index 61c8289..42e5f85 100644
--- a/kitty/kitty.conf
+++ b/kitty/kitty.conf
@@ -2934,6 +2934,8 @@ font_family family="Fira Code"
font_size 10
bold_font auto
italic_font auto
+cursor_trail 1
+cursor_trail_color #ababab
bold_italic_font auto
# END_KITTY_FONTS
diff --git a/waybar/config b/waybar/config
index a4c5d89..1f258e2 100644
--- a/waybar/config
+++ b/waybar/config
@@ -1,4 +1,9 @@
{
+
+ "start_hidden": false,
+ "ipc": true,
+ "on-sigusr1": "hide",
+ "on-sigusr2": "show",
"layer": "top",
"position": "top",
"modules-left": [
@@ -26,8 +31,6 @@
"format": "{name}",
"persistent-workspaces": {
"1": [],
- "2": [],
- "3": []
}
},
"hyprland/window": {