Skip to content

Commit 4ff79c0

Browse files
authored
Merge pull request #231 from JezerM/passKeys
--pass-*-keys options (#136)
2 parents 8da502a + 4346d8b commit 4ff79c0

File tree

6 files changed

+54
-9
lines changed

6 files changed

+54
-9
lines changed

.github/workflows/Build Test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
- name: Install deps
1010
run: |
1111
sudo apt update
12-
sudo apt install pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
12+
sudo apt install pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxcb-xtest0-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
1313
- name: Build
1414
run: ./build.sh
1515
- name: Check and distcheck

.github/workflows/codeql-analysis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666

6767
- run: |
6868
sudo apt-get update
69-
sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
69+
sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxcb-xtest0-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
7070
./build.sh
7171
7272
- name: Perform CodeQL Analysis

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ The following dependencies will need to be installed for a successful build, dep
8181
### Debian
8282
Run this command to install all dependencies:
8383
```
84-
sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util0-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
84+
sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util0-dev libxcb-xrm-dev libxcb-xtest0-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
8585
```
8686
If you still see missing packages during build after installing all of these dependencies, try following the steps [here](https://github.com/Raymo111/i3lock-color/issues/211#issuecomment-809891727).
8787

@@ -95,7 +95,7 @@ sudo dnf install -y autoconf automake cairo-devel fontconfig gcc libev-devel lib
9595
### Ubuntu 18/20.04 LTS
9696
Run this command to install all dependencies:
9797
```
98-
sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
98+
sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxcb-xtest0-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev
9999
```
100100

101101
## Building i3lock-color

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ AC_SEARCH_LIBS([iconv_open], [iconv], , [AC_MSG_FAILURE([cannot find the require
9797

9898
dnl Each prefix corresponds to a source tarball which users might have
9999
dnl downloaded in a newer version and would like to overwrite.
100-
PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-composite])
100+
PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-composite xcb-xtest])
101101
PKG_CHECK_MODULES([XCB_IMAGE], [xcb-image])
102102
PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util xcb-atom])
103103
PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm])

i3lock.1

+12
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,18 @@ power - XF86PowerDown, XF86PowerOff, XF86Sleep
388388
volume - XF86AudioMute, XF86AudioLowerVolume, XF86AudioRaiseVolume
389389
.RE
390390

391+
.TP
392+
.B \-\-special\-passthrough
393+
Allows special keys to pass through the locked screen, with \-\-pass\-{media, screen,
394+
power, volume}\-keys. Keystrokes are forcibly sent to the window manager or desktop
395+
environment in three steps: un-grab keyboard, send key, and re-grab the keyboard.
396+
No other keys will be sent to the WM/DE.
397+
398+
Note: ONLY use this option if the special keys are NOT passed through without it.
399+
This could be less safe than the default behavior since the keyboard is ungrabbed for
400+
the keys to be passed through. This HAS been tested though, so there SHOULDN'T be any
401+
security issues.
402+
391403
.TP
392404
.B \-\-bar\-indicator
393405
Replaces the usual ring indicator with a bar indicator. Comes with perks.

i3lock.c

+37-4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
#endif
5050
#include <xcb/xcb_aux.h>
5151
#include <xcb/randr.h>
52+
#include <xcb/xtest.h>
53+
#include <time.h>
5254

5355
#include "i3lock.h"
5456
#include "xcb.h"
@@ -257,6 +259,7 @@ bool pass_media_keys = false;
257259
bool pass_screen_keys = false;
258260
bool pass_power_keys = false;
259261
bool pass_volume_keys = false;
262+
bool special_passthrough = false;
260263

261264
// for the rendering thread, so we can clean it up
262265
pthread_t draw_thread;
@@ -650,6 +653,32 @@ static bool skip_without_validation(void) {
650653
return false;
651654
}
652655

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+
653682
/*
654683
* Handle key presses. Fixes state, then looks up the key symbol for the
655684
* 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) {
709738
case XKB_KEY_XF86AudioMute:
710739
case XKB_KEY_XF86AudioLowerVolume:
711740
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);
713742
return;
714743
}
715744
}
@@ -719,7 +748,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
719748
switch(ksym) {
720749
case XKB_KEY_XF86MonBrightnessUp:
721750
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);
723752
return;
724753
}
725754
}
@@ -730,7 +759,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
730759
case XKB_KEY_XF86PowerDown:
731760
case XKB_KEY_XF86PowerOff:
732761
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);
734763
return;
735764
}
736765
}
@@ -741,7 +770,7 @@ static void handle_key_press(xcb_key_press_event_t *event) {
741770
case XKB_KEY_XF86AudioMute:
742771
case XKB_KEY_XF86AudioLowerVolume:
743772
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);
745774
return;
746775
}
747776
}
@@ -1543,6 +1572,7 @@ int main(int argc, char *argv[]) {
15431572
{"pass-screen-keys", no_argument, NULL, 602},
15441573
{"pass-power-keys", no_argument, NULL, 603},
15451574
{"pass-volume-keys", no_argument, NULL, 604},
1575+
{"special-passthrough", no_argument, NULL, 605},
15461576

15471577
// bar indicator stuff
15481578
{"bar-indicator", no_argument, NULL, 700},
@@ -2104,6 +2134,9 @@ int main(int argc, char *argv[]) {
21042134
case 604:
21052135
pass_volume_keys = true;
21062136
break;
2137+
case 605:
2138+
special_passthrough = true;
2139+
break;
21072140

21082141
// Bar indicator
21092142
case 700:

0 commit comments

Comments
 (0)