Implement hide-on-modifier
This commit is contained in:
parent
84d7da0acf
commit
53ec74a4ab
|
@ -15,6 +15,7 @@ LDFLAGS += -lev
|
||||||
LDFLAGS += -lyajl
|
LDFLAGS += -lyajl
|
||||||
LDFLAGS += -lxcb
|
LDFLAGS += -lxcb
|
||||||
LDFLAGS += -lxcb-atom
|
LDFLAGS += -lxcb-atom
|
||||||
|
LDFLAGS += -lX11
|
||||||
LDFLAGS += -L/usr/local/lib
|
LDFLAGS += -L/usr/local/lib
|
||||||
|
|
||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
|
|
135
i3bar/src/xcb.c
135
i3bar/src/xcb.c
|
@ -13,10 +13,16 @@
|
||||||
#include <xcb/xcb_event.h>
|
#include <xcb/xcb_event.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <i3/ipc.h>
|
#include <i3/ipc.h>
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#include <X11/extensions/XKB.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
/* We save the Atoms in an easy to access array, indexed by an enum */
|
/* We save the Atoms in an easy to access array, indexed by an enum */
|
||||||
|
@ -36,10 +42,15 @@ xcb_screen_t *xcb_screens;
|
||||||
xcb_window_t xcb_root;
|
xcb_window_t xcb_root;
|
||||||
xcb_font_t xcb_font;
|
xcb_font_t xcb_font;
|
||||||
|
|
||||||
|
Display *xkb_dpy;
|
||||||
|
int xkb_event_base;
|
||||||
|
int mod_pressed;
|
||||||
|
|
||||||
/* Event-Watchers, to interact with the user */
|
/* Event-Watchers, to interact with the user */
|
||||||
ev_prepare *xcb_prep;
|
ev_prepare *xcb_prep;
|
||||||
ev_check *xcb_chk;
|
ev_check *xcb_chk;
|
||||||
ev_io *xcb_io;
|
ev_io *xcb_io;
|
||||||
|
ev_io *xkb_io;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts a colorstring to a colorpixel as expected from xcb_change_gc.
|
* Converts a colorstring to a colorpixel as expected from xcb_change_gc.
|
||||||
|
@ -56,6 +67,54 @@ uint32_t get_colorpixel(const char *s) {
|
||||||
return (r << 16 | g << 8 | b);
|
return (r << 16 | g << 8 | b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hides all bars (unmaps them)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void hide_bars() {
|
||||||
|
i3_output *walk;
|
||||||
|
SLIST_FOREACH(walk, outputs, slist) {
|
||||||
|
xcb_unmap_window(xcb_connection, walk->bar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unhides all bars (maps them)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void unhide_bars() {
|
||||||
|
i3_output *walk;
|
||||||
|
xcb_void_cookie_t cookie;
|
||||||
|
xcb_generic_error_t *err;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t values[4];
|
||||||
|
|
||||||
|
SLIST_FOREACH(walk, outputs, slist) {
|
||||||
|
if (walk->bar == XCB_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mask = XCB_CONFIG_WINDOW_X |
|
||||||
|
XCB_CONFIG_WINDOW_Y |
|
||||||
|
XCB_CONFIG_WINDOW_WIDTH |
|
||||||
|
XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
|
values[0] = walk->rect.x;
|
||||||
|
values[1] = walk->rect.y + walk->rect.h - font_height - 6;
|
||||||
|
values[2] = walk->rect.w;
|
||||||
|
values[3] = font_height + 6;
|
||||||
|
printf("Reconfiguring Window for output %s to %d,%d\n", walk->name, values[0], values[1]);
|
||||||
|
cookie = xcb_configure_window_checked(xcb_connection,
|
||||||
|
walk->bar,
|
||||||
|
mask,
|
||||||
|
values);
|
||||||
|
|
||||||
|
if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
|
||||||
|
printf("ERROR: Could not reconfigure window. XCB-errorcode: %d\n", err->error_code);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
xcb_map_window(xcb_connection, walk->bar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle a button-press-event (i.c. a mouse click on one of our bars).
|
* Handle a button-press-event (i.c. a mouse click on one of our bars).
|
||||||
* We determine, wether the click occured on a ws-button or if the scroll-
|
* We determine, wether the click occured on a ws-button or if the scroll-
|
||||||
|
@ -175,6 +234,45 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
|
||||||
void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to bind to the modifier per XKB. Sadly, XCB does not implement this
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void xkb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
||||||
|
XkbEvent ev;
|
||||||
|
int modstate;
|
||||||
|
|
||||||
|
printf("Got XKB-Event!\n");
|
||||||
|
|
||||||
|
while (XPending(xkb_dpy)) {
|
||||||
|
XNextEvent(xkb_dpy, (XEvent*)&ev);
|
||||||
|
|
||||||
|
if (ev.type != xkb_event_base) {
|
||||||
|
printf("ERROR: No Xkb-Event!\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.any.xkb_type != XkbStateNotify) {
|
||||||
|
printf("ERROR: No State Notify!\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int mods = ev.state.mods;
|
||||||
|
modstate = mods & Mod4Mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modstate != mod_pressed) {
|
||||||
|
if (modstate == 0) {
|
||||||
|
printf("Mod4 got released!\n");
|
||||||
|
hide_bars();
|
||||||
|
} else {
|
||||||
|
printf("Mod4 got pressed!\n");
|
||||||
|
unhide_bars();
|
||||||
|
}
|
||||||
|
mod_pressed = modstate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the rendered width of a string with the configured font.
|
* Calculate the rendered width of a string with the configured font.
|
||||||
* The string has to be encoded in ucs2 and glyph_len has to be the length
|
* The string has to be encoded in ucs2 and glyph_len has to be the length
|
||||||
|
@ -242,18 +340,55 @@ void init_xcb(char *fontname) {
|
||||||
strlen(fontname),
|
strlen(fontname),
|
||||||
fontname);
|
fontname);
|
||||||
|
|
||||||
|
int xkb_major, xkb_minor, xkb_errbase, xkb_err;
|
||||||
|
xkb_major = XkbMajorVersion;
|
||||||
|
xkb_minor = XkbMinorVersion;
|
||||||
|
|
||||||
|
xkb_dpy = XkbOpenDisplay(":0",
|
||||||
|
&xkb_event_base,
|
||||||
|
&xkb_errbase,
|
||||||
|
&xkb_major,
|
||||||
|
&xkb_minor,
|
||||||
|
&xkb_err);
|
||||||
|
|
||||||
|
if (xkb_dpy == NULL) {
|
||||||
|
printf("ERROR: No XKB!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl(ConnectionNumber(xkb_dpy), F_SETFD, FD_CLOEXEC) == -1) {
|
||||||
|
fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i1;
|
||||||
|
if (!XkbQueryExtension(xkb_dpy, &i1, &xkb_event_base, &xkb_errbase, &xkb_major, &xkb_minor)) {
|
||||||
|
printf("ERROR: XKB not supported by X-server!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!XkbSelectEvents(xkb_dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask)) {
|
||||||
|
printf("Could not grab Key!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/* The varios Watchers to communicate with xcb */
|
/* The varios Watchers to communicate with xcb */
|
||||||
xcb_io = malloc(sizeof(ev_io));
|
xcb_io = malloc(sizeof(ev_io));
|
||||||
xcb_prep = malloc(sizeof(ev_prepare));
|
xcb_prep = malloc(sizeof(ev_prepare));
|
||||||
xcb_chk = malloc(sizeof(ev_check));
|
xcb_chk = malloc(sizeof(ev_check));
|
||||||
|
xkb_io = malloc(sizeof(ev_io));
|
||||||
|
|
||||||
ev_io_init(xcb_io, &xcb_io_cb, xcb_get_file_descriptor(xcb_connection), EV_READ);
|
ev_io_init(xcb_io, &xcb_io_cb, xcb_get_file_descriptor(xcb_connection), EV_READ);
|
||||||
ev_prepare_init(xcb_prep, &xcb_prep_cb);
|
ev_prepare_init(xcb_prep, &xcb_prep_cb);
|
||||||
ev_check_init(xcb_chk, &xcb_chk_cb);
|
ev_check_init(xcb_chk, &xcb_chk_cb);
|
||||||
|
ev_io_init(xkb_io, &xkb_io_cb, ConnectionNumber(xkb_dpy), EV_READ);
|
||||||
|
|
||||||
ev_io_start(main_loop, xcb_io);
|
ev_io_start(main_loop, xcb_io);
|
||||||
ev_prepare_start(main_loop, xcb_prep);
|
ev_prepare_start(main_loop, xcb_prep);
|
||||||
ev_check_start(main_loop, xcb_chk);
|
ev_check_start(main_loop, xcb_chk);
|
||||||
|
ev_io_start(main_loop, xkb_io);
|
||||||
|
|
||||||
|
XFlush(xkb_dpy);
|
||||||
|
|
||||||
/* Now we get the atoms and save them in a nice data-structure */
|
/* Now we get the atoms and save them in a nice data-structure */
|
||||||
get_atoms();
|
get_atoms();
|
||||||
|
|
Loading…
Reference in New Issue