Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions dash-frontend/src/tab/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ enum SettingType {
ClickFreezeTimeMs,
Clock12h,
DoubleCursorFix,
FocusedScreenAssistX,
FocusedScreenAssistY,
FocusedScreenRotateAssistX,
FocusedScreenRotateAssistY,
FocusedScreenCurveX,
FocusedScreenDistance,
FocusedScreenScale,
FocusFollowsMouseMode,
HandsfreePointer,
HideGrabHelp,
Expand Down Expand Up @@ -290,6 +297,13 @@ impl SettingType {
pub fn mut_f32(self, config: &mut GeneralConfig) -> &mut f32 {
match self {
Self::UiAnimationSpeed => &mut config.ui_animation_speed,
Self::FocusedScreenAssistX => &mut config.focused_screen_assist_x,
Self::FocusedScreenAssistY => &mut config.focused_screen_assist_y,
Self::FocusedScreenRotateAssistX => &mut config.focused_screen_rotate_assist_x,
Self::FocusedScreenRotateAssistY => &mut config.focused_screen_rotate_assist_y,
Self::FocusedScreenCurveX => &mut config.focused_screen_curve_x,
Self::FocusedScreenDistance => &mut config.focused_screen_distance,
Self::FocusedScreenScale => &mut config.focused_screen_scale,
Self::UiGradientIntensity => &mut config.ui_gradient_intensity,
Self::UiRoundMultiplier => &mut config.ui_round_multiplier,
Self::ScrollSpeed => &mut config.scroll_speed,
Expand Down Expand Up @@ -372,6 +386,13 @@ impl SettingType {
Self::ClickFreezeTimeMs => Ok("APP_SETTINGS.CLICK_FREEZE_TIME_MS"),
Self::Clock12h => Ok("APP_SETTINGS.CLOCK_12H"),
Self::DoubleCursorFix => Ok("APP_SETTINGS.DOUBLE_CURSOR_FIX"),
Self::FocusedScreenAssistX => Err("Focused screen assist X"),
Self::FocusedScreenAssistY => Err("Focused screen assist Y"),
Self::FocusedScreenRotateAssistX => Err("Focused screen rotate assist X"),
Self::FocusedScreenRotateAssistY => Err("Focused screen rotate assist Y"),
Self::FocusedScreenCurveX => Err("Focused screen curve X"),
Self::FocusedScreenDistance => Err("Focused screen distance"),
Self::FocusedScreenScale => Err("Focused screen scale"),
Self::FocusFollowsMouseMode => Ok("APP_SETTINGS.FOCUS_FOLLOWS_MOUSE_MODE"),
Self::GridOpacity => Ok("APP_SETTINGS.GRID_OPACITY"),
Self::HandsfreePointer => Ok("APP_SETTINGS.HANDSFREE_POINTER"),
Expand Down
7 changes: 7 additions & 0 deletions dash-frontend/src/tab/settings/tab_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ pub fn mount(mp: &mut MacroParams, parent: WidgetID) -> anyhow::Result<()> {
options_slider_f32(mp, c, SettingType::ScrollSpeed, 0.1, 5.0, 0.1)?;
options_slider_f32(mp, c, SettingType::LongPressDuration, 0.1, 2.0, 0.1)?;
options_slider_f32(mp, c, SettingType::PointerLerpFactor, 0.1, 1.0, 0.1)?;
options_slider_f32(mp, c, SettingType::FocusedScreenDistance, 0.2, 2.0, 0.05)?;
options_slider_f32(mp, c, SettingType::FocusedScreenScale, 1.0, 2.5, 0.05)?;
options_slider_f32(mp, c, SettingType::FocusedScreenCurveX, 0.0, 0.8, 0.02)?;
options_slider_f32(mp, c, SettingType::FocusedScreenAssistX, 0.0, 0.75, 0.01)?;
options_slider_f32(mp, c, SettingType::FocusedScreenAssistY, 0.0, 0.85, 0.01)?;
options_slider_f32(mp, c, SettingType::FocusedScreenRotateAssistX, 0.0, 0.5, 0.01)?;
options_slider_f32(mp, c, SettingType::FocusedScreenRotateAssistY, 0.0, 0.5, 0.01)?;
options_slider_f32(mp, c, SettingType::XrClickSensitivity, 0.1, 1.0, 0.1)?;
options_slider_f32(mp, c, SettingType::XrClickSensitivityRelease, 0.1, 1.0, 0.1)?;
options_slider_i32(mp, c, SettingType::ClickFreezeTimeMs, 0, 500, 50)?;
Expand Down
48 changes: 48 additions & 0 deletions scripts/test-focus.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
set -e

REPO_ROOT="/home/taylor/dev/open-source/real-wayvr"
WAYVRCTL="$REPO_ROOT/target/debug/wayvrctl"

if [ ! -f "$WAYVRCTL" ]; then
echo "wayvrctl not found, building..."
cd "$REPO_ROOT"
cargo build --package wayvrctl
fi

active_window=$(hyprctl -j activewindow)

if [ -z "$active_window" ] || [ "$active_window" = "{}" ]; then
echo "No active window found"
exit 1
fi

monitor_id=$(echo "$active_window" | jq -r '.monitor')
monitor_name=$(hyprctl -j monitors | jq -r --argjson monitor_id "$monitor_id" '.[] | select(.id == $monitor_id) | .name' | head -n 1)
monitor_json=$(hyprctl -j monitors | jq -c --argjson monitor_id "$monitor_id" '.[] | select(.id == $monitor_id)' | head -n 1)

if [ -z "$monitor_name" ] || [ "$monitor_name" = "null" ]; then
echo "Could not resolve active monitor"
exit 1
fi

target_x=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'(((($active.at[0] + ($active.size[0] / 2)) - $monitor.x) / $monitor.width) | if . < 0 then 0 elif . > 1 then 1 else . end)')

target_y=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'(((($active.at[1] + ($active.size[1] / 2)) - $monitor.y) / $monitor.height) | if . < 0 then 0 elif . > 1 then 1 else . end)')

echo "Current wayvrctl screen focus commands:"
"$WAYVRCTL" screen-focus-toggle --help
echo
"$WAYVRCTL" screen-focus-at --help
echo
echo "Toggling screen focus for active monitor: $monitor_name"
"$WAYVRCTL" screen-focus-toggle "$monitor_name"
echo
echo "Refreshing screen focus at target: monitor=$monitor_name x=$target_x y=$target_y"
"$WAYVRCTL" screen-focus-at --refresh-only "$monitor_name" "$target_x" "$target_y"
35 changes: 35 additions & 0 deletions scripts/wayvr-hypr-focus.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash
set -e

REPO_ROOT="/home/taylor/dev/open-source/real-wayvr"
WAYVRCTL="$REPO_ROOT/target/debug/wayvrctl"

if [ ! -f "$WAYVRCTL" ]; then
echo "wayvrctl not found, building..."
cd "$REPO_ROOT"
cargo build --package wayvrctl
fi

active_window=$(hyprctl -j activewindow)

if [ -z "$active_window" ] || [ "$active_window" = "{}" ]; then
echo "No active window found in Hyprland"
exit 1
fi

monitor_id=$(echo "$active_window" | jq -r '.monitor')

if [ -z "$monitor_id" ] || [ "$monitor_id" = "null" ]; then
echo "Could not get active monitor id"
exit 1
fi

monitor_name=$(hyprctl -j monitors | jq -r --argjson monitor_id "$monitor_id" '.[] | select(.id == $monitor_id) | .name' | head -n 1)

if [ -z "$monitor_name" ] || [ "$monitor_name" = "null" ]; then
echo "Could not resolve monitor name for id $monitor_id"
exit 1
fi

echo "Toggling focused screen for active monitor: $monitor_name"
exec "$WAYVRCTL" screen-focus-toggle "$monitor_name"
142 changes: 142 additions & 0 deletions scripts/wayvr-hypr-helper-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#!/bin/bash
set -e

WAYVRCTL="${WAYVRCTL:-wayvrctl}"
STATE_DIR="/tmp/wayvr-hypr-focus"
PID_FILE="$STATE_DIR/watch.pid"
SCREEN_FILE="$STATE_DIR/screen_name"
SOCKET_PATH="${XDG_RUNTIME_DIR}/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"

mkdir -p "$STATE_DIR"

run_focus_command() {
local refresh_flag="$1"
local expected_screen="${2:-}"

active_window=$(hyprctl -j activewindow)

if [ -z "$active_window" ] || [ "$active_window" = "{}" ]; then
return 1
fi

monitor_id=$(echo "$active_window" | jq -r '.monitor')

if [ -z "$monitor_id" ] || [ "$monitor_id" = "null" ]; then
return 1
fi

monitor_name=$(hyprctl -j monitors | jq -r --argjson monitor_id "$monitor_id" '.[] | select(.id == $monitor_id) | .name' | head -n 1)
monitor_json=$(hyprctl -j monitors | jq -c --argjson monitor_id "$monitor_id" '.[] | select(.id == $monitor_id)' | head -n 1)

if [ -z "$monitor_name" ] || [ "$monitor_name" = "null" ]; then
return 1
fi

if [ -n "$expected_screen" ] && [ "$monitor_name" != "$expected_screen" ]; then
return 1
fi

target_x=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'(((($active.at[0] + ($active.size[0] / 2)) - $monitor.x) / $monitor.width) | if . < 0 then 0 elif . > 1 then 1 else . end)')

target_y=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'(((($active.at[1] + ($active.size[1] / 2)) - $monitor.y) / $monitor.height) | if . < 0 then 0 elif . > 1 then 1 else . end)')

crop_x=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'((($active.at[0] - $monitor.x) / $monitor.width) | if . < 0 then 0 elif . > 1 then 1 else . end)')

crop_y=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'((($active.at[1] - $monitor.y) / $monitor.height) | if . < 0 then 0 elif . > 1 then 1 else . end)')

crop_w=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'((($active.size[0]) / $monitor.width) | if . < 0.02 then 0.02 elif . > 1 then 1 else . end)')

crop_h=$(jq -n \
--argjson active "$active_window" \
--argjson monitor "$monitor_json" \
'((($active.size[1]) / $monitor.height) | if . < 0.02 then 0.02 elif . > 1 then 1 else . end)')

"$WAYVRCTL" screen-focus-at $refresh_flag \
--crop-x "$crop_x" --crop-y "$crop_y" --crop-w "$crop_w" --crop-h "$crop_h" \
"$monitor_name" "$target_x" "$target_y"

printf '%s' "$monitor_name" > "$SCREEN_FILE"
}

event_stream() {
python3 - "$SOCKET_PATH" <<'PY'
import socket
import sys

sock_path = sys.argv[1]
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(sock_path)
buf = b""

while True:
data = sock.recv(4096)
if not data:
break
buf += data
while b"\n" in buf:
line, buf = buf.split(b"\n", 1)
sys.stdout.write(line.decode("utf-8", "replace") + "\n")
sys.stdout.flush()
PY
}

should_refresh_event() {
case "$1" in
activewindowv2*|activewindow*|fullscreen*|movewindow*|movewindowv2*|changefloatingmode*|openwindow*|closewindow*)
return 0
;;
*)
return 1
;;
esac
}

if [ "${1:-}" = "--watch" ]; then
watched_screen="$2"
while [ -f "$PID_FILE" ] && [ "$(cat "$PID_FILE")" = "$$" ]; do
event_stream | while IFS= read -r line; do
if [ ! -f "$PID_FILE" ] || [ "$(cat "$PID_FILE")" != "$$" ]; then
break
fi

if should_refresh_event "$line"; then
run_focus_command --refresh-only "$watched_screen" || true
fi
done
sleep 0.2
done
exit 0
fi

if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
watched_screen="$(cat "$SCREEN_FILE" 2>/dev/null || true)"
kill "$(cat "$PID_FILE")" 2>/dev/null || true
rm -f "$PID_FILE" "$SCREEN_FILE"
if [ -n "$watched_screen" ]; then
exec "$WAYVRCTL" screen-focus-toggle "$watched_screen"
fi
exit 0
fi

run_focus_command "" || {
echo "No active window found"
exit 1
}

nohup "$0" --watch "$(cat "$SCREEN_FILE")" >/dev/null 2>&1 &
printf '%s' "$!" > "$PID_FILE"
25 changes: 25 additions & 0 deletions scripts/wayvr-hypr-helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
set -e

active_window=$(hyprctl -j activewindow)

if [ -z "$active_window" ] || [ "$active_window" = "{}" ]; then
echo "No active window found"
exit 1
fi

monitor_id=$(echo "$active_window" | jq -r '.monitor')

if [ -z "$monitor_id" ] || [ "$monitor_id" = "null" ]; then
echo "Could not get active monitor id"
exit 1
fi

monitor_name=$(hyprctl -j monitors | jq -r --argjson monitor_id "$monitor_id" '.[] | select(.id == $monitor_id) | .name' | head -n 1)

if [ -z "$monitor_name" ] || [ "$monitor_name" = "null" ]; then
echo "Could not resolve monitor name for id $monitor_id"
exit 1
fi

exec wayvrctl screen-focus-toggle "$monitor_name"
Loading