Public part of my dotfiles.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pushToTalk 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #!/usr/bin/env python3
  2. import sys
  3. import pulsectl
  4. from Xlib import X, XK, display
  5. from Xlib.ext import record
  6. from Xlib.protocol import rq
  7. KEY = XK.XK_F7
  8. def mute(state):
  9. with pulsectl.Pulse('list-source') as pulse:
  10. for source in pulse.source_list():
  11. if source.port_active:
  12. if source.mute != state:
  13. pulse.mute(source, state)
  14. print(f"{source.name} {'un' if not state else ''}muted")
  15. mute(True)
  16. local_dpy = display.Display()
  17. record_dpy = display.Display()
  18. def record_callback(reply):
  19. if reply.category != record.FromServer:
  20. return
  21. if reply.client_swapped:
  22. print("* received swapped protocol data, cowardly ignored")
  23. return
  24. if not len(reply.data) or reply.data[0] < 2:
  25. # not an event
  26. return
  27. data = reply.data
  28. while len(data):
  29. event, data = rq.EventField(None).parse_binary_value(
  30. data, record_dpy.display, None, None)
  31. if event.type in [X.KeyPress, X.KeyRelease]:
  32. keysym = local_dpy.keycode_to_keysym(event.detail, 0)
  33. if keysym == KEY:
  34. mute(event.type == X.KeyRelease)
  35. # Check if the extension is present
  36. if not record_dpy.has_extension("RECORD"):
  37. print("RECORD extension not found")
  38. sys.exit(1)
  39. r = record_dpy.record_get_version(0, 0)
  40. print("RECORD extension version %d.%d" %
  41. (r.major_version, r.minor_version))
  42. # Create a recording context; we only want key and mouse events
  43. ctx = record_dpy.record_create_context(
  44. 0,
  45. [record.AllClients],
  46. [{
  47. 'core_requests': (0, 0),
  48. 'core_replies': (0, 0),
  49. 'ext_requests': (0, 0, 0, 0),
  50. 'ext_replies': (0, 0, 0, 0),
  51. 'delivered_events': (0, 0),
  52. 'device_events': (X.KeyPress, X.MotionNotify),
  53. 'errors': (0, 0),
  54. 'client_started': False,
  55. 'client_died': False,
  56. }])
  57. # Enable the context; this only returns after a call to record_disable_context,
  58. # while calling the callback function in the meantime
  59. try:
  60. record_dpy.record_enable_context(ctx, record_callback)
  61. except KeyboardInterrupt:
  62. local_dpy.record_disable_context(ctx)
  63. local_dpy.flush()
  64. # Finally free the context
  65. record_dpy.record_free_context(ctx)