Repository navigation
Expand file tree
/
Copy pathxx-hotkey-demo.c
More file actions
138 lines (118 loc) · 3.84 KB
/
Copy pathxx-hotkey-demo.c
File metadata and controls
138 lines (118 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Minimal xx-hotkey demo client.
*
* Requests a single global hotkey (Super+Space) and prints the lifecycle and
* trigger/release events. It requires a compositor that implements
* xx_hotkey_manager_v1; without one it just reports that the global is
* missing.
*
* Build with `make xx-hotkey-demo`
*/
#include "xx-hotkey-v1-client-protocol.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#include <xkbcommon/xkbcommon.h>
static struct xx_hotkey_manager_v1 *manager;
static const char *deny_reason_str(uint32_t reason) {
switch (reason) {
case XX_HOTKEY_V1_DENY_REASON_ALREADY_BOUND:
return "already_bound";
case XX_HOTKEY_V1_DENY_REASON_NOT_PERMITTED:
return "not_permitted";
default:
return "unknown";
}
}
static void hk_bound(void *data, struct xx_hotkey_v1 *hk) {
(void)data;
(void)hk;
printf("bound: hotkey is active\n");
}
static void hk_denied(void *data, struct xx_hotkey_v1 *hk, uint32_t reason,
const char *message) {
(void)data;
(void)hk;
if (message && message[0])
printf("denied: %s (%s)\n", deny_reason_str(reason), message);
else
printf("denied: %s\n", deny_reason_str(reason));
}
static void hk_revoked(void *data, struct xx_hotkey_v1 *hk,
const char *message) {
(void)data;
(void)hk;
if (message && message[0])
printf("revoked (%s)\n", message);
else
printf("revoked\n");
}
static void hk_triggered(void *data, struct xx_hotkey_v1 *hk, uint32_t serial,
uint32_t time) {
(void)data;
(void)hk;
printf("triggered (serial=%u, time=%u)\n", serial, time);
}
static void hk_released(void *data, struct xx_hotkey_v1 *hk, uint32_t serial,
uint32_t time) {
(void)data;
(void)hk;
printf("released (serial=%u, time=%u)\n", serial, time);
}
static const struct xx_hotkey_v1_listener hk_listener = {
.bound = hk_bound,
.denied = hk_denied,
.revoked = hk_revoked,
.triggered = hk_triggered,
.released = hk_released,
};
static void reg_global(void *data, struct wl_registry *reg, uint32_t name,
const char *interface, uint32_t version) {
(void)data;
(void)version;
if (strcmp(interface, xx_hotkey_manager_v1_interface.name) == 0)
manager = wl_registry_bind(reg, name, &xx_hotkey_manager_v1_interface, 1);
}
static void reg_global_remove(void *data, struct wl_registry *reg,
uint32_t name) {
(void)data;
(void)reg;
(void)name;
}
static const struct wl_registry_listener reg_listener = {
.global = reg_global,
.global_remove = reg_global_remove,
};
int main(void) {
struct wl_display *display = wl_display_connect(NULL);
if (!display) {
fprintf(stderr, "failed to connect to a wayland display\n");
return 1;
}
struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, ®_listener, NULL);
wl_display_roundtrip(display);
if (!manager) {
fprintf(stderr, "compositor does not implement xx_hotkey_manager_v1\n");
wl_display_disconnect(display);
return 1;
}
xx_hotkey_manager_v1_set_app_id(manager, "com.example.xx-hotkey-demo");
struct xx_hotkey_v1 *hotkey = xx_hotkey_manager_v1_create_hotkey(manager);
xx_hotkey_v1_add_listener(hotkey, &hk_listener, NULL);
xx_hotkey_v1_set_description(hotkey, "Toggle the launcher");
xx_hotkey_v1_set_key_trigger(hotkey, XKB_KEY_space,
XX_HOTKEY_MANAGER_V1_MODIFIERS_SUPER);
xx_hotkey_v1_commit(hotkey);
printf("requested Super+Space; waiting for events (Ctrl-C to quit)...\n");
while (wl_display_dispatch(display) != -1)
;
xx_hotkey_v1_destroy(hotkey);
xx_hotkey_manager_v1_destroy(manager);
wl_registry_destroy(registry);
wl_display_disconnect(display);
return 0;
}