mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 06:00:09 +02:00
Lazy susan: Meta+Alt+Tab spins the panels around you
- ft-screens "spin next|prev|<degrees>": every unpinned screen and floating window turns together about a vertical axis through your head (0.3 s, eased), so the next panel on the right or left comes to straight ahead; the arrangement stays as it is. Taps during a spin add to it, from where the panels are headed; grabbing a panel or placing it (ft-layout, ft-floatd) takes it out of the spin - when a spin settles, the panel in front gets the pointer (recenter), typing (as after a click), and KWin's active window: its floating window, or the top window on a screen (ft-floatd "front N", the KWin script's activate-output). KWin's outputs follow the screens' new places (ft-layout scale), as after a move - the input relay: spin_next and spin_prev actions, Meta+Alt+Tab and Meta+Alt+Shift+Tab by default; Frametop Input Settings lists them. Not Meta+Tab: that's Cmd+Tab on a Mac reached through a remote desktop like RustDesk, and the relay would take the Mac's app switcher. Meta+Alt+Tab (Cmd+Option+Tab) is unused on macOS, Windows, and KDE Used on the Frame (SteamOS 0.3.0 build 20260922) with one screen and three or four floating windows, through RustDesk to a Mac. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1ebf3692fb
commit
6fb168a8b8
9 files changed
+220
-10
No files matched your search
+21
-6
@@ -31,7 +31,9 @@ gaze_quickcal = the gaze service's one-dot check ("quickcal" to @ft_gazed), sens
|
||||
layout_reset = put the desktop screens back in their saved layout, screens_toggle = hide or show the desktop screens,
|
||||
keyboard_toggle = open or close Frametop's keyboard, float_toggle = float the desktop window under the
|
||||
pointer (else the active one) in VR, or put it back if it floats, dock_all = put every floating
|
||||
window back (both to ft-floatd, @frametop_float), profile:NAME = switch to that profile (ft-layout
|
||||
window back (both to ft-floatd, @frametop_float), spin_next and spin_prev = turn every panel in the
|
||||
room about your head so the next one to the right or left comes to the front (ft-screens' "spin",
|
||||
Meta+Alt+Tab and Meta+Alt+Shift+Tab by default), profile:NAME = switch to that profile (ft-layout
|
||||
use NAME: its screens and apps; docs/profiles.md), key = pass through as a key, none).
|
||||
|
||||
Frame controller buttons can be mapped too ("controller_buttons": {"right/a": action} in the
|
||||
@@ -189,12 +191,15 @@ RULES_PATH = os.path.expanduser("~/.config/frametop-input.json")
|
||||
ACTIONS = ("left", "right", "middle", "back", "scroll_up", "scroll_down", "dashboard", "recenter",
|
||||
"pointer_toggle", "follow_toggle", "gaze_toggle", "gaze_precision", "gaze_drag", "gaze_left", "gaze_right",
|
||||
"gaze_quickcal", "sens_up", "sens_down", "layout_reset", "screens_toggle", "keyboard_toggle", "float_toggle",
|
||||
"dock_all", "key", "none")
|
||||
"dock_all", "spin_next", "spin_prev", "key", "none")
|
||||
# Gaze mode is a mouse feature: these never come from a controller button (docs/gaze-controllers.md).
|
||||
GAZE_ACTIONS = ("gaze_toggle", "gaze_precision", "gaze_drag", "gaze_left", "gaze_right", "gaze_quickcal")
|
||||
# Key combinations a rules file without "key_bindings" gets: Meta+J and Meta+K click at the gaze
|
||||
# (free on the Frametop desktop, and apps don't use Meta), Meta+Shift+F floats a window.
|
||||
DEFAULT_KEY_BINDINGS = {"125+36": "gaze_left", "125+37": "gaze_right", "42+125+33": "float_toggle"}
|
||||
# (free on the Frametop desktop, and apps don't use Meta), Meta+Shift+F floats a window, and
|
||||
# Meta+Alt+Tab and Meta+Alt+Shift+Tab spin the panels around you (ft-screens' lazy susan); not
|
||||
# Meta+Tab, which is Cmd+Tab on a Mac reached through a remote desktop like RustDesk.
|
||||
DEFAULT_KEY_BINDINGS = {"125+36": "gaze_left", "125+37": "gaze_right", "42+125+33": "float_toggle",
|
||||
"56+125+15": "spin_next", "42+56+125+15": "spin_prev"}
|
||||
KEY_F24 = 194 # sent to the desktop with a Meta combination (see the top)
|
||||
# Key combinations ("key_bindings"): modifiers, each side's code folded into the left one's.
|
||||
MODIFIERS = {29: 29, 97: 29, 42: 42, 54: 42, 56: 56, 100: 56, 125: 125, 126: 125}
|
||||
@@ -210,6 +215,9 @@ GAZED = "\0ft_gazed"
|
||||
FLOAT = "\0frametop_float" # ft-floatd, floating windows in the Frametop desktop
|
||||
# Actions for ft-floatd ("float_toggle", "dock_all"): they don't need pointer mode.
|
||||
FLOAT_ACTIONS = {"float_toggle": b"float pointer", "dock_all": b"dock all"}
|
||||
# Actions for ft-screens: spin_next and spin_prev turn every panel in the room about your head,
|
||||
# so the next one to the right or left comes to the front. They don't need pointer mode either.
|
||||
SCREENS_ACTIONS = {"spin_next": b"spin next", "spin_prev": b"spin prev"}
|
||||
PROFILE = "profile:" # "profile:NAME": switch to that profile (doesn't need pointer mode either)
|
||||
|
||||
|
||||
@@ -218,7 +226,7 @@ def known_action(a):
|
||||
|
||||
|
||||
def needs_pointer(a):
|
||||
return a not in FLOAT_ACTIONS and not a.startswith(PROFILE)
|
||||
return a not in FLOAT_ACTIONS and a not in SCREENS_ACTIONS and not a.startswith(PROFILE)
|
||||
KEYS = "\0frametop_keys" # keys of keyboards grabbed for the desktop, for other readers
|
||||
FT_LAYOUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "layout", "ft-layout")
|
||||
DEFAULT_BUTTONS = {BTN_LEFT: "left", BTN_RIGHT: "right", BTN_MIDDLE: "middle",
|
||||
@@ -748,7 +756,7 @@ def main():
|
||||
|
||||
def do_action(action, value, now, source="mouse"):
|
||||
"""A mapped mouse or controller button, or key combination (pointer mode only, but
|
||||
for FLOAT_ACTIONS and profiles)."""
|
||||
for FLOAT_ACTIONS, SCREENS_ACTIONS, and profiles)."""
|
||||
if action == "keyboard_toggle":
|
||||
if value == 1 and vr_keyboard_mode() != "never":
|
||||
vr_keyboard("toggle")
|
||||
@@ -765,6 +773,13 @@ def main():
|
||||
except OSError:
|
||||
pass # the Frametop desktop isn't running
|
||||
log(action)
|
||||
elif action in SCREENS_ACTIONS:
|
||||
if value == 1:
|
||||
try:
|
||||
screens_sock.sendto(SCREENS_ACTIONS[action], SCREENS)
|
||||
except OSError:
|
||||
pass # the Frametop desktop isn't running
|
||||
log(action)
|
||||
elif state["pointer"]:
|
||||
state["pointer"].action(action, value, now, source)
|
||||
|
||||
|
||||
Reference in new issue
Block a user