├── LICENSE ├── Makefile ├── README.md ├── arg.h ├── chwb2.c ├── chwn.c ├── config.mk ├── man ├── Makefile ├── chwb2.1 ├── chwn.1 ├── wew.1 ├── wname.1 ├── xmmv.1 └── xmrs.1 ├── util.c ├── util.h ├── wew.c ├── wname.c ├── xmmv.c └── xmrs.c /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2014-2016 brosephs , 4 | 5 | 6 | Permission to use, copy, modify, and distribute this software for any 7 | purpose with or without fee is hereby granted, provided that the above 8 | copyright notice and this permission notice appear in all copies. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 11 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 12 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 13 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 15 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | PERFORMANCE OF THIS SOFTWARE. 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include config.mk 2 | 3 | HDR = arg.h util.h 4 | SRC = \ 5 | wew.c \ 6 | chwb2.c \ 7 | wname.c \ 8 | xmmv.c \ 9 | xmrs.c \ 10 | chwn.c 11 | 12 | OBJ = $(SRC:.c=.o) 13 | BIN = $(SRC:.c=) 14 | 15 | .POSIX: 16 | 17 | all: binutils 18 | 19 | binutils: $(BIN) 20 | 21 | manpages: 22 | cd man; $(MAKE) $(MFLAGS) 23 | 24 | $(OBJ): $(HDR) util.o 25 | 26 | .o: 27 | @echo "LD $@" 28 | @$(LD) $< util.o -o $@ $(LDFLAGS) 29 | 30 | .c.o: 31 | @echo "CC $<" 32 | @$(CC) -c $< -o $@ $(CFLAGS) 33 | 34 | install: $(BIN) 35 | mkdir -p $(DESTDIR)$(PREFIX)/bin/ 36 | cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin/ 37 | cd man; $(MAKE) $(MFLAGS) install 38 | 39 | uninstall: 40 | @echo "uninstalling binaries" 41 | @for util in $(BIN); do \ 42 | rm -f $(DESTDIR)$(PREFIX)/bin/$$util; \ 43 | done 44 | cd man; $(MAKE) $(MFLAGS) uninstall 45 | 46 | clean: 47 | rm -f $(OBJ) $(BIN) util.o 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | wmutils' opt 2 | ============= 3 | 4 | opt is a set of optional utilities meant to accompany 5 | [core](https://github.com/wmutils/core). 6 | 7 | Just as the core programs, each utility does one job 8 | and does it well, like dealing with window events or names. 9 | 10 | utilities 11 | --------- 12 | 13 | opt has less utilities than core, here is a little overview: 14 | 15 | * chwb2 - control two different window borders 16 | * wew - print window events 17 | * wname - print a window's name 18 | * xmmv - move a window with the mouse 19 | * xmrs - resize a window with the mouse 20 | 21 | For more information, refer to the programs manpages. 22 | 23 | dependencies 24 | ------------ 25 | 26 | Like core, opt depends only on the XCB library. 27 | 28 | license 29 | ------- 30 | 31 | This project and all its code is licensed under the [ISC](http://www.openbsd.org/policy.html) 32 | license. See the LICENSE file. 33 | 34 | build & install 35 | --------------- 36 | 37 | $ make 38 | # make install 39 | 40 | In the file config.mk you can override build options, 41 | such as the compiler flags or the installation path. 42 | -------------------------------------------------------------------------------- /arg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copy me if you can. 3 | * by 20h 4 | */ 5 | 6 | #ifndef ARG_H__ 7 | #define ARG_H__ 8 | 9 | extern char *argv0; 10 | 11 | /* use main(int argc, char *argv[]) */ 12 | #define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ 13 | argv[0] && argv[0][1]\ 14 | && argv[0][0] == '-';\ 15 | argc--, argv++) {\ 16 | char argc_;\ 17 | char **argv_;\ 18 | int brk_;\ 19 | if (argv[0][1] == '-' && argv[0][2] == '\0') {\ 20 | argv++;\ 21 | argc--;\ 22 | break;\ 23 | }\ 24 | for (brk_ = 0, argv[0]++, argv_ = argv;\ 25 | argv[0][0] && !brk_;\ 26 | argv[0]++) {\ 27 | if (argv_ != argv)\ 28 | break;\ 29 | argc_ = argv[0][0];\ 30 | switch (argc_) 31 | 32 | /* Handles obsolete -NUM syntax */ 33 | #define ARGNUM case '0':\ 34 | case '1':\ 35 | case '2':\ 36 | case '3':\ 37 | case '4':\ 38 | case '5':\ 39 | case '6':\ 40 | case '7':\ 41 | case '8':\ 42 | case '9' 43 | 44 | #define ARGEND }\ 45 | } 46 | 47 | #define ARGC() argc_ 48 | 49 | #define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) 50 | 51 | #define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ 52 | ((x), abort(), (char *)0) :\ 53 | (brk_ = 1, (argv[0][1] != '\0')?\ 54 | (&argv[0][1]) :\ 55 | (argc--, argv++, argv[0]))) 56 | 57 | #define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ 58 | (char *)0 :\ 59 | (brk_ = 1, (argv[0][1] != '\0')?\ 60 | (&argv[0][1]) :\ 61 | (argc--, argv++, argv[0]))) 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /chwb2.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014, Broseph 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "arg.h" 24 | #include "util.h" 25 | 26 | char *argv0; 27 | static xcb_connection_t *conn; 28 | 29 | static void usage (char *name); 30 | static void set2border (xcb_window_t, int, int, int, int); 31 | 32 | static void 33 | usage (char *name) 34 | { 35 | fprintf(stderr, "usage: %s <-I color> <-O color> <-i size> <-o size> [wid...]\n", name); 36 | exit(1); 37 | } 38 | 39 | static void 40 | set2border (win, oc, os, ic, is) 41 | xcb_window_t win; 42 | int oc; /* outer color */ 43 | int os; /* outer size */ 44 | int ic; /* inner color */ 45 | int is; /* inner size */ 46 | { 47 | if (os < 0 || oc < 0 || is < 0 || ic < 0) 48 | return; 49 | 50 | uint32_t values[1]; 51 | short w, h, b, o; 52 | 53 | xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, 54 | xcb_get_geometry(conn, win), NULL); 55 | 56 | if (geom == NULL) 57 | return; 58 | 59 | if (is + os > geom->border_width) 60 | warnx("warning: pixmap is greater than border size"); 61 | 62 | oc |= 0xff << 24; 63 | os |= 0xff << 24; 64 | ic |= 0xff << 24; 65 | is |= 0xff << 24; 66 | 67 | w = (short)geom->width; 68 | h = (short)geom->height; 69 | b = (unsigned short)is+os; 70 | o = (unsigned short)os; 71 | 72 | xcb_rectangle_t inner[] = { 73 | /* you're not supposed to understand this. */ 74 | { w,0,b-o ,h+b- o }, 75 | { w+b +o, 0, b -o, h+ b - o}, 76 | { 0,h ,w+b -o,b- o }, 77 | { 0,h +b+ o, w+ b- o, b -o}, 78 | { w+b+o,b +h +o,b,b} 79 | }; 80 | 81 | xcb_rectangle_t outer[] = { 82 | {w + b - o, 0, o, h + b * 2}, 83 | {w + b, 0, o, h + b * 2}, 84 | {0, h + b - o, w + b * 2, o}, 85 | {0, h + b, w + b * 2, o}, 86 | {1, 1, 1, 1} 87 | }; 88 | 89 | xcb_pixmap_t pmap = xcb_generate_id(conn); 90 | xcb_create_pixmap(conn, geom->depth, pmap, win, 91 | geom->width + (b*2), 92 | geom->height + (b*2)); 93 | xcb_gcontext_t gc = xcb_generate_id(conn); 94 | xcb_create_gc(conn, gc, pmap, 0, NULL); 95 | 96 | values[0] = oc; 97 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 98 | xcb_poly_fill_rectangle(conn, pmap, gc, 5, outer); 99 | 100 | values[0] = ic; 101 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 102 | xcb_poly_fill_rectangle(conn, pmap, gc, 5, inner); 103 | 104 | values[0] = pmap; 105 | xcb_change_window_attributes(conn, win, XCB_CW_BORDER_PIXMAP, values); 106 | 107 | xcb_free_pixmap(conn, pmap); 108 | xcb_free_gc(conn, gc); 109 | } 110 | 111 | int 112 | main (int argc, char **argv) 113 | { 114 | int oc,os,ic,is; 115 | 116 | if (argc < 2) 117 | usage(argv[0]); 118 | 119 | oc = os = ic = is = -1; 120 | ARGBEGIN { 121 | case 'I': 122 | ic = strtoul(EARGF(usage(argv0)), NULL, 16); 123 | break; 124 | case 'O': 125 | oc = strtoul(EARGF(usage(argv0)), NULL, 16); 126 | break; 127 | case 'i': 128 | is = strtoul(EARGF(usage(argv0)), NULL, 10); 129 | break; 130 | case 'o': 131 | os = strtoul(EARGF(usage(argv0)), NULL, 10); 132 | break; 133 | case 'h': 134 | usage(argv0); 135 | /* NOTREACHED */ 136 | } ARGEND 137 | 138 | init_xcb(&conn); 139 | 140 | /* assume remaining arguments are windows */ 141 | while (*argv) 142 | set2border(strtoul(*argv++, NULL, 16), oc, os, ic, is); 143 | 144 | xcb_aux_sync(conn); 145 | 146 | kill_xcb(&conn); 147 | 148 | return 0; 149 | } 150 | -------------------------------------------------------------------------------- /chwn.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "arg.h" 10 | #include "util.h" 11 | 12 | static xcb_connection_t *conn; 13 | 14 | static void usage(char *); 15 | static void set_title(xcb_connection_t *, xcb_window_t, char *); 16 | 17 | static void 18 | usage(char *name) 19 | { 20 | fprintf(stderr, "usage: %s \n", name); 21 | exit(1); 22 | } 23 | 24 | void 25 | set_title(xcb_connection_t *con, xcb_window_t w, char *name) 26 | { 27 | xcb_change_property(con, XCB_PROP_MODE_REPLACE, w, XCB_ATOM_WM_NAME, 28 | XCB_ATOM_STRING, 8, strlen(name), name); 29 | xcb_flush(con); 30 | } 31 | 32 | int 33 | main(int argc, char **argv) 34 | { 35 | if (argc != 3) 36 | usage(argv[0]); 37 | 38 | init_xcb(&conn); 39 | 40 | set_title(conn, strtoul(argv[2], NULL, 16), argv[1]); 41 | 42 | kill_xcb(&conn); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | PREFIX = /usr 2 | MANPREFIX = $(PREFIX)/share/man 3 | 4 | CC = cc 5 | LD = $(CC) 6 | 7 | CFLAGS += -std=c99 -pedantic -Wall -Os 8 | LDFLAGS += -lxcb -lxcb-util 9 | -------------------------------------------------------------------------------- /man/Makefile: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | 3 | MAN = \ 4 | wew.1 \ 5 | chwb2.1 \ 6 | wname.1 \ 7 | xmmv.1 \ 8 | chwn.1 \ 9 | xmrs.1 10 | 11 | .POSIX: 12 | 13 | install: $(MAN) 14 | mkdir -p $(DESTDIR)$(MANPREFIX)/man1/ 15 | cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1/ 16 | 17 | uninstall: 18 | @echo "uninstalling manpages" 19 | @for page in $(MAN); do \ 20 | rm -f $(DESTDIR)$(MANPREFIX)/man1/$$page; \ 21 | done 22 | -------------------------------------------------------------------------------- /man/chwb2.1: -------------------------------------------------------------------------------- 1 | .Dd December 13, 2014 2 | .Dt CHWB2 1 3 | .Os wmutils 4 | .Sh NAME 5 | .Nm chwb2 6 | .Nd change window double-borders 7 | .Sh SYNOPSIS 8 | .Nm chwb2 9 | .Op Fl I Ar inner color 10 | .Op Fl O Ar outer color 11 | .Op Fl i Ar inner size 12 | .Op Fl o Ar outer size 13 | .Ar wid Op Ar ... 14 | .Sh DESCRIPTION 15 | .Nm 16 | applies a double pixmap border to 17 | .Ar wid . 18 | .Bl -tag -width Ds 19 | .It Fl I Ar inner color 20 | .It Fl O Ar outer color 21 | Set the inner/outer border color of 22 | .Ar wid 23 | to 24 | .Ar color . 25 | Colors should be passed as a hex triplet without the '#' prefix (see 26 | .Xr strtoul 3 ) 27 | in RGB format. 28 | .It Fl i Ar size 29 | .It Fl o Ar size 30 | Sets the inner/outer border width of 31 | .Ar wid 32 | to 33 | .Ar size . 34 | .El 35 | .Sh ENVIRONMENT 36 | .Nm 37 | acts on the X display specified by the 38 | .Ev DISPLAY 39 | variable. 40 | .Sh EXAMPLES 41 | Set the inner border of the current window to yellow with a black outer rim: 42 | .Dl $ chwb2 -O 000000 -I ffff00 -i 3 -o 1 $(pfw) 43 | .Sh SEE ALSO 44 | .Xr chwb 1 45 | .Xr strtoul 3 46 | -------------------------------------------------------------------------------- /man/chwn.1: -------------------------------------------------------------------------------- 1 | '\" e 2 | .Dd September 26, 2016 3 | .Dt CHWN 1 4 | .Os wmutils 5 | .Sh NAME 6 | .Nm chwn 7 | .Nd set WM_NAME atom of a window 8 | .Sh SYNOPSIS 9 | .Nm chwn 10 | .Ar name wid 11 | .Sh DESCRIPTION 12 | .Nm chwn 13 | sets the WM_NAME atom of 14 | .Ar wid 15 | to 16 | .Ar name. 17 | This is most of the time equivalent to renaming the window. 18 | .Sh ENVIRONMENT 19 | .Nm 20 | acts on the X display specified by the 21 | .Ev DISPLAY 22 | variable. 23 | -------------------------------------------------------------------------------- /man/wew.1: -------------------------------------------------------------------------------- 1 | .Dd December 17, 2014 2 | .Dt WEW 1 3 | .Os wmutils 4 | .Sh NAME 5 | .Nm wew 6 | .Nd window event watcher 7 | .Sh SYNOPSIS 8 | .Nm wew 9 | .Op Fl l 10 | .Op Fl m Ar mask 11 | .Sh DESCRIPTION 12 | .Nm 13 | is a daemon that prints X events to stdout in the form: 14 | .Pp 15 | .Bd -literral 16 | .Ar event wid [args] 17 | .Ed 18 | .Pp 19 | See section EVENT VALUES for the possible values of 20 | .Ar event . 21 | .Bl -tag -width Ds 22 | .It Fl l 23 | List event mask values 24 | .It Fl m Ar mask 25 | Set new windows event mask to 26 | .Ar mask 27 | Multiple events are registered by performing a bitwise OR of their values. 28 | (defaults to STRUCTURE_NOTIFY|ENTER_NOTIFY|FOCUS_CHANGE). The events 29 | registered on the root window cannot be modified. 30 | .El 31 | .Sh EVENT VALUES 32 | Events will be reported according to these names: 33 | .Pp 34 | .Bl -bullet -compact 35 | .It 36 | .Dv CREATE 37 | .It 38 | .Dv DESTROY 39 | .It 40 | .Dv BUTTON_PRESS 41 | .It 42 | .Dv BUTTON_RELEASE 43 | .It 44 | .Dv MOTION 45 | .It 46 | .Dv ENTER 47 | .It 48 | .Dv LEAVE 49 | .It 50 | .Dv CONFIGURE 51 | .It 52 | .Dv KEY_PRESS 53 | .It 54 | .Dv FOCUS_IN 55 | .It 56 | .Dv FOCUS_OUT 57 | .It 58 | .Dv KEYMAP 59 | .It 60 | .Dv EXPOSE 61 | .It 62 | .Dv GRAPHICS_EXPOSURE 63 | .It 64 | .Dv NO_EXPOSURE 65 | .It 66 | .Dv VISIBILITY 67 | .It 68 | .Dv UNMAP 69 | .It 70 | .Dv MAP 71 | .It 72 | .Dv MAP_REQUEST 73 | .It 74 | .Dv REPARENT 75 | .It 76 | .Dv CONFIGURE_REQUEST 77 | .It 78 | .Dv GRAVITY 79 | .It 80 | .Dv RESIZE_REQUEST 81 | .It 82 | .Dv CIRCULATE 83 | .It 84 | .Dv PROPERTY 85 | .It 86 | .Dv SELECTION_CLEAR 87 | .It 88 | .Dv SELECTION_REQUEST 89 | .It 90 | .Dv SELECTION 91 | .It 92 | .Dv COLORMAP 93 | .It 94 | .Dv CLIENT_MESSAGE 95 | .It 96 | .Dv MAPPING 97 | .El 98 | .Sh ENVIRONMENT 99 | .Nm 100 | acts on the X display specified by the 101 | .Ev DISPLAY 102 | variable. 103 | -------------------------------------------------------------------------------- /man/wname.1: -------------------------------------------------------------------------------- 1 | .Dd December 13, 2014 2 | .Dt WNAME 1 3 | .Os wmutils 4 | .Sh NAME 5 | .Nm wname 6 | .Nd print window name 7 | .Sh SYNOPSIS 8 | .Nm wname 9 | .Ar wid Op ... 10 | .Sh DESCRIPTION 11 | .Nm 12 | prints the name of the window IDs given as arguments, 13 | one name per line. 14 | .Sh ENVIRONMENT 15 | .Nm 16 | acts on the X display specified by the 17 | .Ev DISPLAY 18 | variable. 19 | -------------------------------------------------------------------------------- /man/xmmv.1: -------------------------------------------------------------------------------- 1 | .Dd June 10, 2015 2 | .Dt XMMV 1 3 | .Os wmutils 4 | .Sh NAME 5 | .Nm xmmv 6 | .Nd X mouse move 7 | .Sh SYNOPSIS 8 | .Nm 9 | .Ar 10 | .Sh DESCRIPTION 11 | .Nm 12 | moves windows with mouse, places window on keydown 13 | .Sh ENVIRONMENT 14 | .Nm 15 | acts on the X display specified by the 16 | .Ev DISPLAY 17 | variable. 18 | .Sh SEE ALSO 19 | .Xr chwb 1 , 20 | .Xr strtoul 3 21 | -------------------------------------------------------------------------------- /man/xmrs.1: -------------------------------------------------------------------------------- 1 | .Dd June 10, 2015 2 | .Dt XMRS 1 3 | .Os wmutils 4 | .Sh NAME 5 | .Nm xmrs 6 | .Nd X mouse resize 7 | .Sh SYNOPSIS 8 | .Nm 9 | .Ar 10 | .Sh DESCRIPTION 11 | .Nm 12 | resizes windows with mouse, places window on keydown 13 | .Sh ENVIRONMENT 14 | .Nm 15 | acts on the X display specified by the 16 | .Ev DISPLAY 17 | variable. 18 | .Sh SEE ALSO 19 | .Xr chwb 1 , 20 | .Xr strtoul 3 21 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "util.h" 6 | 7 | void 8 | init_xcb(xcb_connection_t **con) 9 | { 10 | *con = xcb_connect(NULL, NULL); 11 | if (xcb_connection_has_error(*con)) 12 | errx(1, "unable connect to the X server"); 13 | } 14 | 15 | void 16 | kill_xcb(xcb_connection_t **con) 17 | { 18 | if (*con) 19 | xcb_disconnect(*con); 20 | } 21 | 22 | void 23 | get_screen(xcb_connection_t *con, xcb_screen_t **scr) 24 | { 25 | *scr = xcb_setup_roots_iterator(xcb_get_setup(con)).data; 26 | if (*scr == NULL) 27 | errx(1, "unable to retrieve screen informations"); 28 | } 29 | 30 | int 31 | exists(xcb_connection_t *con, xcb_window_t w) 32 | { 33 | xcb_get_window_attributes_cookie_t c; 34 | xcb_get_window_attributes_reply_t *r; 35 | 36 | c = xcb_get_window_attributes(con, w); 37 | r = xcb_get_window_attributes_reply(con, c, NULL); 38 | 39 | if (r == NULL) 40 | return 0; 41 | 42 | return 1; 43 | } 44 | 45 | int 46 | mapped(xcb_connection_t *con, xcb_window_t w) 47 | { 48 | int ms; 49 | xcb_get_window_attributes_cookie_t c; 50 | xcb_get_window_attributes_reply_t *r; 51 | 52 | c = xcb_get_window_attributes(con, w); 53 | r = xcb_get_window_attributes_reply(con, c, NULL); 54 | 55 | if (r == NULL) 56 | return 0; 57 | 58 | ms = r->map_state; 59 | 60 | free(r); 61 | return ms == XCB_MAP_STATE_VIEWABLE; 62 | } 63 | 64 | int 65 | ignore(xcb_connection_t *con, xcb_window_t w) 66 | { 67 | int or; 68 | xcb_get_window_attributes_cookie_t c; 69 | xcb_get_window_attributes_reply_t *r; 70 | 71 | c = xcb_get_window_attributes(con, w); 72 | r = xcb_get_window_attributes_reply(con, c, NULL); 73 | 74 | if (r == NULL) 75 | return 0; 76 | 77 | or = r->override_redirect; 78 | 79 | free(r); 80 | return or; 81 | } 82 | 83 | int 84 | get_windows(xcb_connection_t *con, xcb_window_t w, xcb_window_t **l) 85 | { 86 | int childnum = 0; 87 | xcb_query_tree_cookie_t c; 88 | xcb_query_tree_reply_t *r; 89 | 90 | c = xcb_query_tree(con, w); 91 | r = xcb_query_tree_reply(con, c, NULL); 92 | if (r == NULL) 93 | errx(1, "0x%08x: no such window", w); 94 | 95 | *l = xcb_query_tree_children(r); 96 | 97 | childnum = r->children_len; 98 | free(r); 99 | 100 | return childnum; 101 | } 102 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H__ 2 | #define UTIL_H__ 3 | 4 | void init_xcb(xcb_connection_t **); 5 | void kill_xcb(xcb_connection_t **); 6 | 7 | void get_screen(xcb_connection_t *, xcb_screen_t **); 8 | int get_windows(xcb_connection_t *, xcb_window_t, xcb_window_t **); 9 | 10 | int exists(xcb_connection_t *, xcb_window_t); 11 | int mapped(xcb_connection_t *, xcb_window_t); 12 | int ignore(xcb_connection_t *, xcb_window_t); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /wew.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | #include "arg.h" 9 | 10 | void usage(char*); 11 | void list_events(void); 12 | void register_events(xcb_window_t, uint32_t); 13 | void print_event(xcb_generic_event_t*); 14 | 15 | static xcb_connection_t *conn; 16 | static xcb_screen_t *scr; 17 | static uint32_t mask = XCB_EVENT_MASK_NO_EVENT 18 | | XCB_EVENT_MASK_STRUCTURE_NOTIFY 19 | | XCB_EVENT_MASK_FOCUS_CHANGE 20 | | XCB_EVENT_MASK_ENTER_WINDOW 21 | /* | XCB_EVENT_MASK_LEAVE_WINDOW */ 22 | /* | XCB_EVENT_MASK_KEY_PRESS */ 23 | /* | XCB_EVENT_MASK_KEY_RELEASE */ 24 | /* | XCB_EVENT_MASK_BUTTON_PRESS */ 25 | /* | XCB_EVENT_MASK_BUTTON_RELEASE */ 26 | /* | XCB_EVENT_MASK_POINTER_MOTION */ 27 | /* | XCB_EVENT_MASK_POINTER_MOTION_HINT */ 28 | /* | XCB_EVENT_MASK_BUTTON_1_MOTION */ 29 | /* | XCB_EVENT_MASK_BUTTON_2_MOTION */ 30 | /* | XCB_EVENT_MASK_BUTTON_3_MOTION */ 31 | /* | XCB_EVENT_MASK_BUTTON_4_MOTION */ 32 | /* | XCB_EVENT_MASK_BUTTON_5_MOTION */ 33 | /* | XCB_EVENT_MASK_BUTTON_MOTION */ 34 | /* | XCB_EVENT_MASK_KEYMAP_STATE */ 35 | /* | XCB_EVENT_MASK_EXPOSURE */ 36 | /* | XCB_EVENT_MASK_VISIBILITY_CHANGE */ 37 | /* | XCB_EVENT_MASK_RESIZE_REDIRECT */ 38 | /* | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY */ 39 | /* | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT */ 40 | /* | XCB_EVENT_MASK_PROPERTY_CHANGE */ 41 | /* | XCB_EVENT_MASK_COLOR_MAP_CHANGE */ 42 | /* | XCB_EVENT_MASK_OWNER_GRAB_BUTTON */ 43 | ; 44 | static uint32_t rootmask = XCB_EVENT_MASK_NO_EVENT 45 | | XCB_EVENT_MASK_STRUCTURE_NOTIFY 46 | | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY 47 | | XCB_EVENT_MASK_BUTTON_PRESS 48 | | XCB_EVENT_MASK_BUTTON_RELEASE 49 | ; 50 | 51 | static const char *evname[] = { 52 | [0] = "EVENT_ERROR", 53 | [XCB_CREATE_NOTIFY] = "CREATE", 54 | [XCB_DESTROY_NOTIFY] = "DESTROY", 55 | [XCB_BUTTON_PRESS] = "BUTTON_PRESS", 56 | [XCB_BUTTON_RELEASE] = "BUTTON_RELEASE", 57 | [XCB_MOTION_NOTIFY] = "MOTION", 58 | [XCB_ENTER_NOTIFY] = "ENTER", 59 | [XCB_LEAVE_NOTIFY] = "LEAVE", 60 | [XCB_CONFIGURE_NOTIFY] = "CONFIGURE", 61 | [XCB_KEY_PRESS] = "KEY_PRESS", 62 | [XCB_FOCUS_IN] = "FOCUS_IN", 63 | [XCB_FOCUS_OUT] = "FOCUS_OUT", 64 | [XCB_KEYMAP_NOTIFY] = "KEYMAP", 65 | [XCB_EXPOSE] = "EXPOSE", 66 | [XCB_GRAPHICS_EXPOSURE] = "GRAPHICS_EXPOSURE", 67 | [XCB_NO_EXPOSURE] = "NO_EXPOSURE", 68 | [XCB_VISIBILITY_NOTIFY] = "VISIBILITY", 69 | [XCB_UNMAP_NOTIFY] = "UNMAP", 70 | [XCB_MAP_NOTIFY] = "MAP", 71 | [XCB_MAP_REQUEST] = "MAP_REQUEST", 72 | [XCB_REPARENT_NOTIFY] = "REPARENT", 73 | [XCB_CONFIGURE_REQUEST] = "CONFIGURE_REQUEST", 74 | [XCB_GRAVITY_NOTIFY] = "GRAVITY", 75 | [XCB_RESIZE_REQUEST] = "RESIZE_REQUEST", 76 | [XCB_CIRCULATE_NOTIFY] = "CIRCULATE", 77 | [XCB_PROPERTY_NOTIFY] = "PROPERTY", 78 | [XCB_SELECTION_CLEAR] = "SELECTION_CLEAR", 79 | [XCB_SELECTION_REQUEST] = "SELECTION_REQUEST", 80 | [XCB_SELECTION_NOTIFY] = "SELECTION", 81 | [XCB_COLORMAP_NOTIFY] = "COLORMAP", 82 | [XCB_CLIENT_MESSAGE] = "CLIENT_MESSAGE", 83 | [XCB_MAPPING_NOTIFY] = "MAPPING" 84 | }; 85 | 86 | void 87 | usage(char *name) 88 | { 89 | fprintf(stderr, "usage: %s [-l] [-rm ]\n", name); 90 | exit(1); 91 | } 92 | 93 | void 94 | list_events(void) 95 | { 96 | printf( 97 | "XCB_EVENT_MASK_NO_EVENT .............. 0\n" 98 | "XCB_EVENT_MASK_KEY_PRESS ............. 1\n" 99 | "XCB_EVENT_MASK_KEY_RELEASE ........... 2\n" 100 | "XCB_EVENT_MASK_BUTTON_PRESS .......... 4\n" 101 | "XCB_EVENT_MASK_BUTTON_RELEASE ........ 8\n" 102 | "XCB_EVENT_MASK_ENTER_WINDOW .......... 16\n" 103 | "XCB_EVENT_MASK_LEAVE_WINDOW .......... 32\n" 104 | "XCB_EVENT_MASK_POINTER_MOTION ........ 64\n" 105 | "XCB_EVENT_MASK_POINTER_MOTION_HINT ... 128\n" 106 | "XCB_EVENT_MASK_BUTTON_1_MOTION ....... 256\n" 107 | "XCB_EVENT_MASK_BUTTON_2_MOTION ....... 512\n" 108 | "XCB_EVENT_MASK_BUTTON_3_MOTION ....... 1024\n" 109 | "XCB_EVENT_MASK_BUTTON_4_MOTION ....... 2048\n" 110 | "XCB_EVENT_MASK_BUTTON_5_MOTION ....... 4096\n" 111 | "XCB_EVENT_MASK_BUTTON_MOTION ......... 8192\n" 112 | "XCB_EVENT_MASK_KEYMAP_STATE .......... 16384\n" 113 | "XCB_EVENT_MASK_EXPOSURE .............. 32768\n" 114 | "XCB_EVENT_MASK_VISIBILITY_CHANGE ..... 65536\n" 115 | "XCB_EVENT_MASK_STRUCTURE_NOTIFY ...... 131072\n" 116 | "XCB_EVENT_MASK_RESIZE_REDIRECT ....... 262144\n" 117 | "XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY ... 524288\n" 118 | "XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT . 1048576\n" 119 | "XCB_EVENT_MASK_FOCUS_CHANGE .......... 2097152\n" 120 | "XCB_EVENT_MASK_PROPERTY_CHANGE ....... 4194304\n" 121 | "XCB_EVENT_MASK_COLOR_MAP_CHANGE ...... 8388608\n" 122 | "XCB_EVENT_MASK_OWNER_GRAB_BUTTON ..... 16777216\n" 123 | ); 124 | } 125 | 126 | void 127 | register_events(xcb_window_t w, uint32_t m) 128 | { 129 | uint32_t val[] = { m }; 130 | 131 | xcb_change_window_attributes(conn, w, XCB_CW_EVENT_MASK, val); 132 | xcb_flush(conn); 133 | } 134 | 135 | void 136 | print_event(xcb_generic_event_t *e) 137 | { 138 | xcb_enter_notify_event_t *en; 139 | xcb_focus_in_event_t *ef; 140 | 141 | switch (e->response_type & ~0x80) { 142 | case XCB_ENTER_NOTIFY: 143 | case XCB_LEAVE_NOTIFY: 144 | en = (xcb_enter_notify_event_t *)e; 145 | if (en->mode != XCB_NOTIFY_MODE_NORMAL) 146 | return; 147 | printf("%s\t0x%08x\n", evname[e->response_type], en->event); 148 | break; 149 | 150 | case XCB_FOCUS_IN: 151 | case XCB_FOCUS_OUT: 152 | ef = (xcb_focus_in_event_t *)e; 153 | if (ef->mode != XCB_NOTIFY_MODE_NORMAL) 154 | return; 155 | printf("%s\t0x%08x\n", evname[e->response_type], ef->event); 156 | break; 157 | 158 | case XCB_CREATE_NOTIFY: 159 | case XCB_DESTROY_NOTIFY: 160 | printf("%s\t0x%08x\n", evname[e->response_type], 161 | ((xcb_create_notify_event_t*)e)->window); 162 | break; 163 | 164 | case XCB_UNMAP_NOTIFY: 165 | case XCB_MAP_NOTIFY: 166 | printf("%s\t0x%08x\n", evname[e->response_type], 167 | ((xcb_map_notify_event_t*)e)->window); 168 | break; 169 | 170 | case XCB_BUTTON_PRESS: 171 | case XCB_BUTTON_RELEASE: 172 | printf("%s\t0x%08x %d\n", evname[e->response_type], 173 | ((xcb_button_press_event_t*)e)->event, 174 | ((xcb_button_press_event_t*)e)->detail); 175 | break; 176 | 177 | /* 178 | * MOTION_NOTIFY. Be careful with this one... 179 | * It triggers ALOT! 180 | * 181 | * |\.---./|_ 182 | * (o) (°) ''--._ 183 | * / .A--. '\ 184 | * |' `. \ 185 | * / \ 186 | * /_;`|__\------(__/-\ 187 | */ 188 | case XCB_MOTION_NOTIFY: 189 | printf("%s\t0x%08x\n", evname[e->response_type], 190 | ((xcb_motion_notify_event_t*)e)->event); 191 | break; 192 | /* please... handle me ... ;_; 193 | case XCB_KEY_PRESS: 194 | case XCB_KEY_RELEASE: 195 | case XCB_KEYMAP_NOTIFY: 196 | case XCB_EXPOSE: 197 | case XCB_GRAPHICS_EXPOSURE: 198 | case XCB_NO_EXPOSURE: 199 | case XCB_VISIBILITY_NOTIFY: 200 | case XCB_MAP_REQUEST: 201 | case XCB_REPARENT_NOTIFY: 202 | case XCB_CONFIGURE_NOTIFY: 203 | case XCB_CONFIGURE_REQUEST: 204 | case XCB_GRAVITY_NOTIFY: 205 | case XCB_RESIZE_REQUEST: 206 | case XCB_CIRCULATE_NOTIFY: 207 | case XCB_CIRCULATE_REQUEST: 208 | case XCB_PROPERTY_NOTIFY: 209 | case XCB_SELECTION_CLEAR: 210 | case XCB_SELECTION_REQUEST: 211 | case XCB_SELECTION_NOTIFY: 212 | case XCB_COLORMAP_NOTIFY: 213 | case XCB_CLIENT_MESSAGE: 214 | case XCB_MAPPING_NOTIFY: 215 | */ 216 | } 217 | } 218 | 219 | int 220 | main (int argc, char **argv) 221 | { 222 | int i, wn; 223 | char *argv0; 224 | xcb_window_t *wc; 225 | xcb_generic_event_t *e; 226 | xcb_create_notify_event_t *ec; 227 | 228 | ARGBEGIN { 229 | case 'l': 230 | list_events(); 231 | exit(0); 232 | case 'r': 233 | rootmask = strtoul(EARGF(usage(argv0)), NULL, 10); 234 | break; 235 | case 'm': 236 | mask = strtoul(EARGF(usage(argv0)), NULL, 10); 237 | break; 238 | default: usage(argv0); 239 | } ARGEND; 240 | 241 | init_xcb(&conn); 242 | get_screen(conn, &scr); 243 | 244 | /* 245 | * We need to get notifed of window creations, no matter what, because 246 | * we need to register the event mask on all newly created windows 247 | */ 248 | register_events(scr->root, rootmask); 249 | 250 | /* register the events on all mapped windows */ 251 | wn = get_windows(conn, scr->root, &wc); 252 | for (i=0; iresponse_type & ~0x80) 258 | { 259 | /* register events for each new windows */ 260 | case XCB_CREATE_NOTIFY: 261 | ec = (xcb_create_notify_event_t*)e; 262 | register_events(ec->window, mask); 263 | /* FALLTHROUGH */ 264 | } 265 | print_event(e); 266 | fflush(stdout); 267 | 268 | free(e); 269 | } 270 | 271 | kill_xcb(&conn); 272 | 273 | return 0; 274 | } 275 | -------------------------------------------------------------------------------- /wname.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "util.h" 9 | 10 | static xcb_connection_t *conn; 11 | 12 | static void usage(char *); 13 | static int get_title(xcb_window_t); 14 | 15 | static void 16 | usage(char *name) 17 | { 18 | fprintf(stderr, "usage: %s \n", name); 19 | exit(1); 20 | } 21 | 22 | static int 23 | get_title(xcb_window_t win) 24 | { 25 | int len = 0; 26 | xcb_get_property_cookie_t cookie; 27 | xcb_get_property_reply_t *r; 28 | 29 | cookie = xcb_get_property(conn, 0, win, 30 | XCB_ATOM_WM_NAME, XCB_ATOM_ANY, 0L, 32L); 31 | r = xcb_get_property_reply(conn, cookie, NULL); 32 | 33 | if (r) { 34 | len = xcb_get_property_value_length(r); 35 | if (!len) 36 | return 1; 37 | 38 | printf("%.*s\n", len, (char *) xcb_get_property_value(r)); 39 | 40 | free(r); 41 | return 0; 42 | } 43 | 44 | warnx("could not get window title"); 45 | return 1; 46 | } 47 | 48 | int 49 | main(int argc, char **argv) 50 | { 51 | int i, r = 0; 52 | 53 | if (argc < 2) 54 | usage(argv[0]); 55 | 56 | init_xcb(&conn); 57 | 58 | for (i=1; i < argc; i++) 59 | r += get_title(strtoul(argv[i], NULL, 16)); 60 | 61 | kill_xcb(&conn); 62 | 63 | return r; 64 | } 65 | -------------------------------------------------------------------------------- /xmmv.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | #define CLEANMASK(m) ((m & ~0x80)) 10 | 11 | static xcb_connection_t *conn; 12 | static xcb_screen_t *scr; 13 | 14 | static void usage(char *); 15 | static xcb_window_t get_focuswin(void); 16 | static void cleanup(void); 17 | 18 | static void 19 | cleanup(void) 20 | { 21 | kill_xcb(&conn); 22 | } 23 | 24 | static void 25 | usage(char *name) 26 | { 27 | fprintf(stderr, "usage: %s \n", name); 28 | exit(1); 29 | } 30 | 31 | static xcb_window_t 32 | get_focuswin(void) { 33 | xcb_window_t w = 0; 34 | 35 | xcb_get_input_focus_cookie_t c; 36 | xcb_get_input_focus_reply_t *r; 37 | 38 | c = xcb_get_input_focus(conn); 39 | r = xcb_get_input_focus_reply(conn, c, NULL); 40 | 41 | if (r == NULL) 42 | errx(1, "failed to get focused window"); 43 | 44 | w = r->focus; 45 | free(r); 46 | return w; 47 | } 48 | 49 | static void 50 | mmove(xcb_window_t win) { 51 | uint32_t values[3]; 52 | xcb_get_geometry_reply_t *geom; 53 | xcb_query_pointer_reply_t *ptr; 54 | xcb_generic_event_t *ev = NULL; 55 | int orig_x, orig_y; 56 | 57 | geom = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, win), NULL); 58 | xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0, 0, 59 | geom->width/2, geom->height/2); 60 | 61 | if (!geom) 62 | errx(1, "could not get window size"); 63 | 64 | orig_x = geom->x; 65 | orig_y = geom->y; 66 | 67 | if (!scr->root) 68 | return; 69 | 70 | xcb_grab_pointer(conn, 0, scr->root, 71 | XCB_EVENT_MASK_BUTTON_RELEASE 72 | | XCB_EVENT_MASK_BUTTON_PRESS, 73 | XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, 74 | scr->root, XCB_NONE, XCB_CURRENT_TIME); 75 | 76 | xcb_flush(conn); 77 | 78 | 79 | for (;;) { 80 | ev = xcb_poll_for_event(conn); 81 | 82 | if (geom->x != orig_x || geom->y != orig_y) 83 | if (ev != NULL) { 84 | if (ev->response_type == XCB_MOTION_NOTIFY) 85 | break; 86 | exit(0); 87 | } 88 | 89 | geom = xcb_get_geometry_reply(conn, 90 | xcb_get_geometry(conn, win), NULL); 91 | if (!geom) 92 | errx(1, "could not get window size"); 93 | 94 | 95 | ptr = xcb_query_pointer_reply(conn, 96 | xcb_query_pointer(conn, scr->root), 0); 97 | 98 | if (!ptr) 99 | errx(1, "could not get pointer location"); 100 | 101 | values[0] = ptr->root_x + geom->width/2; 102 | values[1] = ptr->root_y + geom->height/2; 103 | 104 | values[0] = (ptr->root_x + geom->width / 2 105 | > scr->width_in_pixels 106 | - (geom->border_width*2)) 107 | ? scr->width_in_pixels - geom->width 108 | - (geom->border_width*2) 109 | : ptr->root_x - geom->width / 2; 110 | values[1] = (ptr->root_y + geom->height / 2 111 | > scr->height_in_pixels 112 | - (geom->border_width*2)) 113 | ? (scr->height_in_pixels - geom->height 114 | - (geom->border_width*2)) 115 | : ptr->root_y - geom->height / 2; 116 | 117 | if (ptr->root_x < geom->width/2) 118 | values[0] = 0; 119 | if (ptr->root_y < geom->height/2) 120 | values[1] = 0; 121 | 122 | xcb_configure_window(conn, win, XCB_CONFIG_WINDOW_X 123 | | XCB_CONFIG_WINDOW_Y, values); 124 | xcb_flush(conn); 125 | } 126 | 127 | xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); 128 | } 129 | 130 | int 131 | main(int argc, char **argv) 132 | { 133 | xcb_window_t win; 134 | 135 | if (argc > 2) 136 | usage(argv[0]); 137 | 138 | init_xcb(&conn); 139 | get_screen(conn, &scr); 140 | atexit(cleanup); 141 | 142 | if (argc == 2) 143 | win = strtoul(argv[1], NULL, 16); 144 | else 145 | win = get_focuswin(); 146 | 147 | mmove(win); 148 | 149 | return 0; 150 | } 151 | -------------------------------------------------------------------------------- /xmrs.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | #define CLEANMASK(m) ((m & ~0x80)) 10 | #define MAX(a, b) (a > b ? a : b) 11 | 12 | static xcb_connection_t *conn; 13 | static xcb_screen_t *scr; 14 | 15 | static void usage(char *); 16 | static xcb_window_t get_focuswin(void); 17 | static void cleanup(void); 18 | 19 | static void 20 | cleanup(void) 21 | { 22 | kill_xcb(&conn); 23 | } 24 | 25 | static void 26 | usage(char *name) 27 | { 28 | fprintf(stderr, "usage: %s \n", name); 29 | exit(1); 30 | } 31 | 32 | static xcb_window_t 33 | get_focuswin(void) { 34 | xcb_window_t w = 0; 35 | 36 | xcb_get_input_focus_cookie_t c; 37 | xcb_get_input_focus_reply_t *r; 38 | 39 | c = xcb_get_input_focus(conn); 40 | r = xcb_get_input_focus_reply(conn, c, NULL); 41 | 42 | if (r == NULL) 43 | errx(1, "failed to get focused window"); 44 | 45 | w = r->focus; 46 | free(r); 47 | return w; 48 | } 49 | 50 | static void 51 | mresize(xcb_window_t win) { 52 | uint32_t values[3]; 53 | xcb_get_geometry_reply_t *geom; 54 | xcb_query_pointer_reply_t *ptr; 55 | xcb_generic_event_t *ev = NULL; 56 | int orig_width, orig_height; 57 | 58 | geom = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, win), NULL); 59 | xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0, 0, 60 | geom->width, geom->height); 61 | 62 | if (!geom) 63 | errx(1, "could not get window size"); 64 | 65 | orig_width = geom->width; 66 | orig_height = geom->height; 67 | 68 | if (!scr->root) 69 | return; 70 | 71 | xcb_grab_pointer(conn, 0, scr->root, 72 | XCB_EVENT_MASK_BUTTON_RELEASE 73 | | XCB_EVENT_MASK_BUTTON_PRESS, 74 | XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, 75 | scr->root, XCB_NONE, XCB_CURRENT_TIME); 76 | 77 | xcb_flush(conn); 78 | 79 | 80 | for (;;) { 81 | ev = xcb_poll_for_event(conn); 82 | 83 | if (geom->width != orig_width || geom->height != orig_height) 84 | if (ev != NULL) { 85 | if (ev->response_type == XCB_MOTION_NOTIFY) 86 | break; 87 | exit(0); 88 | } 89 | 90 | geom = xcb_get_geometry_reply(conn, 91 | xcb_get_geometry(conn, win), NULL); 92 | if (!geom) 93 | errx(1, "could not get window size"); 94 | 95 | 96 | ptr = xcb_query_pointer_reply(conn, 97 | xcb_query_pointer(conn, scr->root), 0); 98 | 99 | if (!ptr) 100 | errx(1, "could not get pointer location"); 101 | 102 | values[0] = MAX(1, ptr->root_x - geom->x - 2 * geom->border_width); 103 | values[1] = MAX(1, ptr->root_y - geom->y - 2 * geom->border_width); 104 | 105 | 106 | if (values[0] >= 0 && values[1] >= 0) 107 | xcb_configure_window(conn, win, XCB_CONFIG_WINDOW_WIDTH 108 | | XCB_CONFIG_WINDOW_HEIGHT, values); 109 | xcb_flush(conn); 110 | } 111 | 112 | xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); 113 | } 114 | 115 | int 116 | main(int argc, char **argv) 117 | { 118 | xcb_window_t win; 119 | 120 | if (argc > 2) 121 | usage(argv[0]); 122 | 123 | init_xcb(&conn); 124 | get_screen(conn, &scr); 125 | atexit(cleanup); 126 | 127 | if (argc == 2) 128 | win = strtoul(argv[1], NULL, 16); 129 | else 130 | win = get_focuswin(); 131 | 132 | mresize(win); 133 | 134 | return 0; 135 | } 136 | --------------------------------------------------------------------------------