mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 06:00:09 +02:00
Float key in the input relay, docking everything, and the plan for profiles
The input relay owns the float key now: float_toggle (Meta+Shift+F unless the rules have their own key combinations) floats the window under the pointer, or the active one over the wallpaper, and docks it if it floats. dock_all puts every floating window back. Both are mappable to mouse and controller buttons, and work without pointer mode. The KWin script no longer registers a shortcut, and ft-floatd drops the old one. Key combinations move to Input Settings' Keyboard page. docs/floating-windows.md records the decisions from 2026-09-30 (the title bar button, Launch as Standalone, profiles), and docs/profiles.md plans profiles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e16b7588e2
commit
1e83f96b0f
9 files changed
+220
-69
No files matched your search
@@ -9,6 +9,8 @@ to the input relay over its control socket (@frametop_relay):
|
||||
- Controllers: the same for the Frame controllers' buttons, minus the gaze actions (gaze
|
||||
mode is a mouse feature). They're read by the pointer helper through SteamVR input
|
||||
(@ft_pointer_helper: vrstatus, vrglobal), and a mapped button is taken from games.
|
||||
- Keyboard: when Frametop's keyboard opens, and key combinations for any action (Meta+Shift+F
|
||||
floats a window unless the rules have their own list).
|
||||
- Pointer: speed, dot size, distance and the rest, applied live.
|
||||
- Ignored panels: SteamVR overlays the pointer passes through (POINTER_IGNORE), by app or
|
||||
one by one. The helper lists them (@ft_pointer_helper "overlays").
|
||||
@@ -65,6 +67,7 @@ ACTION_LABELS = {
|
||||
"sens_up": "Faster pointer",
|
||||
"sens_down": "Slower pointer", "layout_reset": "Reset desktop screen layout",
|
||||
"screens_toggle": "Hide/show desktop screens", "keyboard_toggle": "Open/close keyboard",
|
||||
"float_toggle": "Float window in VR / put it back", "dock_all": "Put all floating windows back",
|
||||
"key": "Pass through as key",
|
||||
"none": "Do nothing",
|
||||
}
|
||||
@@ -104,6 +107,15 @@ POINTER_ROLES = {"right": "Right hand", "left": "Left hand", "stylus": "Stylus (
|
||||
# Key combinations ("key_bindings" in the rules): modifiers, either side folded into the left code.
|
||||
MODIFIER_CODES = {29: 29, 97: 29, 42: 42, 54: 42, 56: 56, 100: 56, 125: 125, 126: 125}
|
||||
MODIFIER_NAMES = {29: "Ctrl", 42: "Shift", 56: "Alt", 125: "Meta"}
|
||||
# What a rules file without "key_bindings" gets (the relay's DEFAULT_KEY_BINDINGS): Meta+Shift+F.
|
||||
DEFAULT_KEY_BINDINGS = {"42+125+33": "float_toggle"}
|
||||
|
||||
|
||||
def key_bindings(rules):
|
||||
"""The rules' key combinations, or the defaults if it has none of its own (an empty list
|
||||
counts as its own)."""
|
||||
bound = rules.get("key_bindings")
|
||||
return dict(bound) if isinstance(bound, dict) else dict(DEFAULT_KEY_BINDINGS)
|
||||
# The gaze service's settings (gaze/ft-gazed): whose eye tracking, and the eye bias.
|
||||
GAZE_TRACKERS = {"steam": "SteamVR's eye tracker", "own": "our own eye tracker"}
|
||||
GAZE_EYES = {"auto": "auto", "left": "left eye", "right": "right eye"}
|
||||
@@ -842,7 +854,7 @@ class Backend(QObject):
|
||||
|
||||
@Property("QVariantList", notify=mappingsChanged)
|
||||
def keyShortcuts(self):
|
||||
bound = read_json(RULES_PATH).get("key_bindings", {}) or {}
|
||||
bound = key_bindings(read_json(RULES_PATH))
|
||||
return [{"combo": c, "label": self.comboName(c), "action": a, "actionLabel": ACTION_LABELS.get(a, a)}
|
||||
for c, a in sorted(bound.items())]
|
||||
|
||||
@@ -869,14 +881,15 @@ class Backend(QObject):
|
||||
|
||||
def _save_shortcut(self, combo, action):
|
||||
rules = read_json(RULES_PATH)
|
||||
rules.setdefault("key_bindings", {})[combo] = action
|
||||
rules["key_bindings"] = dict(key_bindings(rules), **{combo: action})
|
||||
self._save_rules(rules)
|
||||
self.message.emit(f"{self.comboName(combo)} → {ACTION_LABELS[action]}", False)
|
||||
|
||||
@Slot(str)
|
||||
def removeShortcut(self, combo):
|
||||
rules = read_json(RULES_PATH)
|
||||
(rules.get("key_bindings") or {}).pop(combo, None)
|
||||
rules["key_bindings"] = key_bindings(rules)
|
||||
rules["key_bindings"].pop(combo, None)
|
||||
self._save_rules(rules)
|
||||
self.message.emit(f"{self.comboName(combo)} removed", False)
|
||||
|
||||
|
||||
Reference in new issue
Block a user