Add indicator to show current indicator using libxkbcommon

The indicator is based on XCB-XKB and `libxkbcommon`. It can be tested
using the following configuration:

```
bar-list = ["bar"];
bar: {
  position: "top";
  block-list: ["ya_xkb"];
  ya_xkb: {
    exec: "YABAR_KEYBOARD_LAYOUT";
    interval: 1;
  };
}
```

The followinng new dependencies have been introduced:

- libxkbcommon-dev
- libxkbcommon-x11-dev
- libxcb-xkb-dev

Both work with libxcb and allow the usage of XKB through an XCB session.
In this case the session `ya.c` created by `src/ya_exec.c` can be used
for this indicator, so no extra X11 logic is needed.
This commit is contained in:
Maximilian Bosch 2017-10-26 22:18:26 +02:00
parent cbecc7766e
commit 5aa1fb5eb5
No known key found for this signature in database
GPG key ID: 091DBF4D1FC46B8E
8 changed files with 79 additions and 7 deletions

View file

@ -19,6 +19,9 @@ matrix:
- libasound2-dev
- libiw-dev
- wget
- libxkbcommon-dev
- libxkbcommon-x11-dev
- libxcb-xkb-dev
before_install:
- wget https://github.com/acrisci/playerctl/releases/download/v0.5.0/playerctl-0.5.0_amd64.deb -O playerctl.deb
- sudo dpkg -i playerctl.deb
@ -37,6 +40,9 @@ matrix:
- libxcb-icccm4-dev
- libasound2-dev
- libiw-dev
- libxkbcommon-dev
- libxkbcommon-x11-dev
- libxcb-xkb-dev
- script: make docs
language: generic
addons:

View file

@ -12,7 +12,7 @@ DEPS += playerctl-1.0
endif
LDFLAGS += -flto -O2
LDLIBS += -liw -lxcb -lpthread -lxcb-randr -lxcb-ewmh -lxcb-icccm -lm `pkg-config --libs $(DEPS)`
LDLIBS += -liw -lxcb -lpthread -lxcb-randr -lxcb-ewmh -lxcb-icccm -lxkbcommon -lxkbcommon-x11 -lxcb-xkb -lm `pkg-config --libs $(DEPS)`
PROGRAM := yabar
DOCS := $(PROGRAM).1
PREFIX ?= /usr

View file

@ -48,8 +48,8 @@ AUR: [yabar](https://aur.archlinux.org/packages/yabar/) and [yabar-git](https://
### From Source
Yabar initially requires a C compiler (e.g. gcc or clang), make as well as the libraries libconfig, cairo, pango and alsa. The feature `DYA_INTERNAL_EWMH` in `Makefile` additionaly xcb-ewmh (or xcb-util-wm in some distros) and the feature `-DYA_ICON` requires gdk-pixbuf2. These dependencies can be installed through your distribution's package manager:
* Fedora: `dnf install libconfig-devel cairo-devel pango-devel gdk-pixbuf2-devel alsa-lib-devel xcb-util-wm-devel wireless-tools-devel`
* Debian / Ubuntu: `apt-get install libcairo2-dev libpango1.0-dev libconfig-dev libxcb-randr0-dev libxcb-ewmh-dev libxcb-icccm4-dev libgdk-pixbuf2.0-dev libasound2-dev libiw-dev`
* Fedora: `dnf install libconfig-devel cairo-devel pango-devel gdk-pixbuf2-devel alsa-lib-devel xcb-util-wm-devel wireless-tools-devel libxkbcommon-devel libxkbcommon-x11-devel`
* Debian / Ubuntu: `apt-get install libcairo2-dev libpango1.0-dev libconfig-dev libxcb-randr0-dev libxcb-ewmh-dev libxcb-icccm4-dev libgdk-pixbuf2.0-dev libasound2-dev libiw-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-xkb-dev`
You can install yabar as follows:

View file

@ -368,6 +368,11 @@ internal-option1: "/dev/sda";
** "/dev/mapper/vgc-" all mounted logical volumes of volume group vgc
** "/dev" all mounted partitions / logical volumes
* *YABAR_KEYBOARD_LAYOUT* - *XKB layout*: Retrieves the uppercased layout string from libxkb. Example:
---
exec: "YABAR_KEYBOARD_LAYOUT";
---
LICENSE
-------
Yabar is licensed under the *MIT license*. For more info check out the file 'LICENSE'.

View file

@ -205,4 +205,8 @@ topbar:{
type: "periodic";
internal-option1: "spotify";
}
keyboard: {
exec: "YABAR_KEYBOARD_LAYOUT";
interval: 1;
}
}

View file

@ -120,15 +120,15 @@ enum {
#ifdef YA_INTERNAL_EWMH
#ifdef PLAYERCTL
#define YA_INTERNAL_LEN 17
#define YA_INTERNAL_LEN 18
#else
#define YA_INTERNAL_LEN 16
#define YA_INTERNAL_LEN 17
#endif
#else
#ifdef PLAYERCTL
#define YA_INTERNAL_LEN 15
#define YA_INTERNAL_LEN 16
#else
#define YA_INTERNAL_LEN 14
#define YA_INTERNAL_LEN 15
#endif
#endif
enum {
@ -146,6 +146,7 @@ enum {
YA_INT_VOLUME,
YA_INT_WIFI,
YA_INT_DISKSPACE,
YA_INT_KEYBOARD_LAYOUT,
#ifdef PLAYERCTL
YA_INT_SONG,
#endif

View file

@ -5,5 +5,6 @@ with import <nixpkgs>{}; stdenv.mkDerivation {
buildInputs = [
cairo gdk_pixbuf libconfig pango pkgconfig xorg.xcbutilwm docbook_xsl
alsaLib wirelesstools asciidoc libxslt makeWrapper libxml2 playerctl
libxkbcommon
];
}

View file

@ -22,6 +22,7 @@ void ya_int_battery(ya_block_t *blk);
void ya_int_volume(ya_block_t *blk);
void ya_int_wifi(ya_block_t *blk);
void ya_int_diskspace(ya_block_t *blk);
void ya_int_keyboard_layout(ya_block_t *blk);
#ifdef PLAYERCTL
void ya_int_song(ya_block_t *blk);
@ -45,6 +46,7 @@ struct reserved_blk ya_reserved_blks[YA_INTERNAL_LEN] = {
{"YABAR_VOLUME", ya_int_volume},
{"YABAR_WIFI", ya_int_wifi},
{"YABAR_DISKSPACE", ya_int_diskspace},
{"YABAR_KEYBOARD_LAYOUT", ya_int_keyboard_layout},
#ifdef YA_INTERNAL_EWMH
{"YABAR_TITLE", NULL},
{"YABAR_WORKSPACE", NULL}
@ -136,6 +138,59 @@ __attribute__ ((gnu_inline)) inline void ya_setup_prefix_suffix(ya_block_t *blk,
}
}
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-x11.h>
#include <xcb/xkb.h>
void ya_int_keyboard_layout(ya_block_t *blk) {
char *startstr = blk->buf;
size_t prflen = 0, suflen = 0;
ya_setup_prefix_suffix(blk, &prflen, &suflen, &startstr);
struct xkb_keymap *keymap;
struct xkb_state *state;
int32_t device_id;
struct xkb_context *ctx;
const char* name;
xkb_layout_index_t layout;
static uint8_t xkb_base_event;
static uint8_t xkb_base_error;
int ret = xkb_x11_setup_xkb_extension(
ya.c,
XKB_X11_MIN_MAJOR_XKB_VERSION,
XKB_X11_MIN_MINOR_XKB_VERSION,
0,
NULL,
NULL,
&xkb_base_event,
&xkb_base_error);
if (!ret)
ya_block_error(blk, "Unable to register XKB extension!");
ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!ctx) ya_block_error(blk, "Cannot create new XCB context!");
device_id = xkb_x11_get_core_keyboard_device_id(ya.c);
if (device_id == -1) ya_block_error(blk, "Empty reply, cannot get device id!");
while (1) {
keymap = xkb_x11_keymap_new_from_device(ctx, ya.c, device_id, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!keymap) ya_block_error(blk, "Cannot find keymap!");
state = xkb_state_new(keymap);
layout = xkb_state_serialize_layout(state, XKB_STATE_LAYOUT_EFFECTIVE);
name = xkb_keymap_layout_get_name(keymap, layout);
sprintf(startstr, "%s", name);
xkb_state_unref(state);
xkb_keymap_unref(keymap);
ya_draw_pango_text(blk);
sleep(blk->sleep);
}
}
#ifdef PLAYERCTL
#include <playerctl/playerctl.h>
#define CHECK_PLAYER_ERROR(PREFIX) \