create Wayland desktop environment that simply binds keyboard shortcuts
up vote
0
down vote
favorite
There are dozens of questions on here asking how to create global keyboard bindings in a Wayland environment. Generally, the answer is "use your desktop environment" - an answer that is pretty much useless to most anyone asking the question.
So, in order to draw out a more useful answer, I ask how does one create a minimal Wayland desktop environment which can bind shortcut keys?
I've got Mutter running as my WM, and I'm using GNOME Do as a launcher. It's pretty much exactly the desktop environment I want, with the exception that I can't bind hotkeys.
I don't care if I have to write a 10k line C app to make this work. I just want to know how to proceed. How does GNOME bind keyboard shortcuts within Wayland? Where is the code for that? Where is the appropriate documentation for Wayland/Mutter?
keyboard-shortcuts wayland
add a comment |
up vote
0
down vote
favorite
There are dozens of questions on here asking how to create global keyboard bindings in a Wayland environment. Generally, the answer is "use your desktop environment" - an answer that is pretty much useless to most anyone asking the question.
So, in order to draw out a more useful answer, I ask how does one create a minimal Wayland desktop environment which can bind shortcut keys?
I've got Mutter running as my WM, and I'm using GNOME Do as a launcher. It's pretty much exactly the desktop environment I want, with the exception that I can't bind hotkeys.
I don't care if I have to write a 10k line C app to make this work. I just want to know how to proceed. How does GNOME bind keyboard shortcuts within Wayland? Where is the code for that? Where is the appropriate documentation for Wayland/Mutter?
keyboard-shortcuts wayland
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
There are dozens of questions on here asking how to create global keyboard bindings in a Wayland environment. Generally, the answer is "use your desktop environment" - an answer that is pretty much useless to most anyone asking the question.
So, in order to draw out a more useful answer, I ask how does one create a minimal Wayland desktop environment which can bind shortcut keys?
I've got Mutter running as my WM, and I'm using GNOME Do as a launcher. It's pretty much exactly the desktop environment I want, with the exception that I can't bind hotkeys.
I don't care if I have to write a 10k line C app to make this work. I just want to know how to proceed. How does GNOME bind keyboard shortcuts within Wayland? Where is the code for that? Where is the appropriate documentation for Wayland/Mutter?
keyboard-shortcuts wayland
There are dozens of questions on here asking how to create global keyboard bindings in a Wayland environment. Generally, the answer is "use your desktop environment" - an answer that is pretty much useless to most anyone asking the question.
So, in order to draw out a more useful answer, I ask how does one create a minimal Wayland desktop environment which can bind shortcut keys?
I've got Mutter running as my WM, and I'm using GNOME Do as a launcher. It's pretty much exactly the desktop environment I want, with the exception that I can't bind hotkeys.
I don't care if I have to write a 10k line C app to make this work. I just want to know how to proceed. How does GNOME bind keyboard shortcuts within Wayland? Where is the code for that? Where is the appropriate documentation for Wayland/Mutter?
keyboard-shortcuts wayland
keyboard-shortcuts wayland
asked Nov 8 at 16:57
rich remer
2,0842333
2,0842333
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
After much research and experimentation, it looks like libevdev
is maybe the right tool. I developed the program below as a proof-of-concept to bind Alt+X
to launch xterm
.
Unfortunately, it has to be run as root, so I'm thinking I need to somehow tie this into the local desktop session. For my purposes, it's probably good enough to just setuid
using the root
user and call it a day.
I'm also not convinced my keyboard detection heuristic is very good. I'm essentially looking for any device that has keys and a repeat rate, which on my system only matches my keyboard.
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#define DEVROOT "/dev/input/"
#define DEVROOT_LEN 12
#define PATH_LEN (DEVROOT_LEN + NAME_MAX)
int outerr(int, const char*);
struct libevdev* open_device(int);
bool kblike(struct libevdev*);
int main(int argc, char* argv) {
DIR* dir;
struct dirent* entry;
char path[PATH_LEN];
int fd, err;
struct libevdev* dev = NULL;
struct input_event ev;
bool key, rep, alt;
if (!(dir = opendir("/dev/input"))) {
return outerr(errno, "cannot enumerate devices");
}
// look for keyboard device
while (entry = readdir(dir)) {
if (DT_CHR == entry->d_type) {
sprintf(path, "/dev/input/%s", entry->d_name);
if (-1 == (fd = open(path, O_RDONLY|O_NONBLOCK))) {
return outerr(errno, "cannot read device");
}
if (dev = open_device(fd)) {
if (kblike(dev)) break;
libevdev_free(dev);
dev = NULL;
}
}
}
closedir(dir);
// check if keyboard was found
if (dev == NULL) {
return outerr(ENODEV, "could not detect keyboard");
} else do {
err = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (err == 0 && ev.type == EV_KEY) switch (ev.code) {
case KEY_LEFTALT:
alt = ev.value == 1;
break;
case KEY_X:
if (ev.value == 1 && alt) system("xterm");
break;
}
} while (err == 1 || err == 0 || err == -EAGAIN);
return 0;
}
int outerr(int errnum, const char* msg) {
fprintf(stderr, "%s (%s)n", msg, strerror(errnum));
return errnum;
}
bool kblike(struct libevdev* dev) {
return libevdev_has_event_type(dev, EV_KEY)
&& libevdev_has_event_type(dev, EV_REP);
}
struct libevdev* open_device(int fd) {
struct libevdev* dev = libevdev_new();
int err;
if (dev == NULL) {
errno = ENOMEM;
} else if (0 > (err = libevdev_set_fd(dev, fd))) {
libevdev_free(dev);
dev = NULL;
errno = -err;
}
return dev;
}
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
After much research and experimentation, it looks like libevdev
is maybe the right tool. I developed the program below as a proof-of-concept to bind Alt+X
to launch xterm
.
Unfortunately, it has to be run as root, so I'm thinking I need to somehow tie this into the local desktop session. For my purposes, it's probably good enough to just setuid
using the root
user and call it a day.
I'm also not convinced my keyboard detection heuristic is very good. I'm essentially looking for any device that has keys and a repeat rate, which on my system only matches my keyboard.
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#define DEVROOT "/dev/input/"
#define DEVROOT_LEN 12
#define PATH_LEN (DEVROOT_LEN + NAME_MAX)
int outerr(int, const char*);
struct libevdev* open_device(int);
bool kblike(struct libevdev*);
int main(int argc, char* argv) {
DIR* dir;
struct dirent* entry;
char path[PATH_LEN];
int fd, err;
struct libevdev* dev = NULL;
struct input_event ev;
bool key, rep, alt;
if (!(dir = opendir("/dev/input"))) {
return outerr(errno, "cannot enumerate devices");
}
// look for keyboard device
while (entry = readdir(dir)) {
if (DT_CHR == entry->d_type) {
sprintf(path, "/dev/input/%s", entry->d_name);
if (-1 == (fd = open(path, O_RDONLY|O_NONBLOCK))) {
return outerr(errno, "cannot read device");
}
if (dev = open_device(fd)) {
if (kblike(dev)) break;
libevdev_free(dev);
dev = NULL;
}
}
}
closedir(dir);
// check if keyboard was found
if (dev == NULL) {
return outerr(ENODEV, "could not detect keyboard");
} else do {
err = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (err == 0 && ev.type == EV_KEY) switch (ev.code) {
case KEY_LEFTALT:
alt = ev.value == 1;
break;
case KEY_X:
if (ev.value == 1 && alt) system("xterm");
break;
}
} while (err == 1 || err == 0 || err == -EAGAIN);
return 0;
}
int outerr(int errnum, const char* msg) {
fprintf(stderr, "%s (%s)n", msg, strerror(errnum));
return errnum;
}
bool kblike(struct libevdev* dev) {
return libevdev_has_event_type(dev, EV_KEY)
&& libevdev_has_event_type(dev, EV_REP);
}
struct libevdev* open_device(int fd) {
struct libevdev* dev = libevdev_new();
int err;
if (dev == NULL) {
errno = ENOMEM;
} else if (0 > (err = libevdev_set_fd(dev, fd))) {
libevdev_free(dev);
dev = NULL;
errno = -err;
}
return dev;
}
add a comment |
up vote
1
down vote
After much research and experimentation, it looks like libevdev
is maybe the right tool. I developed the program below as a proof-of-concept to bind Alt+X
to launch xterm
.
Unfortunately, it has to be run as root, so I'm thinking I need to somehow tie this into the local desktop session. For my purposes, it's probably good enough to just setuid
using the root
user and call it a day.
I'm also not convinced my keyboard detection heuristic is very good. I'm essentially looking for any device that has keys and a repeat rate, which on my system only matches my keyboard.
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#define DEVROOT "/dev/input/"
#define DEVROOT_LEN 12
#define PATH_LEN (DEVROOT_LEN + NAME_MAX)
int outerr(int, const char*);
struct libevdev* open_device(int);
bool kblike(struct libevdev*);
int main(int argc, char* argv) {
DIR* dir;
struct dirent* entry;
char path[PATH_LEN];
int fd, err;
struct libevdev* dev = NULL;
struct input_event ev;
bool key, rep, alt;
if (!(dir = opendir("/dev/input"))) {
return outerr(errno, "cannot enumerate devices");
}
// look for keyboard device
while (entry = readdir(dir)) {
if (DT_CHR == entry->d_type) {
sprintf(path, "/dev/input/%s", entry->d_name);
if (-1 == (fd = open(path, O_RDONLY|O_NONBLOCK))) {
return outerr(errno, "cannot read device");
}
if (dev = open_device(fd)) {
if (kblike(dev)) break;
libevdev_free(dev);
dev = NULL;
}
}
}
closedir(dir);
// check if keyboard was found
if (dev == NULL) {
return outerr(ENODEV, "could not detect keyboard");
} else do {
err = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (err == 0 && ev.type == EV_KEY) switch (ev.code) {
case KEY_LEFTALT:
alt = ev.value == 1;
break;
case KEY_X:
if (ev.value == 1 && alt) system("xterm");
break;
}
} while (err == 1 || err == 0 || err == -EAGAIN);
return 0;
}
int outerr(int errnum, const char* msg) {
fprintf(stderr, "%s (%s)n", msg, strerror(errnum));
return errnum;
}
bool kblike(struct libevdev* dev) {
return libevdev_has_event_type(dev, EV_KEY)
&& libevdev_has_event_type(dev, EV_REP);
}
struct libevdev* open_device(int fd) {
struct libevdev* dev = libevdev_new();
int err;
if (dev == NULL) {
errno = ENOMEM;
} else if (0 > (err = libevdev_set_fd(dev, fd))) {
libevdev_free(dev);
dev = NULL;
errno = -err;
}
return dev;
}
add a comment |
up vote
1
down vote
up vote
1
down vote
After much research and experimentation, it looks like libevdev
is maybe the right tool. I developed the program below as a proof-of-concept to bind Alt+X
to launch xterm
.
Unfortunately, it has to be run as root, so I'm thinking I need to somehow tie this into the local desktop session. For my purposes, it's probably good enough to just setuid
using the root
user and call it a day.
I'm also not convinced my keyboard detection heuristic is very good. I'm essentially looking for any device that has keys and a repeat rate, which on my system only matches my keyboard.
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#define DEVROOT "/dev/input/"
#define DEVROOT_LEN 12
#define PATH_LEN (DEVROOT_LEN + NAME_MAX)
int outerr(int, const char*);
struct libevdev* open_device(int);
bool kblike(struct libevdev*);
int main(int argc, char* argv) {
DIR* dir;
struct dirent* entry;
char path[PATH_LEN];
int fd, err;
struct libevdev* dev = NULL;
struct input_event ev;
bool key, rep, alt;
if (!(dir = opendir("/dev/input"))) {
return outerr(errno, "cannot enumerate devices");
}
// look for keyboard device
while (entry = readdir(dir)) {
if (DT_CHR == entry->d_type) {
sprintf(path, "/dev/input/%s", entry->d_name);
if (-1 == (fd = open(path, O_RDONLY|O_NONBLOCK))) {
return outerr(errno, "cannot read device");
}
if (dev = open_device(fd)) {
if (kblike(dev)) break;
libevdev_free(dev);
dev = NULL;
}
}
}
closedir(dir);
// check if keyboard was found
if (dev == NULL) {
return outerr(ENODEV, "could not detect keyboard");
} else do {
err = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (err == 0 && ev.type == EV_KEY) switch (ev.code) {
case KEY_LEFTALT:
alt = ev.value == 1;
break;
case KEY_X:
if (ev.value == 1 && alt) system("xterm");
break;
}
} while (err == 1 || err == 0 || err == -EAGAIN);
return 0;
}
int outerr(int errnum, const char* msg) {
fprintf(stderr, "%s (%s)n", msg, strerror(errnum));
return errnum;
}
bool kblike(struct libevdev* dev) {
return libevdev_has_event_type(dev, EV_KEY)
&& libevdev_has_event_type(dev, EV_REP);
}
struct libevdev* open_device(int fd) {
struct libevdev* dev = libevdev_new();
int err;
if (dev == NULL) {
errno = ENOMEM;
} else if (0 > (err = libevdev_set_fd(dev, fd))) {
libevdev_free(dev);
dev = NULL;
errno = -err;
}
return dev;
}
After much research and experimentation, it looks like libevdev
is maybe the right tool. I developed the program below as a proof-of-concept to bind Alt+X
to launch xterm
.
Unfortunately, it has to be run as root, so I'm thinking I need to somehow tie this into the local desktop session. For my purposes, it's probably good enough to just setuid
using the root
user and call it a day.
I'm also not convinced my keyboard detection heuristic is very good. I'm essentially looking for any device that has keys and a repeat rate, which on my system only matches my keyboard.
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#define DEVROOT "/dev/input/"
#define DEVROOT_LEN 12
#define PATH_LEN (DEVROOT_LEN + NAME_MAX)
int outerr(int, const char*);
struct libevdev* open_device(int);
bool kblike(struct libevdev*);
int main(int argc, char* argv) {
DIR* dir;
struct dirent* entry;
char path[PATH_LEN];
int fd, err;
struct libevdev* dev = NULL;
struct input_event ev;
bool key, rep, alt;
if (!(dir = opendir("/dev/input"))) {
return outerr(errno, "cannot enumerate devices");
}
// look for keyboard device
while (entry = readdir(dir)) {
if (DT_CHR == entry->d_type) {
sprintf(path, "/dev/input/%s", entry->d_name);
if (-1 == (fd = open(path, O_RDONLY|O_NONBLOCK))) {
return outerr(errno, "cannot read device");
}
if (dev = open_device(fd)) {
if (kblike(dev)) break;
libevdev_free(dev);
dev = NULL;
}
}
}
closedir(dir);
// check if keyboard was found
if (dev == NULL) {
return outerr(ENODEV, "could not detect keyboard");
} else do {
err = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (err == 0 && ev.type == EV_KEY) switch (ev.code) {
case KEY_LEFTALT:
alt = ev.value == 1;
break;
case KEY_X:
if (ev.value == 1 && alt) system("xterm");
break;
}
} while (err == 1 || err == 0 || err == -EAGAIN);
return 0;
}
int outerr(int errnum, const char* msg) {
fprintf(stderr, "%s (%s)n", msg, strerror(errnum));
return errnum;
}
bool kblike(struct libevdev* dev) {
return libevdev_has_event_type(dev, EV_KEY)
&& libevdev_has_event_type(dev, EV_REP);
}
struct libevdev* open_device(int fd) {
struct libevdev* dev = libevdev_new();
int err;
if (dev == NULL) {
errno = ENOMEM;
} else if (0 > (err = libevdev_set_fd(dev, fd))) {
libevdev_free(dev);
dev = NULL;
errno = -err;
}
return dev;
}
answered Nov 12 at 4:06
rich remer
2,0842333
2,0842333
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53212610%2fcreate-wayland-desktop-environment-that-simply-binds-keyboard-shortcuts%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown