49
49
#endif
50
50
#include <xcb/xcb_aux.h>
51
51
#include <xcb/randr.h>
52
+ #include <xcb/xtest.h>
53
+ #include <time.h>
52
54
53
55
#include "i3lock.h"
54
56
#include "xcb.h"
@@ -257,6 +259,7 @@ bool pass_media_keys = false;
257
259
bool pass_screen_keys = false;
258
260
bool pass_power_keys = false;
259
261
bool pass_volume_keys = false;
262
+ bool special_passthrough = false;
260
263
261
264
// for the rendering thread, so we can clean it up
262
265
pthread_t draw_thread ;
@@ -650,6 +653,32 @@ static bool skip_without_validation(void) {
650
653
return false;
651
654
}
652
655
656
+ /*
657
+ * Sends key press event to root/wm
658
+ * Releases the keyboard, sends the event, and
659
+ * grabs the keyboard again
660
+ * */
661
+ static void send_key_to_root (xcb_key_press_event_t * event , bool twice ) {
662
+ if (!special_passthrough ) {
663
+ xcb_send_event (conn , true, screen -> root , XCB_EVENT_MASK_BUTTON_PRESS , (char * )event );
664
+ return ;
665
+ }
666
+
667
+ xcb_ungrab_keyboard (conn , XCB_CURRENT_TIME );
668
+ DEBUG ("Received: %d at %ld\n" , event -> detail , time (0 ));
669
+
670
+ xcb_test_fake_input (conn , XCB_KEY_PRESS , event -> detail , XCB_CURRENT_TIME , screen -> root , 0 , 0 , 0 );
671
+ xcb_test_fake_input (conn , XCB_KEY_RELEASE , event -> detail , XCB_CURRENT_TIME , screen -> root , 0 , 0 , 0 );
672
+
673
+ if (twice ) {
674
+ xcb_test_fake_input (conn , XCB_KEY_PRESS , event -> detail , XCB_CURRENT_TIME , screen -> root , 0 , 0 , 0 );
675
+ xcb_test_fake_input (conn , XCB_KEY_RELEASE , event -> detail , XCB_CURRENT_TIME , screen -> root , 0 , 0 , 0 );
676
+ }
677
+
678
+ xcb_grab_keyboard (conn , true, screen -> root , XCB_CURRENT_TIME , XCB_GRAB_MODE_ASYNC , XCB_GRAB_MODE_ASYNC );
679
+ xcb_set_input_focus (conn , XCB_INPUT_FOCUS_PARENT , win , XCB_CURRENT_TIME );
680
+ }
681
+
653
682
/*
654
683
* Handle key presses. Fixes state, then looks up the key symbol for the
655
684
* given keycode, then looks up the key symbol (as UCS-2), converts it to
@@ -709,7 +738,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
709
738
case XKB_KEY_XF86AudioMute :
710
739
case XKB_KEY_XF86AudioLowerVolume :
711
740
case XKB_KEY_XF86AudioRaiseVolume :
712
- xcb_send_event ( conn , true, screen -> root , XCB_EVENT_MASK_BUTTON_PRESS , ( char * ) event );
741
+ send_key_to_root ( event , true);
713
742
return ;
714
743
}
715
744
}
@@ -719,7 +748,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
719
748
switch (ksym ) {
720
749
case XKB_KEY_XF86MonBrightnessUp :
721
750
case XKB_KEY_XF86MonBrightnessDown :
722
- xcb_send_event ( conn , true, screen -> root , XCB_EVENT_MASK_BUTTON_PRESS , ( char * ) event );
751
+ send_key_to_root ( event , false );
723
752
return ;
724
753
}
725
754
}
@@ -730,7 +759,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
730
759
case XKB_KEY_XF86PowerDown :
731
760
case XKB_KEY_XF86PowerOff :
732
761
case XKB_KEY_XF86Sleep :
733
- xcb_send_event ( conn , true, screen -> root , XCB_EVENT_MASK_BUTTON_PRESS , ( char * ) event );
762
+ send_key_to_root ( event , false );
734
763
return ;
735
764
}
736
765
}
@@ -741,7 +770,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
741
770
case XKB_KEY_XF86AudioMute :
742
771
case XKB_KEY_XF86AudioLowerVolume :
743
772
case XKB_KEY_XF86AudioRaiseVolume :
744
- xcb_send_event ( conn , true, screen -> root , XCB_EVENT_MASK_BUTTON_PRESS , ( char * ) event );
773
+ send_key_to_root ( event , true);
745
774
return ;
746
775
}
747
776
}
@@ -1543,6 +1572,7 @@ int main(int argc, char *argv[]) {
1543
1572
{"pass-screen-keys" , no_argument , NULL , 602 },
1544
1573
{"pass-power-keys" , no_argument , NULL , 603 },
1545
1574
{"pass-volume-keys" , no_argument , NULL , 604 },
1575
+ {"special-passthrough" , no_argument , NULL , 605 },
1546
1576
1547
1577
// bar indicator stuff
1548
1578
{"bar-indicator" , no_argument , NULL , 700 },
@@ -2104,6 +2134,9 @@ int main(int argc, char *argv[]) {
2104
2134
case 604 :
2105
2135
pass_volume_keys = true;
2106
2136
break ;
2137
+ case 605 :
2138
+ special_passthrough = true;
2139
+ break ;
2107
2140
2108
2141
// Bar indicator
2109
2142
case 700 :
0 commit comments