Skip to content
Open
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
18 changes: 13 additions & 5 deletions src/hhd/controller/lib/hide.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,18 @@ def unhide_all():
except Exception:
pass

if not removed:
# Always trigger udev reload if we removed rules OR have hidden devices
if removed or _hidden:
# We have to reload affected devices if we removed rules
for parent in _hidden:
reload_children(parent)

# If no specific devices to reload but we removed rules, reload all input devices
if removed and not _hidden:
subprocess.run(["udevadm", "trigger", "--subsystem-match=input"], capture_output=True)
subprocess.run(["udevadm", "settle"], capture_output=True)

_hidden.clear()
return True

# We have to reload affected devices if we removed rules
for parent in _hidden:
reload_children(parent)
_hidden.clear()
return True
6 changes: 6 additions & 0 deletions src/hhd/controller/physical/evdev.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ def open(self) -> Sequence[int]:

def close(self, exit: bool) -> bool:
if self.dev:
try:
if self.grab:
self.dev.ungrab()
except Exception as e:
logger.warning(f"Failed to ungrab device {self.dev.path}: {e}")

if self.hidden and exit:
unhide_gamepad(self.dev.path, self.hidden)
self.dev.close()
Expand Down
26 changes: 23 additions & 3 deletions src/hhd/device/claw/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,21 +455,25 @@ def controller_loop(
btn_map=dconf.get("btn_mapping", MSI_CLAW_MAPPINGS),
)

# Mute these so after suspend we do not get stray keypresses
# Desktop detectors with dynamic grabbing
d_kbd_2 = DesktopDetectorEvdev(
vid=[MSI_CLAW_VID],
pid=[MSI_CLAW_XINPUT_PID, MSI_CLAW_DINPUT_PID],
required=False,
grab=True,
grab=False, # Start without grabbing, grab dynamically when needed
capabilities={EC("EV_KEY"): [EC("KEY_ESC")]},
)
d_mouse = DesktopDetectorEvdev(
vid=[MSI_CLAW_VID],
pid=[MSI_CLAW_XINPUT_PID, MSI_CLAW_DINPUT_PID],
required=False,
grab=True,
grab=False, # Start without grabbing, grab dynamically when needed
capabilities={EC("EV_KEY"): [EC("BTN_MOUSE")]},
)

# Track grabbing state for desktop detectors
d_kbd_2_grabbed = False
d_mouse_grabbed = False

kargs = {}

Expand Down Expand Up @@ -559,6 +563,22 @@ def prepare(m):
if id(d) in to_run:
evs.extend(d.produce(r))

# Dynamic grabbing for desktop detectors
# Only grab when we need to detect desktop events, release when not needed
if not d_kbd_2_grabbed and d_kbd_2.dev:
try:
d_kbd_2.dev.grab()
d_kbd_2_grabbed = True
except Exception:
pass # Ignore grab failures, continue without grabbing

if not d_mouse_grabbed and d_mouse.dev:
try:
d_mouse.dev.grab()
d_mouse_grabbed = True
except Exception:
pass # Ignore grab failures, continue without grabbing

# Detect if we are in desktop mode through events
desktop_mode = d_mouse.desktop or d_kbd_2.desktop
d_mouse.desktop = False
Expand Down
1 change: 1 addition & 0 deletions src/hhd/plugins/powerbutton/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class PowerButtonConfig(NamedTuple):
"MSI Claw A8",
"Claw A8 BZ2EM",
type="only_press",
phys=["gpio-keys", "LNXPWRBN", "PNP0C0C"],
),
]

Expand Down