tnew tool: slw - wmutils - X windows manipulation utilities
(HTM) git clone git://z3bra.org/wmutils
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit f946be83a69bda18f335cec80e5d244b3b884b2a
(DIR) parent 8d7082a227ba67ac6635420ee343f7d17a90fed9
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Mon, 14 Oct 2019 12:04:02 +0200
new tool: slw
This tool grabs the cursor and wait for a button press/release event.
When the event is received, the ID of the window that received the event
will be printed to stdout.
This is useful to select a random window interactively using the mouse
pointer.
Note: this adds a new "dependency" on the xcb-utils cursor library.
Diffstat:
M Makefile | 3 ++-
M README.md | 1 +
M config.mk | 4 ++--
M man/Makefile | 1 +
A man/slw.1 | 17 +++++++++++++++++
A slw.c | 59 +++++++++++++++++++++++++++++++
6 files changed, 82 insertions(+), 3 deletions(-)
---
(DIR) diff --git a/Makefile b/Makefile
t@@ -14,7 +14,8 @@ SRC = \
wrs.c \
chwb.c \
ignw.c \
- wmp.c
+ wmp.c \
+ slw.c
OBJ = $(SRC:.c=.o)
BIN = $(SRC:.c=)
(DIR) diff --git a/README.md b/README.md
t@@ -38,6 +38,7 @@ without being added to this list, so take it with a grain of salt.
* lsw - list windows
* mapw - map/unmap windows
* pfw - print focused window
+* slw - select window interactively
* wattr - show window's attributes
* wmp - move the mouse pointer
* wmv - move a window
(DIR) diff --git a/config.mk b/config.mk
t@@ -4,6 +4,6 @@ MANPREFIX = $(PREFIX)/man
CC = cc
LD = $(CC)
-CFLAGS = -std=c99 -pedantic -Wall -Os
-LDFLAGS = -lxcb -lxcb-util
+CFLAGS = -std=c99 -pedantic -Wall -Os -I/usr/X11R6/include
+LDFLAGS = -lxcb -lxcb-util -lxcb-cursor -L/usr/X11R6/lib
(DIR) diff --git a/man/Makefile b/man/Makefile
t@@ -14,6 +14,7 @@ MAN = \
chwb.1 \
ignw.1 \
wmp.1 \
+ slw.1 \
wmutils.1
.POSIX:
(DIR) diff --git a/man/slw.1 b/man/slw.1
t@@ -0,0 +1,17 @@
+.Dd October 14, 2019
+.Dt SLW 1
+.Os wmutils
+.Sh NAME
+.Nm slw
+.Nd select window interactively
+.Sh SYNOPSIS
+.Nm slw
+.Sh DESCRIPTION
+Wait for a button press event and print the window ID that got the
+event to
+.Dv stdout .
+.Sh ENVIRONMENT
+.Nm
+acts on the X display specified by the
+.Ev DISPLAY
+variable.
(DIR) diff --git a/slw.c b/slw.c
t@@ -0,0 +1,59 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#include <xcb/xcb_cursor.h>
+
+#include "util.h"
+
+static xcb_connection_t *conn;
+static xcb_screen_t *scr;
+
+static xcb_window_t
+select_window(void)
+{
+ uint32_t val[] = { XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE };
+ xcb_window_t w = 0;
+ xcb_grab_pointer_cookie_t c;
+ xcb_grab_pointer_reply_t *r;
+ xcb_generic_event_t *e;
+
+ c = xcb_grab_pointer(conn, 0, scr->root,
+ XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE,
+ XCB_CURRENT_TIME);
+
+ r = xcb_grab_pointer_reply(conn, c, NULL);
+ if (!r || r->status != XCB_GRAB_STATUS_SUCCESS)
+ errx(1, "couldn't grab pointer");
+
+ xcb_change_window_attributes(conn, scr->root, XCB_CW_EVENT_MASK, val);
+ xcb_flush(conn);
+
+ for (;;) {
+ e = xcb_wait_for_event(conn);
+ switch ((e->response_type & ~0x80)) {
+ case XCB_BUTTON_PRESS:
+ w = ((xcb_button_press_event_t*)e)->child;
+ break;
+ case XCB_BUTTON_RELEASE:
+ return w;
+ break;
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ init_xcb(&conn);
+ get_screen(conn, &scr);
+
+ printf("0x%08x\n", select_window());
+
+ kill_xcb(&conn);
+ return 0;
+}