From 6860491c78b9474eb9b2ed0b55899f289d3c6a44 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 23 Nov 2011 13:02:45 +0100 Subject: Simplified and renamed start_terminal() to start() which can start any program. Skip the double fork() and explicitly ignore SIGCHLD to fend off zombies. Added support for mouse buttons on root window to optionally start a program with start(). By default mouse button three starts mcmenu which must be in PATH. --- NEWS | 8 ++++++ config.h | 7 +++++ mcwm.c | 93 ++++++++++++++++++++++++++++++++-------------------------------- mcwm.man | 27 ++++++++++++++++++- 4 files changed, 87 insertions(+), 48 deletions(-) diff --git a/NEWS b/NEWS index 46f0b1e..fd9e18e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,14 @@ User visible changes +2011-11-22 + + * Now optionally starts programs when MODKEY + mouse buttons are + pressed on root window. See config.h for configuration and the + manual page for an example. + + Also simplified starting programs. + 2011-11-17 * In a ConfigureRequest we no longer obey window movements not diff --git a/config.h b/config.h index 35176a7..0291b11 100644 --- a/config.h +++ b/config.h @@ -32,6 +32,13 @@ */ #define TERMINAL "urxvt" +/* + * Start these programs when pressing MODKEY and mouse buttons on root window. + */ +#define MOUSE1 "" +#define MOUSE2 "" +#define MOUSE3 "mcmenu" + /* * Default colour on border for focused windows. Can be set from * command line with "-f colour". diff --git a/mcwm.c b/mcwm.c index 613d53e..0613c9f 100644 --- a/mcwm.c +++ b/mcwm.c @@ -326,7 +326,7 @@ static struct client *findclient(xcb_drawable_t win); static void focusnext(void); static void setunfocus(xcb_drawable_t win); static void setfocus(struct client *client); -static int start_terminal(void); +static int start(char *program); static void resizelim(struct client *client); static void moveresize(xcb_drawable_t win, uint16_t x, uint16_t y, uint16_t width, uint16_t height); @@ -2085,15 +2085,10 @@ void setfocus(struct client *client) focuswin = client; } -/* - * Start a program specified in conf.terminal. - * - * Returns 0 on success. - */ -int start_terminal(void) +int start(char *program) { pid_t pid; - + pid = fork(); if (-1 == pid) { @@ -2102,10 +2097,10 @@ int start_terminal(void) } else if (0 == pid) { - pid_t termpid; - - /* In our first child. */ + char *argv[2]; + /* In the child. */ + /* * Make this process a new process leader, otherwise the * terminal will die when the wm dies. Also, this makes any @@ -2117,39 +2112,15 @@ int start_terminal(void) exit(1); } - /* - * Fork again for the terminal process. This way, the wm won't - * know anything about it. - */ - termpid = fork(); - if (-1 == termpid) + argv[0] = program; + argv[1] = NULL; + + if (-1 == execvp(program, argv)) { - perror("fork"); + perror("execve"); exit(1); } - else if (0 == termpid) - { - char *argv[2]; - - /* In the second child, now starting terminal. */ - - argv[0] = conf.terminal; - argv[1] = NULL; - - if (-1 == execvp(conf.terminal, argv)) - { - perror("execve"); - exit(1); - } - } /* second child */ - - /* Exit our first child so the wm can pick up and continue. */ exit(0); - } /* first child */ - else - { - /* Wait for the first forked process to exit. */ - waitpid(pid, NULL, 0); } return 0; @@ -3010,7 +2981,7 @@ void handle_keypress(xcb_key_press_event_t *ev) switch (key) { case KEY_RET: /* return */ - start_terminal(); + start(conf.terminal); break; case KEY_F: /* f */ @@ -3486,6 +3457,32 @@ void events(void) e->detail, (long)e->event, e->child, e->event_x, e->event_y); + if (0 == e->child) + { + /* Mouse click on root window. Start programs? */ + + switch (e->detail) + { + case 1: /* Mouse button one. */ + start(MOUSE1); + break; + + case 2: /* Middle mouse button. */ + start(MOUSE2); + break; + + case 3: /* Mouse button three. */ + start(MOUSE3); + break; + + default: + break; + } /* switch */ + + /* Break out of event switch. */ + break; + } + /* * If we don't have any currently focused window, we can't * do anything. We don't want to do anything if the mouse @@ -3497,11 +3494,6 @@ void events(void) break; } - /* - * XXX if 0 == e->child, we're on the root window. Do - * something on the root when mouse buttons are pressed? - */ - /* * If middle button was pressed, raise window or lower * it if it was already on top. @@ -4004,6 +3996,13 @@ int main(int argc, char **argv) /* Install signal handlers. */ + /* We ignore child exists. Don't create zombies. */ + if (SIG_ERR == signal(SIGCHLD, SIG_IGN)) + { + perror("mcwm: signal"); + exit(1); + } + if (SIG_ERR == signal(SIGINT, sigcatch)) { perror("mcwm: signal"); @@ -4111,7 +4110,7 @@ int main(int argc, char **argv) XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, 1 /* left mouse button */, MOUSEMODKEY); - + xcb_grab_button(conn, 0, root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, diff --git a/mcwm.man b/mcwm.man index 5b234db..1f4ebf7 100644 --- a/mcwm.man +++ b/mcwm.man @@ -147,7 +147,10 @@ cursor. Of course, changing workspaces has nothing to do with the focused window. .PP If you don't like the default key bindings, border width, et cetera, -look in the config.h file, change and recompile. +look in the config.h file, change and recompile. In the config.h file +you can also define mouse button actions on the root window. By +default button 3 starts the command mcmenu. You can write your own +mcmenu by using, for instance, 9menu or ratmenu. .PP .SH STARTING Typically the window manager is started from a script, either run by @@ -179,5 +182,27 @@ exec urxvt .fi .in -4 .sp +.PP +You may also want to define an mcmenu program for use with mcwm. +Here's a complete example using the 9menu program: +.sp +.in +4 +.nf +\&#! /bin/sh +9menu -bg black -fg white \\ + -popup \\ + 'cpu:urxvt -e ssh cpu.example.org' \\ + ':' \\ + 'VGA On: xrandr --output VGA --on' \\ + 'VGA Off: xrandr --output VGA --off' \\ + 'VGA Above: xrandr --output VGA --auto --above LVDS' \\ + ':' \\ + 'HHKB: xkbcomp -I$HOME/conf/xkb $HOME/conf/xkb/hhkb.xkb $DISPLAY' \\ + 'Thinkpad: xmodmap /home/mc/lib/xmodmap/thinkpad-x60.xmodmap' \\ + ':' \\ + 'close:' +.fi +.in -4 +.sp .SH AUTHOR Michael Cardell Widerkrantz . -- cgit v1.2.3 From cf4756732ddf8d5255f7c6aa1d2d0cd95c48c84e Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 23 Nov 2011 13:08:22 +0100 Subject: Affected by last patch. --- TODO | 2 -- WISHLIST | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/TODO b/TODO index 49dd388..4248532 100644 --- a/TODO +++ b/TODO @@ -88,8 +88,6 @@ * Configuration file. -* Start configurable programs when clicking on root window. - * Handle Urgency hint Some windows might need attention and marks this with an urgency diff --git a/WISHLIST b/WISHLIST index 58a5591..d0f2a22 100644 --- a/WISHLIST +++ b/WISHLIST @@ -43,7 +43,7 @@ v Know about physical screens dynamically (RandR). - Snap to border and screen edge, which favours the edge. -- Mouse buttons on root window should start some configurable +v Mouse buttons on root window should start some configurable programs. - Feedback window for size when resizing. -- cgit v1.2.3 From cb863dec28787af284ccf14e4e1eb0c8eacace1f Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Thu, 24 Nov 2011 10:44:23 +0100 Subject: Bump. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5156262..442047a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=20110818 +VERSION=20111124 DIST=mcwm-$(VERSION) SRC=mcwm.c list.c config.h events.h list.h DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man $(SRC) -- cgit v1.2.3 From 230295e0822084a4b75df5138106bc836b8004bb Mon Sep 17 00:00:00 2001 From: David Jacobs Date: Tue, 24 Jan 2012 10:42:21 +0100 Subject: Names of functions and constants updated to work with xcb-util 3.8. Thanks David! --- Makefile | 11 +++++----- mcwm.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 442047a..fdb94fe 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,11 @@ -VERSION=20111124 +VERSION=20120124 DIST=mcwm-$(VERSION) SRC=mcwm.c list.c config.h events.h list.h DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man $(SRC) -CC=gcc -CFLAGS=-g -std=c99 -Wall -Wextra -O2 -I/usr/local/include #-DDEBUG #-DDMALLOC -LDFLAGS=-L/usr/local/lib -lxcb -lxcb-randr -lxcb-keysyms -lxcb-icccm \ - -lxcb-atom #-ldmalloc +CFLAGS+=-g -std=c99 -Wall -Wextra -I/usr/local/include #-DDEBUG #-DDMALLOC +LDFLAGS+=-L/usr/local/lib -lxcb -lxcb-randr -lxcb-keysyms -lxcb-icccm \ + -lxcb-util #-ldmalloc RM=/bin/rm PREFIX=/usr/local @@ -21,7 +20,7 @@ mcwm: $(OBJS) mcwm-static: $(OBJS) $(CC) -o $@ $(OBJS) -static $(CFLAGS) $(LDFLAGS) \ - -lxcb-property -lxcb-event -lXau -lXdmcp + -lXau -lXdmcp mcwm.o: mcwm.c events.h list.h config.h Makefile diff --git a/mcwm.c b/mcwm.c index 0613c9f..7702187 100644 --- a/mcwm.c +++ b/mcwm.c @@ -45,6 +45,10 @@ #include +#include +#include +#include + #ifdef DEBUG #include "events.h" #endif @@ -503,7 +507,7 @@ void setwmdesktop(xcb_drawable_t win, uint32_t ws) PDEBUG("Changing _NET_WM_DESKTOP on window %d to %d\n", win, ws); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, - atom_desktop, CARDINAL, 32, 1, + atom_desktop, XCB_ATOM_CARDINAL, 32, 1, &ws); } @@ -521,7 +525,7 @@ int32_t getwmdesktop(xcb_drawable_t win) uint32_t *wsp; uint32_t ws; - cookie = xcb_get_any_property(conn, false, win, atom_desktop, + cookie = xcb_get_property(conn, false, win, atom_desktop,XCB_GET_PROPERTY_TYPE_ANY, 0, sizeof (int32_t)); reply = xcb_get_property_reply(conn, cookie, NULL); @@ -1136,8 +1140,8 @@ struct client *setupwin(xcb_window_t win) /* * Get the window's incremental size step, if any. */ - if (!xcb_get_wm_normal_hints_reply( - conn, xcb_get_wm_normal_hints_unchecked( + if (!xcb_icccm_get_wm_normal_hints_reply( + conn, xcb_icccm_get_wm_normal_hints_unchecked( conn, win), &hints, NULL)) { PDEBUG("Couldn't get size hints.\n"); @@ -1147,25 +1151,25 @@ struct client *setupwin(xcb_window_t win) * The user specified the position coordinates. Remember that so * we can use geometry later. */ - if (hints.flags & XCB_SIZE_HINT_US_POSITION) + if (hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) { client->usercoord = true; } - if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE) + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE) { client->min_width = hints.min_width; client->min_height = hints.min_height; } - if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE) + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE) { client->max_width = hints.max_width; client->max_height = hints.max_height; } - if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC) + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC) { client->width_inc = hints.width_inc; client->height_inc = hints.height_inc; @@ -1174,7 +1178,7 @@ struct client *setupwin(xcb_window_t win) client->height_inc); } - if (hints.flags & XCB_SIZE_HINT_BASE_SIZE) + if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE) { client->base_width = hints.base_width; client->base_height = hints.base_height; @@ -2823,7 +2827,7 @@ void botright(void) void deletewin(void) { xcb_get_property_cookie_t cookie; - xcb_get_wm_protocols_reply_t protocols; + xcb_icccm_get_wm_protocols_reply_t protocols; bool use_delete = false; uint32_t i; @@ -2833,14 +2837,14 @@ void deletewin(void) } /* Check if WM_DELETE is supported. */ - cookie = xcb_get_wm_protocols_unchecked(conn, focuswin->id, wm_protocols); - if (xcb_get_wm_protocols_reply(conn, cookie, &protocols, NULL) == 1) { + cookie = xcb_icccm_get_wm_protocols_unchecked(conn, focuswin->id, wm_protocols); + if (xcb_icccm_get_wm_protocols_reply(conn, cookie, &protocols, NULL) == 1) { for (i = 0; i < protocols.atoms_len; i++) if (protocols.atoms[i] == wm_delete_window) use_delete = true; } - xcb_get_wm_protocols_reply_wipe(&protocols); + xcb_icccm_get_wm_protocols_reply_wipe(&protocols); if (use_delete) { @@ -4082,9 +4086,46 @@ int main(int argc, char **argv) conf.fixedcol = getcolor(fixedcol); /* Get some atoms. */ - atom_desktop = xcb_atom_get(conn, "_NET_WM_DESKTOP"); - wm_delete_window = xcb_atom_get(conn, "WM_DELETE_WINDOW"); - wm_protocols = xcb_atom_get(conn, "WM_PROTOCOLS"); + char *atom_name; + xcb_intern_atom_cookie_t cookie_desktop; + xcb_intern_atom_cookie_t cookie_delete_window; + xcb_intern_atom_cookie_t cookie_protocols; + xcb_intern_atom_reply_t *rep; + + atom_name = "_NET_WM_DESKTOP"; + cookie_desktop = xcb_intern_atom(conn, + 0, + strlen(atom_name), + atom_name); + rep = xcb_intern_atom_reply(conn, + cookie_desktop, + NULL); + atom_desktop = rep->atom; + free(rep); + + + atom_name = "WM_DELETE_WINDOW"; + cookie_delete_window = xcb_intern_atom(conn, + 0, + strlen (atom_name), + atom_name); + rep = xcb_intern_atom_reply(conn, + cookie_delete_window, + NULL); + wm_delete_window = rep->atom; + free(rep); + + atom_name = "WM_PROTOCOLS"; + cookie_protocols = xcb_intern_atom(conn, + 0, + strlen (atom_name), + atom_name); + rep = xcb_intern_atom_reply(conn, + cookie_protocols, + NULL); + wm_protocols = rep->atom; + free(rep); + /* Check for RANDR extension and configure. */ randrbase = setuprandr(); -- cgit v1.2.3 From 2656814afcf6cd15e4c42f22a57e6d5aa372d024 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 24 Jan 2012 10:54:53 +0100 Subject: Indent and style. --- mcwm.c | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/mcwm.c b/mcwm.c index 7702187..d39577f 100644 --- a/mcwm.c +++ b/mcwm.c @@ -525,8 +525,9 @@ int32_t getwmdesktop(xcb_drawable_t win) uint32_t *wsp; uint32_t ws; - cookie = xcb_get_property(conn, false, win, atom_desktop,XCB_GET_PROPERTY_TYPE_ANY, 0, - sizeof (int32_t)); + cookie = xcb_get_property(conn, false, win, atom_desktop, + XCB_GET_PROPERTY_TYPE_ANY, 0, + sizeof (int32_t)); reply = xcb_get_property_reply(conn, cookie, NULL); if (NULL == reply) @@ -929,7 +930,8 @@ void fitonscreen(struct client *client) willmove = true; willresize = true; } - else if (client->x + client->width + conf.borderwidth * 2 > mon_x + mon_width) + else if (client->x + client->width + conf.borderwidth * 2 + > mon_x + mon_width) { client->x = mon_x + mon_width - (client->width + conf.borderwidth * 2); willmove = true; @@ -942,10 +944,12 @@ void fitonscreen(struct client *client) willmove = true; willresize = true; } - else if (client->y + client->height + conf.borderwidth * 2 > mon_y + mon_height) + else if (client->y + client->height + conf.borderwidth * 2 + > mon_y + mon_height) { - client->y = mon_y + mon_height - (client->height + conf.borderwidth * 2); - willmove = true; + client->y = mon_y + mon_height - (client->height + conf.borderwidth + * 2); + willmove = true; } if (willmove) @@ -1870,7 +1874,8 @@ void movelim(struct client *client) if (client->y + client->height > mon_y + mon_height - conf.borderwidth * 2) { - client->y = (mon_y + mon_height - conf.borderwidth * 2) - client->height; + client->y = (mon_y + mon_height - conf.borderwidth * 2) + - client->height; } movewindow(client->id, client->x, client->y); @@ -2164,14 +2169,16 @@ void resizelim(struct client *client) client->width = client->min_width; } - if (client->x + client->width + conf.borderwidth * 2 > mon_x + mon_width) + if (client->x + client->width + conf.borderwidth * 2 > mon_x + mon_width) { - client->width = mon_width - ((client->x - mon_x) + conf.borderwidth * 2); + client->width = mon_width - ((client->x - mon_x) + conf.borderwidth + * 2); } if (client->y + client->height + conf.borderwidth * 2 > mon_y + mon_height) { - client->height = mon_height - ((client->y - mon_y) + conf.borderwidth * 2); + client->height = mon_height - ((client->y - mon_y) + conf.borderwidth + * 2); } resize(client->id, client->width, client->height); @@ -2394,8 +2401,9 @@ void movestep(struct client *client, char direction) * If the pointer was inside the window to begin with, move * pointer back to where it was, relative to the window. */ - if (start_x > 0 - conf.borderwidth && start_x < client->width + conf.borderwidth - && start_y > 0 - conf.borderwidth && start_y < client->height + conf.borderwidth ) + if (start_x > 0 - conf.borderwidth && start_x < client->width + + conf.borderwidth && start_y > 0 - conf.borderwidth && start_y + < client->height + conf.borderwidth) { xcb_warp_pointer(conn, XCB_NONE, client->id, 0, 0, 0, 0, start_x, start_y); @@ -2768,10 +2776,9 @@ void botleft(void) } focuswin->x = mon_x; - focuswin->y = mon_y + mon_height - (focuswin->height + conf.borderwidth * 2); - + focuswin->y = mon_y + mon_height - (focuswin->height + conf.borderwidth + * 2); movewindow(focuswin->id, focuswin->x, focuswin->y); - xcb_warp_pointer(conn, XCB_NONE, focuswin->id, 0, 0, 0, 0, pointx, pointy); xcb_flush(conn); @@ -2814,11 +2821,9 @@ void botright(void) } focuswin->x = mon_x + mon_width - (focuswin->width + conf.borderwidth * 2); - - focuswin->y = mon_y + mon_height - (focuswin->height + conf.borderwidth * 2); - + focuswin->y = mon_y + mon_height - (focuswin->height + conf.borderwidth + * 2); movewindow(focuswin->id, focuswin->x, focuswin->y); - xcb_warp_pointer(conn, XCB_NONE, focuswin->id, 0, 0, 0, 0, pointx, pointy); xcb_flush(conn); @@ -2837,11 +2842,17 @@ void deletewin(void) } /* Check if WM_DELETE is supported. */ - cookie = xcb_icccm_get_wm_protocols_unchecked(conn, focuswin->id, wm_protocols); - if (xcb_icccm_get_wm_protocols_reply(conn, cookie, &protocols, NULL) == 1) { + cookie = xcb_icccm_get_wm_protocols_unchecked(conn, focuswin->id, + wm_protocols); + if (xcb_icccm_get_wm_protocols_reply(conn, cookie, &protocols, NULL) == 1) + { for (i = 0; i < protocols.atoms_len; i++) + { if (protocols.atoms[i] == wm_delete_window) + { use_delete = true; + } + } } xcb_icccm_get_wm_protocols_reply_wipe(&protocols); -- cgit v1.2.3 From f79d13649c0dc3fb1b82c293df8dec17d3eaffec Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 24 Jan 2012 10:55:20 +0100 Subject: Bump copyright year. --- mcwm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcwm.c b/mcwm.c index d39577f..e4fd043 100644 --- a/mcwm.c +++ b/mcwm.c @@ -7,8 +7,8 @@ * MC, mc at the domain hack.org * http://hack.org/mc/ * - * Copyright (c) 2010,2011 Michael Cardell Widerkrantz, mc at the - * domain hack.org. + * Copyright (c) 2010, 2011, 2012 Michael Cardell Widerkrantz, mc at + * the domain hack.org. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above -- cgit v1.2.3 From 76e3494126949d95af993e28f4fead6d9b3ae2d1 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 24 Jan 2012 10:56:02 +0100 Subject: Bump copyright year. --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 57c29ef..6be2048 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010,2011 Michael Cardell Widerkrantz +Copyright (c) 2010,2011,2012 Michael Cardell Widerkrantz Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above -- cgit v1.2.3 From bff35a51300c5dc644a1c2d7bdb69c4bed97cff7 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 24 Jan 2012 11:59:26 +0100 Subject: Added more items. Mod2 != MODKEY, so changed to MODKEY. --- TODO | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 4248532..5699d7a 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,25 @@ -*- text -*- +* Bug: We grab MODKEY all the time! We can grab it only when we start + tabbing instead and release it when tabbing is complete. + +* Flag (-i, perhaps?) to allow windows to be unmapped. Add unmap patch + from Christian. + +* Key to move to previous and next workspace. David Jacobs has a patch + for mod4+shift + I/O. + + https://gist.github.com/1478365 + +* Key to move windows to other workspaces, perhaps mod4+Shift + 0..9 + and mod4+shift + I/O. + +* Full-screen windows that are resized from client should be kept + full-screen. + +* When moving windows between physical screens, try to place the + window on roughly the same place on a new screen, if possible. + * When a window tries to map itself outside the physical screens, always map it to the screen closest to the coordinates it asked for instead of always mapping on the first screen in the list. @@ -42,12 +62,12 @@ - A window might be on one, *several* or all virtual screens. - We already have a way of fixing a window on all screens (Mod2-f), - but we need a way of saying "stick on this workspace". Perhaps - something like Mod2-a , where is 1--9 for virtual screens. - Better ways? Note that this seems to be mildly incompatible with - the EWMH _NET_WM_DESKTOP hint we're currently using: We will only - be able to save one of the desktops used. + We already have a way of fixing a window on all screens + (MODKEY-f), but we need a way of saying "stick on this workspace". + Perhaps something like MODKEY-a , where is 1--9 for virtual + screens. Better ways? Note that this seems to be mildly + incompatible with the EWMH _NET_WM_DESKTOP hint we're currently + using: We will only be able to save one of the desktops used. * Hide windows -- cgit v1.2.3 From eef1c0a3bdd5a205c46e256b4936c4ba8a433690 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 24 Jan 2012 12:28:25 +0100 Subject: Spelling. --- mcwm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcwm.c b/mcwm.c index e4fd043..7e3c462 100644 --- a/mcwm.c +++ b/mcwm.c @@ -3364,8 +3364,8 @@ void events(void) * readable again. * * We do it this way instead of xcb_wait_for_event() since - * select() will return if we we're interrupted by a signal. - * We like that. + * select() will return if we were interrupted by a signal. We + * like that. */ ev = xcb_poll_for_event(conn); if (NULL == ev) -- cgit v1.2.3 From ec483ba317c6d2fb5465dcecc37e3d6492d061c1 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 24 Jan 2012 13:14:36 +0100 Subject: Another item. --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 5699d7a..651eaba 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,7 @@ -*- text -*- +* Use the new xcb-ewmh for the EWMH hints. + * Bug: We grab MODKEY all the time! We can grab it only when we start tabbing instead and release it when tabbing is complete. -- cgit v1.2.3 From 8a99196db3ccff3f6b13deb58cda9dbf84ad9009 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 7 Feb 2012 21:01:51 +0100 Subject: Always check for unrecoverable errors when xcb_poll_for_event() returns NULL. Our file descriptor *might* have become unreadable. --- mcwm.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/mcwm.c b/mcwm.c index 7e3c462..3f187aa 100644 --- a/mcwm.c +++ b/mcwm.c @@ -3359,9 +3359,9 @@ void events(void) FD_SET(fd, &in); /* - * Check for events, again and again. When poll returns NULL, - * we block on select() until the event file descriptor gets - * readable again. + * Check for events, again and again. When poll returns NULL + * (and it does that a lot), we block on select() until the + * event file descriptor gets readable again. * * We do it this way instead of xcb_wait_for_event() since * select() will return if we were interrupted by a signal. We @@ -3370,6 +3370,18 @@ void events(void) ev = xcb_poll_for_event(conn); if (NULL == ev) { + PDEBUG("xcb_poll_for_event() returned NULL.\n"); + + /* + * Check if we have an unrecoverable connection error, + * like a disconnected X server. + */ + if (xcb_connection_has_error(conn)) + { + cleanup(0); + exit(1); + } + found = select(fd + 1, &in, NULL, NULL, NULL); if (-1 == found) { -- cgit v1.2.3 From bbae550916c3e1fffa03c46e0b9726ccb7a1a81c Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 7 Feb 2012 21:04:44 +0100 Subject: *** empty log message *** --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index 651eaba..09e45df 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,10 @@ -*- text -*- +* Feature: Xinerama support. Needed when XRANDR above 1.1 not + supported, for instance with Nvidia cards in Twinview configuration. + +* Bug: Ignore other modifiers, such as NumLock and CapsLock. + * Use the new xcb-ewmh for the EWMH hints. * Bug: We grab MODKEY all the time! We can grab it only when we start -- cgit v1.2.3 From 61c2c490002813515caab181af7b4011d3b3def5 Mon Sep 17 00:00:00 2001 From: Christian Neukirchen Date: Wed, 15 Feb 2012 09:07:21 +0100 Subject: Respect IconifyWindow messages. WARNING! This will iconify/hide windows without any way of getting them back from within mcwm. --- mcwm.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/mcwm.c b/mcwm.c index 3f187aa..45acd23 100644 --- a/mcwm.c +++ b/mcwm.c @@ -285,6 +285,8 @@ xcb_atom_t atom_desktop; /* */ xcb_atom_t wm_delete_window; /* WM_DELETE_WINDOW event to close windows. */ +xcb_atom_t wm_change_state; +xcb_atom_t wm_state; xcb_atom_t wm_protocols; /* WM_PROTOCOLS. */ @@ -1048,6 +1050,11 @@ void newwin(xcb_window_t win) /* Show window on screen. */ xcb_map_window(conn, client->id); + /* Declare window normal. */ + long data[] = { XCB_ICCCM_WM_STATE_NORMAL, XCB_NONE }; + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, client->id, + wm_state, wm_state, 32, 2, data); + /* * Move cursor into the middle of the window so we don't lose the * pointer to another window. @@ -3896,6 +3903,24 @@ void events(void) configurerequest((xcb_configure_request_event_t *) ev); break; + case XCB_CLIENT_MESSAGE: + { + xcb_client_message_event_t *e + = (xcb_client_message_event_t *)ev; + if (e->type == wm_change_state + && e->format == 32 + && e->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC) + { + /* Unmap window and declare iconic. */ + xcb_unmap_window(conn, e->window); + long data[] = { XCB_ICCCM_WM_STATE_ICONIC, XCB_NONE }; + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, e->window, + wm_state, wm_state, 32, 2, data); + xcb_flush(conn); + } + } + break; + case XCB_CIRCULATE_REQUEST: { xcb_circulate_request_event_t *e @@ -4110,6 +4135,7 @@ int main(int argc, char **argv) /* Get some atoms. */ char *atom_name; + xcb_intern_atom_cookie_t atom_cookie; xcb_intern_atom_cookie_t cookie_desktop; xcb_intern_atom_cookie_t cookie_delete_window; xcb_intern_atom_cookie_t cookie_protocols; @@ -4138,6 +4164,25 @@ int main(int argc, char **argv) wm_delete_window = rep->atom; free(rep); + + atom_name = "WM_CHANGE_STATE"; + atom_cookie = xcb_intern_atom(conn, + 0, + strlen(atom_name), + atom_name); + rep = xcb_intern_atom_reply(conn, atom_cookie, NULL); + wm_change_state = rep->atom; + free(rep); + + atom_name = "WM_STATE"; + atom_cookie = xcb_intern_atom(conn, + 0, + strlen(atom_name), + atom_name); + rep = xcb_intern_atom_reply(conn, atom_cookie, NULL); + wm_state = rep->atom; + free(rep); + atom_name = "WM_PROTOCOLS"; cookie_protocols = xcb_intern_atom(conn, 0, -- cgit v1.2.3 From 5dbd2572635d5e6cc54c0920e8502f2f18839de8 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 15 Feb 2012 09:22:48 +0100 Subject: Put the iconify functionality behind a command line option (-i) and added the default (false) to config.h. Documented the iconfiy/hide windows functionality in the manual. --- config.h | 6 ++++++ mcwm.c | 24 ++++++++++++++++++------ mcwm.man | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/config.h b/config.h index 0291b11..e843b91 100644 --- a/config.h +++ b/config.h @@ -32,6 +32,12 @@ */ #define TERMINAL "urxvt" +/* + * Do we allow windows to be iconified? Set to true if you want this + * behaviour to be default. Can also be set by calling mcwm with -i. + */ +#define ALLOWICONS false + /* * Start these programs when pressing MODKEY and mouse buttons on root window. */ diff --git a/mcwm.c b/mcwm.c index 45acd23..dc084b0 100644 --- a/mcwm.c +++ b/mcwm.c @@ -276,6 +276,7 @@ struct conf uint32_t focuscol; /* Focused border colour. */ uint32_t unfocuscol; /* Unfocused border colour. */ uint32_t fixedcol; /* Fixed windows border colour. */ + bool allowicons; /* Allow windows to be unmapped. */ } conf; xcb_atom_t atom_desktop; /* @@ -3904,21 +3905,27 @@ void events(void) break; case XCB_CLIENT_MESSAGE: + { + xcb_client_message_event_t *e + = (xcb_client_message_event_t *)ev; + + if (conf.allowicons) { - xcb_client_message_event_t *e - = (xcb_client_message_event_t *)ev; if (e->type == wm_change_state && e->format == 32 && e->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC) { - /* Unmap window and declare iconic. */ - xcb_unmap_window(conn, e->window); long data[] = { XCB_ICCCM_WM_STATE_ICONIC, XCB_NONE }; + + /* Unmap window and declare iconic. */ + + xcb_unmap_window(conn, e->window); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, e->window, wm_state, wm_state, 32, 2, data); xcb_flush(conn); } - } + } /* if */ + } break; case XCB_CIRCULATE_REQUEST: @@ -4071,13 +4078,14 @@ int main(int argc, char **argv) conf.borderwidth = BORDERWIDTH; conf.terminal = TERMINAL; + conf.allowicons = ALLOWICONS; focuscol = FOCUSCOL; unfocuscol = UNFOCUSCOL; fixedcol = FIXEDCOL; while (1) { - ch = getopt(argc, argv, "b:t:f:u:x:"); + ch = getopt(argc, argv, "b:it:f:u:x:"); if (-1 == ch) { @@ -4092,6 +4100,10 @@ int main(int argc, char **argv) conf.borderwidth = atoi(optarg); break; + case 'i': + conf.allowicons = true; + break; + case 't': conf.terminal = optarg; break; diff --git a/mcwm.man b/mcwm.man index 1f4ebf7..e90febe 100644 --- a/mcwm.man +++ b/mcwm.man @@ -7,6 +7,9 @@ mcwm \- MC's Window Manager for X11. .B \-b ] width [ +.B \-i +] +[ .B \-t .I terminal-program ] [ @@ -27,6 +30,12 @@ mcwm \- MC's Window Manager for X11. .PP \-b width sets border width to this many pixels. .PP +\-i turns on icons/hidden windows. +.B Please note +that there is no way from mcwm to get a hidden window back! You have +to use an external program such as a dock or the 9icon script (see +below) to get the window mapped again. +.PP \-t urxvt will start urxvt when MODKEY + Return is pressed. Change to your prefered terminal program or something else entirely. .PP @@ -150,7 +159,7 @@ If you don't like the default key bindings, border width, et cetera, look in the config.h file, change and recompile. In the config.h file you can also define mouse button actions on the root window. By default button 3 starts the command mcmenu. You can write your own -mcmenu by using, for instance, 9menu or ratmenu. +mcmenu by using, for instance, 9menu, dmenu or ratmenu. .PP .SH STARTING Typically the window manager is started from a script, either run by @@ -189,7 +198,7 @@ Here's a complete example using the 9menu program: .in +4 .nf \&#! /bin/sh -9menu -bg black -fg white \\ +exec 9menu -bg black -fg white \\ -popup \\ 'cpu:urxvt -e ssh cpu.example.org' \\ ':' \\ @@ -204,5 +213,31 @@ Here's a complete example using the 9menu program: .fi .in -4 .sp +.PP +Christian Neukirchen wrote a little script you can use to get +iconified windows mapped again. It relies on xwininfo and xdotool and +GNU xargs. +.sp +.in +4 +.nf +\&#! /bin/sh +# 9icon - show 9menu of iconified windows for unmapping + +IFS=" +" + +for win in $(xwininfo -root -children | awk '$1~/0x/ && $2~/"/ {print $1}'); do + xprop -id $win WM_NAME WM_STATE | + awk -F'"' -v win=$win ' + /^WM_NAME/ { name=$2 } + /window state: Iconic/ { + print name ":xdotool windowmap " win " windowraise " win + } + ' +done | xargs -r -d'\\n' \\ + 9menu -popup -label 9icon -bg grey20 -fg grey80 -font fixed +.fi +.in -4 +.sp .SH AUTHOR Michael Cardell Widerkrantz . -- cgit v1.2.3 From a0f63a0aede481c4b36b5434fe3af3b35e5267e7 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 15 Feb 2012 10:00:22 +0100 Subject: Moved scripts out of manual. --- mcwm.man | 54 ++++++++---------------------------------------------- scripts/9icon | 18 ++++++++++++++++++ scripts/mcmenu | 11 +++++++++++ 3 files changed, 37 insertions(+), 46 deletions(-) create mode 100755 scripts/9icon create mode 100755 scripts/mcmenu diff --git a/mcwm.man b/mcwm.man index e90febe..1ef4864 100644 --- a/mcwm.man +++ b/mcwm.man @@ -33,7 +33,7 @@ mcwm \- MC's Window Manager for X11. \-i turns on icons/hidden windows. .B Please note that there is no way from mcwm to get a hidden window back! You have -to use an external program such as a dock or the 9icon script (see +to use an external program such as a panel or the 9icon script (see below) to get the window mapped again. .PP \-t urxvt will start urxvt when MODKEY + Return is pressed. Change to @@ -192,52 +192,14 @@ exec urxvt .in -4 .sp .PP -You may also want to define an mcmenu program for use with mcwm. -Here's a complete example using the 9menu program: -.sp -.in +4 -.nf -\&#! /bin/sh -exec 9menu -bg black -fg white \\ - -popup \\ - 'cpu:urxvt -e ssh cpu.example.org' \\ - ':' \\ - 'VGA On: xrandr --output VGA --on' \\ - 'VGA Off: xrandr --output VGA --off' \\ - 'VGA Above: xrandr --output VGA --auto --above LVDS' \\ - ':' \\ - 'HHKB: xkbcomp -I$HOME/conf/xkb $HOME/conf/xkb/hhkb.xkb $DISPLAY' \\ - 'Thinkpad: xmodmap /home/mc/lib/xmodmap/thinkpad-x60.xmodmap' \\ - ':' \\ - 'close:' -.fi -.in -4 -.sp +.SH SCRIPTS +You may want to define a menu program for use with mcwm (see +config.h). In the source distribution you can find an example as +mcmenu in the scripts directory. .PP Christian Neukirchen wrote a little script you can use to get -iconified windows mapped again. It relies on xwininfo and xdotool and -GNU xargs. -.sp -.in +4 -.nf -\&#! /bin/sh -# 9icon - show 9menu of iconified windows for unmapping - -IFS=" -" - -for win in $(xwininfo -root -children | awk '$1~/0x/ && $2~/"/ {print $1}'); do - xprop -id $win WM_NAME WM_STATE | - awk -F'"' -v win=$win ' - /^WM_NAME/ { name=$2 } - /window state: Iconic/ { - print name ":xdotool windowmap " win " windowraise " win - } - ' -done | xargs -r -d'\\n' \\ - 9menu -popup -label 9icon -bg grey20 -fg grey80 -font fixed -.fi -.in -4 -.sp +iconified windows mapped again if you are running mcwm in allow icons +mode (-i). You need awk, xdotool, xprop and xwininfo installed. You +can the script as scripts/9icon. .SH AUTHOR Michael Cardell Widerkrantz . diff --git a/scripts/9icon b/scripts/9icon new file mode 100755 index 0000000..dded416 --- /dev/null +++ b/scripts/9icon @@ -0,0 +1,18 @@ +#! /bin/sh + +# 9icon - show 9menu of hidden windows for mapping +# Originally by Christian Neukirchen and +# slightly changed by MC. + +IFS=" +" + +for win in $(xwininfo -root -children | awk '$1~/0x/ && $2~/"/ {print $1}'); do + xprop -id $win WM_NAME WM_STATE | + awk -F'"' -v win=$win ' + /^WM_NAME/ { name=$2 } + /window state: Iconic/ { + print name "'\''" ":xdotool windowmap " win " windowraise " win "'\''" + } + ' +done | xargs 9menu -popup -label 9icon -bg grey20 -fg grey80 -font fixed diff --git a/scripts/mcmenu b/scripts/mcmenu new file mode 100755 index 0000000..f5d6611 --- /dev/null +++ b/scripts/mcmenu @@ -0,0 +1,11 @@ +#! /bin/sh +exec 9menu -bg grey20 -fg grey80 \\ + -popup \\ + 'cpu:urxvt -e ssh cpu.example.org' \\ + ':' \\ + 'VGA On: xrandr --output VGA --on' \\ + 'VGA Off: xrandr --output VGA --off' \\ + ':' \\ + 'HHKB: xkbcomp -I$HOME/conf/xkb $HOME/conf/xkb/hhkb.xkb $DISPLAY' \\ + ':' \\ + 'close:' -- cgit v1.2.3 From 4749170ecb656c64fd6a292325cf05fbe5bc3f65 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 15 Feb 2012 10:03:15 +0100 Subject: Added news. --- NEWS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NEWS b/NEWS index fd9e18e..c07c4ae 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,17 @@ User visible changes +2012-02-15 + + * Added option -i to allow icons. + + * Added scripts: mcmenu (configurable start meny) and 9icon (to map + iconified windows). + +2012-02-07 + + * Check for socket errors. Should prevent busy loops. + 2011-11-22 * Now optionally starts programs when MODKEY + mouse buttons are -- cgit v1.2.3 From 97a51653944b43aee9a6c4d9d4ac8fc99dddd287 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 15 Feb 2012 10:23:59 +0100 Subject: Use getatom() to get all the atoms we need instead of repeating code. --- mcwm.c | 91 +++++++++++++++++++++++------------------------------------------- 1 file changed, 31 insertions(+), 60 deletions(-) diff --git a/mcwm.c b/mcwm.c index dc084b0..dcf6612 100644 --- a/mcwm.c +++ b/mcwm.c @@ -362,6 +362,7 @@ static void configurerequest(xcb_configure_request_event_t *e); static void events(void); static void printhelp(void); static void sigcatch(int sig); +static xcb_atom_t getatom(char *atom_name); /* Function bodies. */ @@ -4041,6 +4042,31 @@ void sigcatch(int sig) sigcode = sig; } +/* + * Get a defined atom from the X server. + */ +xcb_atom_t getatom(char *atom_name) +{ + xcb_intern_atom_cookie_t atom_cookie; + xcb_atom_t atom; + xcb_intern_atom_reply_t *rep; + + atom_cookie = xcb_intern_atom(conn, 0, strlen(atom_name), atom_name); + rep = xcb_intern_atom_reply(conn, atom_cookie, NULL); + if (NULL != rep) + { + atom = rep->atom; + free(rep); + return atom; + } + + /* + * XXX Note that we return 0 as an atom if anything goes wrong. + * Might become interesting. + */ + return 0; +} + int main(int argc, char **argv) { uint32_t mask = 0; @@ -4146,67 +4172,12 @@ int main(int argc, char **argv) conf.fixedcol = getcolor(fixedcol); /* Get some atoms. */ - char *atom_name; - xcb_intern_atom_cookie_t atom_cookie; - xcb_intern_atom_cookie_t cookie_desktop; - xcb_intern_atom_cookie_t cookie_delete_window; - xcb_intern_atom_cookie_t cookie_protocols; - xcb_intern_atom_reply_t *rep; - - atom_name = "_NET_WM_DESKTOP"; - cookie_desktop = xcb_intern_atom(conn, - 0, - strlen(atom_name), - atom_name); - rep = xcb_intern_atom_reply(conn, - cookie_desktop, - NULL); - atom_desktop = rep->atom; - free(rep); - - - atom_name = "WM_DELETE_WINDOW"; - cookie_delete_window = xcb_intern_atom(conn, - 0, - strlen (atom_name), - atom_name); - rep = xcb_intern_atom_reply(conn, - cookie_delete_window, - NULL); - wm_delete_window = rep->atom; - free(rep); - - - atom_name = "WM_CHANGE_STATE"; - atom_cookie = xcb_intern_atom(conn, - 0, - strlen(atom_name), - atom_name); - rep = xcb_intern_atom_reply(conn, atom_cookie, NULL); - wm_change_state = rep->atom; - free(rep); - - atom_name = "WM_STATE"; - atom_cookie = xcb_intern_atom(conn, - 0, - strlen(atom_name), - atom_name); - rep = xcb_intern_atom_reply(conn, atom_cookie, NULL); - wm_state = rep->atom; - free(rep); + atom_desktop = getatom("_NET_WM_DESKTOP"); + wm_delete_window = getatom("WM_DELETE_WINDOW"); + wm_change_state = getatom("WM_CHANGE_STATE"); + wm_state = getatom("WM_STATE"); + wm_protocols = getatom("WM_PROTOCOLS"); - atom_name = "WM_PROTOCOLS"; - cookie_protocols = xcb_intern_atom(conn, - 0, - strlen (atom_name), - atom_name); - rep = xcb_intern_atom_reply(conn, - cookie_protocols, - NULL); - wm_protocols = rep->atom; - free(rep); - - /* Check for RANDR extension and configure. */ randrbase = setuprandr(); -- cgit v1.2.3 From d9e6e80ad9b6aa0347a65a71a7cdb0a78c08d790 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 15 Feb 2012 10:34:10 +0100 Subject: Added hide. Removed superflous \ characters left from when the script was in the manual. Oops. --- scripts/mcmenu | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/mcmenu b/scripts/mcmenu index f5d6611..6d32940 100755 --- a/scripts/mcmenu +++ b/scripts/mcmenu @@ -1,11 +1,11 @@ #! /bin/sh -exec 9menu -bg grey20 -fg grey80 \\ - -popup \\ - 'cpu:urxvt -e ssh cpu.example.org' \\ - ':' \\ - 'VGA On: xrandr --output VGA --on' \\ - 'VGA Off: xrandr --output VGA --off' \\ - ':' \\ - 'HHKB: xkbcomp -I$HOME/conf/xkb $HOME/conf/xkb/hhkb.xkb $DISPLAY' \\ - ':' \\ +exec 9menu -bg grey20 -fg grey80 -popup \ + 'hide:xdotool selectwindow windowminimize' \ + 'cpu:urxvt -e ssh cpu.example.org' \ + ':' \ + 'VGA On: xrandr --output VGA --on' \ + 'VGA Off: xrandr --output VGA --off' \ + ':' \ + 'HHKB: xkbcomp -I$HOME/conf/xkb $HOME/conf/xkb/hhkb.xkb $DISPLAY' \ + ':' \ 'close:' -- cgit v1.2.3 From a30f469abdac71f9545f45a22b0b60c9ae4880ee Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 15 Feb 2012 11:52:01 +0100 Subject: Added a feature request. Removed feature done. --- TODO | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 09e45df..bf7f083 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,16 @@ -*- text -*- +* Feature: Handle several screens (DISPLAY=0.x) in classical X. + + This means we will have several root windows. + + setup = xcb_get_setup(conn); + screens = xcb_setup_roots_length(setup); + + returns the number of screens available. + + We can walk over them with xcb_setup_roots_iterator(setup). + * Feature: Xinerama support. Needed when XRANDR above 1.1 not supported, for instance with Nvidia cards in Twinview configuration. @@ -10,9 +21,6 @@ * Bug: We grab MODKEY all the time! We can grab it only when we start tabbing instead and release it when tabbing is complete. -* Flag (-i, perhaps?) to allow windows to be unmapped. Add unmap patch - from Christian. - * Key to move to previous and next workspace. David Jacobs has a patch for mod4+shift + I/O. @@ -21,8 +29,8 @@ * Key to move windows to other workspaces, perhaps mod4+Shift + 0..9 and mod4+shift + I/O. -* Full-screen windows that are resized from client should be kept - full-screen. +* Full-screen windows that are resized from client requests should be + kept full-screen. * When moving windows between physical screens, try to place the window on roughly the same place on a new screen, if possible. -- cgit v1.2.3 From e1ba6dc56a411ee2df35f97fb93e11b7fbe53d16 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Thu, 16 Feb 2012 14:06:42 +0100 Subject: Added iconify/hide key, MODKEY + i. Changed manual. Group together window operations in manual. --- config.h | 1 + mcwm.c | 28 ++++++++++++++++++++++++- mcwm.man | 73 +++++++++++++++++++++++++++++++++++----------------------------- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/config.h b/config.h index e843b91..bb1678f 100644 --- a/config.h +++ b/config.h @@ -91,3 +91,4 @@ #define USERKEY_DELETE XK_End #define USERKEY_PREVSCREEN XK_comma #define USERKEY_NEXTSCREEN XK_period +#define USERKEY_ICONIFY XK_I diff --git a/mcwm.c b/mcwm.c index dcf6612..b95240e 100644 --- a/mcwm.c +++ b/mcwm.c @@ -127,6 +127,7 @@ typedef enum { KEY_END, KEY_PREVSCR, KEY_NEXTSCR, + KEY_ICONIFY, KEY_MAX } key_enum_t; @@ -254,7 +255,8 @@ struct keys { USERKEY_BOTRIGHT, 0 }, { USERKEY_DELETE, 0 }, { USERKEY_PREVSCREEN, 0 }, - { USERKEY_NEXTSCREEN, 0 }, + { USERKEY_NEXTSCREEN, 0 }, + { USERKEY_ICONIFY, 0 }, }; /* All keycodes generating our MODKEY mask. */ @@ -346,6 +348,7 @@ static void setborders(struct client *client, int width); static void unmax(struct client *client); static void maximize(struct client *client); static void maxvert(struct client *client); +static void hide(struct client *client); static bool getpointer(xcb_drawable_t win, int16_t *x, int16_t *y); static bool getgeom(xcb_drawable_t win, int16_t *x, int16_t *y, uint16_t *width, uint16_t *height); @@ -2624,6 +2627,22 @@ void maxvert(struct client *client) client->vertmaxed = true; } +void hide(struct client *client) +{ + long data[] = { XCB_ICCCM_WM_STATE_ICONIC, XCB_NONE }; + + /* + * Unmap window and declare iconic. + * + * Unmapping will generate an even UnmapNotify event so we can + * forget about the window later. + */ + xcb_unmap_window(conn, client->id); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, client->id, + wm_state, wm_state, 32, 2, data); + xcb_flush(conn); +} + bool getpointer(xcb_drawable_t win, int16_t *x, int16_t *y) { xcb_query_pointer_reply_t *pointer; @@ -3112,6 +3131,13 @@ void handle_keypress(xcb_key_press_event_t *ev) nextscreen(); break; + case KEY_ICONIFY: + if (conf.allowicons) + { + hide(focuswin); + } + break; + default: /* Ignore other keys. */ break; diff --git a/mcwm.man b/mcwm.man index 1ef4864..c2b5eaa 100644 --- a/mcwm.man +++ b/mcwm.man @@ -74,44 +74,57 @@ Note that the mouse cursor needs to be inside the window you want to move, raise/lower or resize even if it currently has the focus. This is a feature, not a bug. .PP -Mod4 + key: +Mod4 + key on focused window: .RS .IP \(bu 2 .B r -raise or lower (toggles) +raise or lower (toggles). .IP \(bu 2 .B x -maximize (toggles) +maximize (toggles). .IP \(bu 2 .B m -maximize vertically (toggles) +maximize vertically (toggles). +.IP \(bu 2 +.B H +resize left. +.IP \(bu 2 +.B J +resize down. +.IP \(bu 2 +.B K +resize up. +.IP \(bu 2 +.B L +resize right. .IP \(bu 2 .B h -move left +move left. .IP \(bu 2 .B j -move down +move down. .IP \(bu 2 .B k -move up +move up. .IP \(bu 2 .B l -move right +move right. .IP \(bu 2 -.B H -resize left +.B y +move to upper left corner of physical screen. .IP \(bu 2 -.B J -resize down +.B u +move to upper right corner of physical screen. .IP \(bu 2 -.B K -resize up +.B b +move to lower left corner of physical screen. .IP \(bu 2 -.B L -resize right +.B n +move to lower right corner of physical screen. .IP \(bu 2 .B Return -start terminal +start terminal or whatever program you have configured with -t or in +the config.h. .IP \(bu 2 .B Tab go to next window in the current workspace window ring. If you release @@ -120,28 +133,22 @@ window. A new press of MODKEY + Tab will bring you back to the window where you last had focus. .IP \(bu 2 .B f -fix window so it is visible on all workspaces. Toggles. Press again to -unfix window. Also used to move windows between workspaces: First fix -the window, change to the workspace you want, then unfix the window on -the new workspace. -.IP \(bu 2 -.B y -move to upper left corner of physical screen. -.IP \(bu 2 -.B u -move to upper right corner of physical screen.. +fix window so it is visible on all workspaces (toggles). Press again +to unfix window. Also used to move windows between workspaces: First +fix the window, change to the workspace you want, then unfix the +window on the new workspace. .IP \(bu 2 -.B b -move to lower left corner of physical screen.. -.IP \(bu 2 -.B n -move to lower right corner of physical screen.. +.B i +iconify (or hide) window from the display. Only usable when mcwm has +been started with -i. Currently there is no way to get a hidden window +back. You have to use an external program such as a panel or the 9icon +script in the mcwm distribution. .IP \(bu 2 .B 0\-9 go to workspace n, 0-9. .IP \(bu 2 .B End -close focused window. +close window. .IP \(bu 2 .B , move window to previous physical screen. -- cgit v1.2.3 From b59c146f9c282c2a3cbcd7d6378d89de38e41811 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 28 Feb 2012 12:09:14 +0100 Subject: New program, hidden. --- Makefile | 2 +- hidden.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 hidden.c diff --git a/Makefile b/Makefile index fdb94fe..f72f875 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ LDFLAGS+=-L/usr/local/lib -lxcb -lxcb-randr -lxcb-keysyms -lxcb-icccm \ RM=/bin/rm PREFIX=/usr/local -TARGETS=mcwm +TARGETS=mcwm hidden OBJS=mcwm.o list.o all: $(TARGETS) diff --git a/hidden.c b/hidden.c new file mode 100644 index 0000000..c86bedb --- /dev/null +++ b/hidden.c @@ -0,0 +1,215 @@ +/* + * + * hidden - A small program to listen all windows with WM_STATE set to + * Iconic. + * + * Copyright (c) 2012 Michael Cardell Widerkrantz, mc at the domain + * hack.org. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +xcb_connection_t *conn; +xcb_screen_t *screen; + +xcb_atom_t wm_state; +xcb_atom_t wm_icon_name; + +static uint32_t get_wm_state(xcb_drawable_t win); +static int findhidden(void); +static void init(void); +static void cleanup(void); +static xcb_atom_t getatom(char *atom_name); + +uint32_t get_wm_state(xcb_drawable_t win) +{ + xcb_get_property_reply_t *reply; + xcb_get_property_cookie_t cookie; + uint32_t *statep; + uint32_t state = 0; + + cookie = xcb_get_property(conn, false, win, wm_state, wm_state, 0, + sizeof (int32_t)); + + reply = xcb_get_property_reply(conn, cookie, NULL); + if (NULL == reply) + { + fprintf(stderr, "mcwm: Couldn't get properties for win %d\n", win); + return -1; + } + + /* Length is 0 if we didn't find it. */ + if (0 == xcb_get_property_value_length(reply)) + { + goto bad; + } + + statep = xcb_get_property_value(reply); + state = *statep; + +bad: + free(reply); + return state; +} + +/* + * List all hidden windows. + * + */ +int findhidden(void) +{ + xcb_query_tree_reply_t *reply; + int i; + int len; + xcb_window_t *children; + xcb_get_window_attributes_reply_t *attr; + uint32_t state; + xcb_get_property_cookie_t cookie; + xcb_icccm_get_text_property_reply_t prop; + xcb_generic_error_t *error; + + /* Get all children. */ + reply = xcb_query_tree_reply(conn, + xcb_query_tree(conn, screen->root), 0); + if (NULL == reply) + { + return -1; + } + + len = xcb_query_tree_children_length(reply); + children = xcb_query_tree_children(reply); + + /* List all hidden windows on this root. */ + for (i = 0; i < len; i ++) + { + attr = xcb_get_window_attributes_reply( + conn, xcb_get_window_attributes(conn, children[i]), NULL); + + if (!attr) + { + fprintf(stderr, "Couldn't get attributes for window %d.", + children[i]); + continue; + } + + /* + * Don't bother windows in override redirect mode. + * + * This mode means they wouldn't have been reported to us + * with a MapRequest if we had been running, so in the + * normal case we wouldn't have seen them. + */ + if (!attr->override_redirect) + { + state = get_wm_state(children[i]); + if (state == XCB_ICCCM_WM_STATE_ICONIC) + { + /* + * Example names: + * + * _NET_WM_ICON_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76, 0x74 + * WM_ICON_NAME(STRING) = "urxvt" + * _NET_WM_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76, 0x74 + * WM_NAME(STRING) = "urxvt" + */ + cookie = xcb_icccm_get_wm_icon_name(conn, children[i]); + xcb_icccm_get_wm_icon_name_reply(conn, cookie, &prop, &error); + + puts(prop.name); + } + } /* if not override redirect */ + + free(attr); + } /* for */ + + free(reply); + + return 0; +} + +void init(void) +{ + int scrno; + xcb_screen_iterator_t iter; + + conn = xcb_connect(NULL, &scrno); + if (!conn) + { + fprintf(stderr, "can't connect to an X server\n"); + exit(1); + } + + iter = xcb_setup_roots_iterator(xcb_get_setup(conn)); + + for (int i = 0; i < scrno; ++i) + { + xcb_screen_next(&iter); + } + + screen = iter.data; + + if (!screen) + { + fprintf(stderr, "can't get the current screen\n"); + xcb_disconnect(conn); + exit(1); + } +} + +void cleanup(void) +{ + xcb_disconnect(conn); +} + +/* + * Get a defined atom from the X server. + */ +xcb_atom_t getatom(char *atom_name) +{ + xcb_intern_atom_cookie_t atom_cookie; + xcb_atom_t atom; + xcb_intern_atom_reply_t *rep; + + atom_cookie = xcb_intern_atom(conn, 0, strlen(atom_name), atom_name); + rep = xcb_intern_atom_reply(conn, atom_cookie, NULL); + if (NULL != rep) + { + atom = rep->atom; + free(rep); + return atom; + } + + /* + * XXX Note that we return 0 as an atom if anything goes wrong. + * Might become interesting. + */ + return 0; +} + +int main(void) +{ + + init(); + + wm_state = getatom("WM_STATE"); + + findhidden(); + cleanup(); + exit(0); +} -- cgit v1.2.3 From c5e912c86c94addd9bdc97d6b954396648ae1a0d Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 5 Mar 2012 07:51:11 +0100 Subject: Quote the window name. It might contain spaces or shell glob symbols. --- scripts/9icon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/9icon b/scripts/9icon index dded416..73edc6e 100755 --- a/scripts/9icon +++ b/scripts/9icon @@ -12,7 +12,7 @@ for win in $(xwininfo -root -children | awk '$1~/0x/ && $2~/"/ {print $1}'); do awk -F'"' -v win=$win ' /^WM_NAME/ { name=$2 } /window state: Iconic/ { - print name "'\''" ":xdotool windowmap " win " windowraise " win "'\''" + print "'\''" name "'\''" "'\''" ":xdotool windowmap " win " windowraise " win "'\''" } ' done | xargs 9menu -popup -label 9icon -bg grey20 -fg grey80 -font fixed -- cgit v1.2.3 From c2dde967dacf9f8eee6de468cacb25859e82a550 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 5 Mar 2012 08:19:40 +0100 Subject: Added title shell function. --- mcwm.man | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/mcwm.man b/mcwm.man index c2b5eaa..1ceacb7 100644 --- a/mcwm.man +++ b/mcwm.man @@ -1,4 +1,4 @@ -.TH mcwm 1 "Nov 07, 2011" "" "" +.TH mcwm 1 "Mar 05, 2012" "" "" .SH NAME mcwm \- MC's Window Manager for X11. .SH SYNOPSIS @@ -208,5 +208,31 @@ Christian Neukirchen wrote a little script you can use to get iconified windows mapped again if you are running mcwm in allow icons mode (-i). You need awk, xdotool, xprop and xwininfo installed. You can the script as scripts/9icon. +.PP +You might also be interested in the following shell function that +might come in handy to give your terminal emulators good titles before +hiding them. +.sp +.in +4 +.nf +# Set the title and icon name of an xterm or clone. +function title +{ + # icon name + echo -e '\\033]1;'$1'\\007' + # title + echo -e '\\033]2;'$1'\\007' +} +.fi +.in -4 +.sp +Use it like this: +.sp +.in +4 +.nf +% title 'really descriptive title' +.fi +.in -4 +.sp .SH AUTHOR Michael Cardell Widerkrantz . -- cgit v1.2.3 From 983a495af0a29a24df3d1d4023bc23de4d496d9f Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 5 Mar 2012 11:30:57 +0100 Subject: Obey display part of DISPLAY. --- mcwm.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/mcwm.c b/mcwm.c index b95240e..f15a4ff 100644 --- a/mcwm.c +++ b/mcwm.c @@ -4104,7 +4104,8 @@ int main(int argc, char **argv) char *focuscol; char *unfocuscol; char *fixedcol; - + int scrno; + /* Install signal handlers. */ /* We ignore child exists. Don't create zombies. */ @@ -4178,15 +4179,29 @@ int main(int argc, char **argv) } /* switch */ } - conn = xcb_connect(NULL, NULL); + conn = xcb_connect(NULL, &scrno); if (xcb_connection_has_error(conn)) { perror("xcb_connect"); exit(1); } - - /* Get the first screen */ - screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; + + xcb_screen_iterator_t iter + = xcb_setup_roots_iterator(xcb_get_setup(conn)); + + for (int i = 0; i < scrno; ++ i) + { + xcb_screen_next(&iter); + } + + screen = iter.data; + if (!screen) + { + fprintf (stderr, "mcwm: Can't get the current screen. Exiting.\n"); + xcb_disconnect(conn); + exit(1); + } + root = screen->root; PDEBUG("Screen size: %dx%d\nRoot window: %d\n", screen->width_in_pixels, @@ -4210,7 +4225,8 @@ int main(int argc, char **argv) /* Loop over all clients and set up stuff. */ if (0 != setupscreen()) { - fprintf(stderr, "Failed to initialize windows. Exiting.\n"); + fprintf(stderr, "mcwm: Failed to initialize windows. Exiting.\n"); + xcb_disconnect(conn); exit(1); } @@ -4218,6 +4234,7 @@ int main(int argc, char **argv) if (0 != setupkeys()) { fprintf(stderr, "mcwm: Couldn't set up keycodes. Exiting."); + xcb_disconnect(conn); exit(1); } -- cgit v1.2.3 From 05b85be1e7bfb75e453920d452d05b50fdece3c9 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 5 Mar 2012 11:38:00 +0100 Subject: US_POSITION should probably be set when hiding windows. --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index bf7f083..d7d5b00 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,8 @@ -*- text -*- +* When hiding a window always set XCB_ICCCM_SIZE_HINT_US_POSITION so + the window will be mapped where it was when it was unmapped. + * Feature: Handle several screens (DISPLAY=0.x) in classical X. This means we will have several root windows. -- cgit v1.2.3 From e68d58b454f32a95423048a288a543f4d6c29d01 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 5 Mar 2012 11:39:37 +0100 Subject: Only get the pointer position if we're going to use it when mapping a new window. If we don't have the pointer position, use the window's coordinates to find the physical screen. Should have been used anyway. --- mcwm.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/mcwm.c b/mcwm.c index f15a4ff..814083f 100644 --- a/mcwm.c +++ b/mcwm.c @@ -978,8 +978,6 @@ void fitonscreen(struct client *client) */ void newwin(xcb_window_t win) { - int16_t pointx; - int16_t pointy; struct client *client; if (NULL != findclient(win)) @@ -993,14 +991,6 @@ void newwin(xcb_window_t win) return; } - /* Get pointer position so we can move the window to the cursor. */ - if (!getpointer(screen->root, &pointx, &pointy)) - { - PDEBUG("Failed to get pointer coords!\n"); - pointx = 0; - pointy = 0; - } - /* * Set up stuff, like borders, add the window to the client list, * et cetera. @@ -1017,12 +1007,23 @@ void newwin(xcb_window_t win) /* * If the client doesn't say the user specified the coordinates - * for the window we store it where our pointer is instead. + * for the window we map it where our pointer is instead. */ if (!client->usercoord) { + int16_t pointx; + int16_t pointy; PDEBUG("Coordinates not set by user. Using pointer: %d,%d.\n", pointx, pointy); + + /* Get pointer position so we can move the window to the cursor. */ + if (!getpointer(screen->root, &pointx, &pointy)) + { + PDEBUG("Failed to get pointer coords!\n"); + pointx = 0; + pointy = 0; + } + client->x = pointx; client->y = pointy; @@ -1036,7 +1037,7 @@ void newwin(xcb_window_t win) /* Find the physical output this window will be on if RANDR is active. */ if (-1 != randrbase) { - client->monitor = findmonbycoord(pointx, pointy); + client->monitor = findmonbycoord(client->x, client->y); if (NULL == client->monitor) { /* -- cgit v1.2.3 From 76ab4565f205b973a7f9f0a9d526e24202d42604 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 5 Mar 2012 11:43:00 +0100 Subject: Added news. --- NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS b/NEWS index c07c4ae..5a4a5ee 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,12 @@ User visible changes +2012-03-05 + + * New key: MODKEY + i hides windows. + + * New program: hidden. Lists hidden windows. + 2012-02-15 * Added option -i to allow icons. -- cgit v1.2.3 From 350e8df632cf0780766707914f9703465a7c9f5f Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 6 Mar 2012 14:05:32 +0100 Subject: Declare variable iter at top of block. Added comments. --- mcwm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mcwm.c b/mcwm.c index 814083f..1bfced2 100644 --- a/mcwm.c +++ b/mcwm.c @@ -4106,6 +4106,7 @@ int main(int argc, char **argv) char *unfocuscol; char *fixedcol; int scrno; + xcb_screen_iterator_t iter; /* Install signal handlers. */ @@ -4179,7 +4180,11 @@ int main(int argc, char **argv) exit(0); } /* switch */ } - + + /* + * Use $DISPLAY. After connecting scrno will contain the value of + * the display's screen. + */ conn = xcb_connect(NULL, &scrno); if (xcb_connection_has_error(conn)) { @@ -4187,9 +4192,8 @@ int main(int argc, char **argv) exit(1); } - xcb_screen_iterator_t iter - = xcb_setup_roots_iterator(xcb_get_setup(conn)); - + /* Find our screen. */ + iter = xcb_setup_roots_iterator(xcb_get_setup(conn)); for (int i = 0; i < scrno; ++ i) { xcb_screen_next(&iter); -- cgit v1.2.3 From af7d2118ef241da20570bf448cb006c598e56d7e Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 6 Mar 2012 14:37:55 +0100 Subject: Whitespace and indentation. Removed superflous word from comment. --- mcwm.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/mcwm.c b/mcwm.c index 1bfced2..b59fa1a 100644 --- a/mcwm.c +++ b/mcwm.c @@ -131,7 +131,6 @@ typedef enum { KEY_MAX } key_enum_t; - struct monitor { xcb_randr_output_t id; @@ -383,7 +382,6 @@ static xcb_atom_t getatom(char *atom_name); */ void finishtabbing(void) { - mode = 0; if (NULL != lastfocuswin) @@ -749,9 +747,7 @@ uint32_t getcolor(const char *colstr) xcb_alloc_named_color_cookie_t colcookie; colormap = screen->default_colormap; - colcookie = xcb_alloc_named_color(conn, colormap, strlen(colstr), colstr); - col_reply = xcb_alloc_named_color_reply(conn, colcookie, &error); if (NULL != error) { @@ -838,7 +834,6 @@ void forgetwin(xcb_window_t win) } free(item->data); - delitem(&winlist, item); return; @@ -1912,7 +1907,6 @@ void movewindow(xcb_drawable_t win, uint16_t x, uint16_t y) | XCB_CONFIG_WINDOW_Y, values); xcb_flush(conn); - } /* Change focus to next in window ring. */ @@ -2635,8 +2629,8 @@ void hide(struct client *client) /* * Unmap window and declare iconic. * - * Unmapping will generate an even UnmapNotify event so we can - * forget about the window later. + * Unmapping will generate an UnmapNotify event so we can forget + * about the window later. */ xcb_unmap_window(conn, client->id); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, client->id, @@ -2648,9 +2642,8 @@ bool getpointer(xcb_drawable_t win, int16_t *x, int16_t *y) { xcb_query_pointer_reply_t *pointer; - pointer = xcb_query_pointer_reply( - conn, xcb_query_pointer(conn, win), 0); - + pointer + = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, win), 0); if (NULL == pointer) { return false; @@ -2669,9 +2662,8 @@ bool getgeom(xcb_drawable_t win, int16_t *x, int16_t *y, uint16_t *width, { xcb_get_geometry_reply_t *geom; - geom = xcb_get_geometry_reply(conn, - xcb_get_geometry(conn, win), NULL); - + geom + = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, win), NULL); if (NULL == geom) { return false; @@ -2770,7 +2762,6 @@ void topright(void) xcb_flush(conn); } - void botleft(void) { int16_t pointx; -- cgit v1.2.3 From d29aae229b96de7d33d9887ec3784cb2f1b3cd67 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 6 Mar 2012 15:05:24 +0100 Subject: Added a lot about EWMH. Removed stuff already done. Changed "physical screen" and all "screen" that refers to monitors to "monitor". Slightly less confusing. --- TODO | 103 +++++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 33 deletions(-) diff --git a/TODO b/TODO index d7d5b00..cd1d4a9 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,23 @@ -*- text -*- -* When hiding a window always set XCB_ICCCM_SIZE_HINT_US_POSITION so - the window will be mapped where it was when it was unmapped. +* IconicState + + Currently we set IconicState only on windows we hide and not when we + unmap them to switch to another desktop. ICCCM and EWMH says we + should set IconicState in both situations. + + We should also set _NET_WM_STATE_HIDDEN when hiding windows. + + hidden.c should list windows with _NET_WM_STATE_HIDDEN and, + optionally, all with IconicState. + +* When hiding a window we want it to re-appear in the same position. + How? + + Setting XCB_ICCCM_SIZE_HINT_US_POSITION before hiding would work + without adding more code, but does ICCCM allow that? + + PPosition? * Feature: Handle several screens (DISPLAY=0.x) in classical X. @@ -19,7 +35,38 @@ * Bug: Ignore other modifiers, such as NumLock and CapsLock. -* Use the new xcb-ewmh for the EWMH hints. + We can use something like this to find the modifier mask for + NumLock: + + xcb_keycode_t *num_lock; + num_lock = xcb_key_symbols_get_keycode(symbols, XK_Num_Lock); + + and get an array of keycodes finished by XCB_NO_SYMBOL. + + then compare the keycodes in the array with the keycodes all the + modifier masks give. See getmodkeys(). + +* Extended Window Manager Hints (EWMH) + + - Use the new xcb-ewmh for the EWMH hints. + + I suggest listing least these in _NET_SUPPORTED (* marks + implemented): + + _NET_NUMBER_OF_DESKTOPS, _NET_WM_DESKTOP*, _NET_CURRENT_DESKTOP, + _NET_WM_STATE, _NET_WM_STATE_STICKY, + _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_HIDDEN, + _NET_WM_STATE_FULLSCREEN, _NET_ACTIVE_WINDOW + + _NET_NUMBER_OF_DESKTOPS can be set to the constant WORKSPACES. + + _NET_CURRENT_DESKTOP is just curws. Set the hint when starting and + when changing workspaces. + + We *may* want to support a message to the root window that *sets* + _NET_CURRENT_DESKTOP and then switch to it. + + We might want to support _NET_WM_WINDOW_TYPE_DESKTOP as well. * Bug: We grab MODKEY all the time! We can grab it only when we start tabbing instead and release it when tabbing is complete. @@ -35,24 +82,24 @@ * Full-screen windows that are resized from client requests should be kept full-screen. -* When moving windows between physical screens, try to place the - window on roughly the same place on a new screen, if possible. +* When moving windows between monitors, try to place the window on + roughly the same place on a new monitor, if possible. -* When a window tries to map itself outside the physical screens, - always map it to the screen closest to the coordinates it asked for - instead of always mapping on the first screen in the list. +* When a window tries to map itself outside the monitors always map it + on the monitor closest to the coordinates it asked for instead of + always mapping on the first monitor in the list. * Feature: We need to continue dragging for move and resize until *both* MODKEY and mouse button has been released. Will be much nicer with trackball. -* Move to first window (or middle of screen) on another screen - with MODKEY + . and , instead of moving windows to new screen. - Shifted these keys will move window to new screen? +* Move to first window (or middle of monitor) on another monitor with + MODKEY + . and , instead of moving windows to new monitor. Shifted + these keys will move window to new monitor? * Handle new modes on physical outputs. What do we have to do? -* A separate workspace list for every physical output. +* A separate workspace list for every monitor. * Allow hexadecimal colour values on command line. @@ -87,20 +134,16 @@ incompatible with the EWMH _NET_WM_DESKTOP hint we're currently using: We will only be able to save one of the desktops used. -* Hide windows - - Instead of iconifying, hide them à la 9wm. Even if we use a key to - hide them, this probably means we have to have a menu to get them - back. Perhaps use an external program somehow? Needs to talk to mcwm - anyway. Unix socket? - * Menu - We might need a menu for hidden windows (see above). Since I'm - probably implementing menu windows anyway, perhaps I should add a - menu with basic window functions, like 9wm and twm. This way, one - might use the window manager without keyboard, if necessary. Not - much work if I have to do the menu anyway... But also chords? + We might need a menu for hidden windows. Since I'm probably + implementing menu windows anyway, perhaps I should add a menu with + basic window functions, like 9wm and twm. This way, one might use + the window manager without keyboard, if necessary. Not much work if + I have to do the menu anyway... But also chords? + + On the other hand, see hidden.c and forthcoming external menu + program. * Chords @@ -133,13 +176,6 @@ the BEL character). Do we want to handle it? How do we tell the user? Can this be done with some stand-alone program instead? -* Support sensible portions of ICCCM and EWMH - - EWMH hints that tells applications about active workspace and - focused window... - - And a few others. - * Code cleaning - Obivous cleanup: The event switch is way too big. @@ -147,9 +183,10 @@ - The states are known everywhere. A tight state machine would be nicer. - - Dispatch table for key bindings instead of keysym->enum->case? + - Dispatch table with function pointers for key bindings instead of + keysym->enum->case? - - Use bitfields instead of extra lists for virtual screens? + - Use bitfields instead of extra lists for workspaces? * Resize behaviour -- cgit v1.2.3 From a6e3cd2dc7485bec4a84bc2ee4694030849fb3d2 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 9 Mar 2012 15:41:30 +0100 Subject: Added option -c to print title:xdotool command. Useful for combining with 9menu and similar menu programs. --- hidden.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/hidden.c b/hidden.c index c86bedb..251025c 100644 --- a/hidden.c +++ b/hidden.c @@ -1,5 +1,4 @@ /* - * * hidden - A small program to listen all windows with WM_STATE set to * Iconic. * @@ -22,6 +21,7 @@ #include #include #include +#include #include #include @@ -31,11 +31,14 @@ xcb_screen_t *screen; xcb_atom_t wm_state; xcb_atom_t wm_icon_name; +bool printcommand = false; + static uint32_t get_wm_state(xcb_drawable_t win); static int findhidden(void); static void init(void); static void cleanup(void); static xcb_atom_t getatom(char *atom_name); +static void printhelp(void); uint32_t get_wm_state(xcb_drawable_t win) { @@ -123,15 +126,24 @@ int findhidden(void) /* * Example names: * - * _NET_WM_ICON_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76, 0x74 - * WM_ICON_NAME(STRING) = "urxvt" - * _NET_WM_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76, 0x74 - * WM_NAME(STRING) = "urxvt" + * _NET_WM_ICON_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, + * 0x76, 0x74 WM_ICON_NAME(STRING) = "urxvt" + * _NET_WM_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76, + * 0x74 WM_NAME(STRING) = "urxvt" */ cookie = xcb_icccm_get_wm_icon_name(conn, children[i]); xcb_icccm_get_wm_icon_name_reply(conn, cookie, &prop, &error); - puts(prop.name); + prop.name[prop.name_len] = '\0'; + if (printcommand) + { + printf("'%s':'xdotool windowmap 0x%x windowraise 0x%x'\n", + prop.name, children[i], children[i]); + } + else + { + puts(prop.name); + } } } /* if not override redirect */ @@ -202,13 +214,38 @@ xcb_atom_t getatom(char *atom_name) return 0; } -int main(void) +void printhelp(void) { + printf("hidden: Usage: hidden [-c]\n"); + printf(" -c print 9menu/xdotool compatible output.\n"); +} - init(); +int main(int argc, char **argv) +{ + int ch; /* Option character */ + while (1) + { + ch = getopt(argc, argv, "c"); + if (-1 == ch) + { + /* No more options, break out of while loop. */ + break; + } + switch (ch) + { + case 'c': + printcommand = true; + break; + + default: + printhelp(); + exit(0); + } /* switch ch */ + } /* while 1 */ + + init(); wm_state = getatom("WM_STATE"); - findhidden(); cleanup(); exit(0); -- cgit v1.2.3 From 669f39452199d4f8002b64828680842969a61f5e Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 9 Mar 2012 15:42:09 +0100 Subject: Script to use hidden with 9menu. --- scripts/mcicon | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 scripts/mcicon diff --git a/scripts/mcicon b/scripts/mcicon new file mode 100755 index 0000000..f002a55 --- /dev/null +++ b/scripts/mcicon @@ -0,0 +1,6 @@ +#! /bin/sh + +# mcicon - list iconified windows in menu and map the chosen one. +# Needs hidden (distributed with mcwm), 9menu and xdotool. + +hidden -c | xargs 9menu -popup -label 9icon -bg grey20 -fg grey80 -font 9x15 -- cgit v1.2.3 From f82fa249a05ece2d582c593a6bd3c1ec09320ae0 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 9 Mar 2012 16:08:23 +0100 Subject: Manual page for hidden. --- hidden.man | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 hidden.man diff --git a/hidden.man b/hidden.man new file mode 100644 index 0000000..2a4edeb --- /dev/null +++ b/hidden.man @@ -0,0 +1,19 @@ +.TH hidden 1 "Mar 09, 2012" "" "" +.SH NAME +hidden \- list iconified windows +.SH SYNOPSIS +.B hidden +[ +.B \-c +] + +.SH DESCRIPTION +.B hidden\fP lists all windows on an X server with WM_STATE Iconic. +.SH OPTIONS +.PP +\-c prints a command suitable to get the window back again. + +.SH ENVIRONMENT +.B hidden\fP obeys the $DISPLAY variable. +.SH AUTHOR +Michael Cardell Widerkrantz . -- cgit v1.2.3 From ad7d7c21f3c3ae9061cb6f88e09c85a645c96f35 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 9 Mar 2012 16:08:40 +0100 Subject: Install hidden and its man page. --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index f72f875..6b12876 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,8 @@ list.o: list.c list.h Makefile install: $(TARGETS) install -m 755 mcwm $(PREFIX)/bin install -m 644 mcwm.man $(PREFIX)/man/man1/mcwm.1 + install -m 755 hidden $(PREFIX)/bin + install -m 644 hidden.man $(PREFIX)/man/man1/hidden.1 deinstall: $(RM) $(PREFIX)/bin/mcwm -- cgit v1.2.3 From 40b3035803504f3afd8be66a7eb54d25a9ebc713 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 9 Mar 2012 16:09:44 +0100 Subject: Mention hidden and mcicon. Use "monitor" instead of "physical screen". Mention $DISPLAY. --- mcwm.man | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/mcwm.man b/mcwm.man index 1ceacb7..1bb43df 100644 --- a/mcwm.man +++ b/mcwm.man @@ -1,4 +1,4 @@ -.TH mcwm 1 "Mar 05, 2012" "" "" +.TH mcwm 1 "Mar 09, 2012" "" "" .SH NAME mcwm \- MC's Window Manager for X11. .SH SYNOPSIS @@ -33,8 +33,8 @@ mcwm \- MC's Window Manager for X11. \-i turns on icons/hidden windows. .B Please note that there is no way from mcwm to get a hidden window back! You have -to use an external program such as a panel or the 9icon script (see -below) to get the window mapped again. +to use an external program such as a panel or the mcicon or 9icon +scripts (see below) to get the window mapped again. .PP \-t urxvt will start urxvt when MODKEY + Return is pressed. Change to your prefered terminal program or something else entirely. @@ -111,16 +111,16 @@ move up. move right. .IP \(bu 2 .B y -move to upper left corner of physical screen. +move to upper left corner of monitor. .IP \(bu 2 .B u -move to upper right corner of physical screen. +move to upper right corner of monitor. .IP \(bu 2 .B b -move to lower left corner of physical screen. +move to lower left corner of monitor. .IP \(bu 2 .B n -move to lower right corner of physical screen. +move to lower right corner of monitor. .IP \(bu 2 .B Return start terminal or whatever program you have configured with -t or in @@ -133,16 +133,16 @@ window. A new press of MODKEY + Tab will bring you back to the window where you last had focus. .IP \(bu 2 .B f -fix window so it is visible on all workspaces (toggles). Press again -to unfix window. Also used to move windows between workspaces: First -fix the window, change to the workspace you want, then unfix the -window on the new workspace. +fix window so it is visible on all workspaces (toggles). Note that +this is also used to move windows between workspaces: First fix the +window, change to the workspace you want, then unfix the window on the +new workspace. .IP \(bu 2 .B i iconify (or hide) window from the display. Only usable when mcwm has been started with -i. Currently there is no way to get a hidden window -back. You have to use an external program such as a panel or the 9icon -script in the mcwm distribution. +back. You have to use an external program such as a panel or the +mcicon or 9icon script in the mcwm distribution. .IP \(bu 2 .B 0\-9 go to workspace n, 0-9. @@ -151,10 +151,10 @@ go to workspace n, 0-9. close window. .IP \(bu 2 .B , -move window to previous physical screen. +move window to previous monitor. .IP \(bu 2 .B . -move window to next physical screen. +move window to next monitor. .RE .PP Note that all functions activated from the keyboard work on the @@ -167,7 +167,8 @@ look in the config.h file, change and recompile. In the config.h file you can also define mouse button actions on the root window. By default button 3 starts the command mcmenu. You can write your own mcmenu by using, for instance, 9menu, dmenu or ratmenu. -.PP +.SH ENVIRONMENT +.B mcwm\fP obeys the $DISPLAY variable. .SH STARTING Typically the window manager is started from a script, either run by .B startx(1) @@ -198,16 +199,20 @@ exec urxvt .fi .in -4 .sp -.PP .SH SCRIPTS You may want to define a menu program for use with mcwm (see config.h). In the source distribution you can find an example as -mcmenu in the scripts directory. +mcmenu (the default menu program in config.h) in the scripts +directory. .PP Christian Neukirchen wrote a little script you can use to get iconified windows mapped again if you are running mcwm in allow icons mode (-i). You need awk, xdotool, xprop and xwininfo installed. You -can the script as scripts/9icon. +can find the script as scripts/9icon. +.PP +Inspired by Christian's work I wrote a small program, hidden(1), which +is included with mcwm. You can use hidden(1) with the -c option +together with 9menu. See scripts/mcicon for an example. .PP You might also be interested in the following shell function that might come in handy to give your terminal emulators good titles before @@ -234,5 +239,7 @@ Use it like this: .fi .in -4 .sp +.SH SEE ALSO +.B hidden(1) .SH AUTHOR Michael Cardell Widerkrantz . -- cgit v1.2.3 From e5509ae6814092303af973e27c2bf7d87969d15f Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 9 Mar 2012 16:15:41 +0100 Subject: Remove hidden and its man page when deinstalling. uninstall alias for deinstall. --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 6b12876..9d2f8c8 100644 --- a/Makefile +++ b/Makefile @@ -32,9 +32,12 @@ install: $(TARGETS) install -m 755 hidden $(PREFIX)/bin install -m 644 hidden.man $(PREFIX)/man/man1/hidden.1 +uninstall: deinstall deinstall: $(RM) $(PREFIX)/bin/mcwm $(RM) $(PREFIX)/man/man1/mcwm.1 + $(RM) $(PREFIX)/bin/hidden + $(RM) $(PREFIX)/man/man1/hidden.1 $(DIST).tar.bz2: mkdir $(DIST) -- cgit v1.2.3 From 66d82b3ab1d00a37d266c8f199cc430fd76afe8c Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Sun, 25 Mar 2012 09:24:46 +0200 Subject: No point in printing that we don't have RANDR in production. Make it a debug printout. --- mcwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcwm.c b/mcwm.c index b59fa1a..c8764e4 100644 --- a/mcwm.c +++ b/mcwm.c @@ -1457,7 +1457,7 @@ int setuprandr(void) extension = xcb_get_extension_data(conn, &xcb_randr_id); if (!extension->present) { - printf("No RANDR.\n"); + PDEBUG("No RANDR extension.\n"); return -1; } else -- cgit v1.2.3 From 1a7c3614b9bc813e96a79c73e509d8e63d710ea4 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Mon, 30 Apr 2012 10:43:31 +0200 Subject: width should also be optional. --- mcwm.man | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcwm.man b/mcwm.man index 1bb43df..265a769 100644 --- a/mcwm.man +++ b/mcwm.man @@ -1,11 +1,11 @@ -.TH mcwm 1 "Mar 09, 2012" "" "" +.TH mcwm 1 "Apr 30, 2012" "" "" .SH NAME mcwm \- MC's Window Manager for X11. .SH SYNOPSIS .B mcwm [ .B \-b -] width +width ] [ .B \-i ] -- cgit v1.2.3 From 6e854c96cd52f58dbf963e6aa959a46c43a2bc59 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 30 Oct 2012 08:40:12 +0100 Subject: Typo. --- config.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.h b/config.h index bb1678f..f26fa6b 100644 --- a/config.h +++ b/config.h @@ -39,7 +39,8 @@ #define ALLOWICONS false /* - * Start these programs when pressing MODKEY and mouse buttons on root window. + * Start these programs when pressing MOUSEMODKEY and mouse buttons on + * root window. */ #define MOUSE1 "" #define MOUSE2 "" -- cgit v1.2.3 From 005c0ea215ba050976db795ad2b0382aadf18b5e Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Tue, 30 Oct 2012 08:57:55 +0100 Subject: Small menu program using only XCB. Not finished. --- mcmenu.c | 517 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 mcmenu.c diff --git a/mcmenu.c b/mcmenu.c new file mode 100644 index 0000000..a8fdac8 --- /dev/null +++ b/mcmenu.c @@ -0,0 +1,517 @@ +/* + * mcmenu - small menu program using only XCB. + * + * MC, mc at the domain hack.org + * http://hack.org/mc/ + * + * Copyright (c) 2010, 2011, 2012 Michael Cardell Widerkrantz, mc at + * the domain hack.org. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +/* + * FIXME calculate height and width. + * How? We get font size *after* opening a window! Resize afterwards? + * + * Can I ask a font about information before using setfont()? I need + * pixel sizes. + * + */ +#define WIDTH 100 +#define HEIGHT 200 + +xcb_connection_t *conn; +xcb_screen_t *screen; + +int sigcode; /* Signal code. Non-zero if we've been + * interruped by a signal. */ +xcb_keycode_t keycode_j; +xcb_keycode_t keycode_k; +xcb_keycode_t keycode_ret; + +struct font +{ + char *name; + /* width, height. */ +}; + +struct window +{ + xcb_window_t id; + xcb_gc_t curfontc; +}; + +static uint32_t getcolor(const char *); +static int setfont(struct window *, const char *, const char *, const char *); +static void printat(struct window *, int16_t, int16_t, const char *); +static struct window *window(int16_t, int16_t, uint16_t, uint16_t); +static void init(void); +static void cleanup(void); +static xcb_keycode_t keysymtokeycode(xcb_keysym_t, xcb_key_symbols_t *); +static void grabkeys(struct window *); +static void printrows(struct window *, char *[], int, int); +static void invertrow(struct window *, char *[], int, int); +static void normalrow(struct window *, char *[], int, int); +static int keypress(xcb_key_press_event_t *, struct window *, char *[], int, + int, int); +static void redraw(struct window *, char *[], int, int, int); + +/* + * Get the pixel values of a named colour colstr. + * + * Returns pixel values. + */ +uint32_t getcolor(const char *colstr) +{ + xcb_alloc_named_color_reply_t *col_reply; + xcb_colormap_t colormap; + xcb_generic_error_t *error; + xcb_alloc_named_color_cookie_t colcookie; + + colormap = screen->default_colormap; + + colcookie = xcb_alloc_named_color(conn, colormap, strlen(colstr), colstr); + + col_reply = xcb_alloc_named_color_reply(conn, colcookie, &error); + if (NULL != error) + { + fprintf(stderr, "mcwm: Couldn't get pixel value for colour %s. " + "Exiting.\n", colstr); + + xcb_disconnect(conn); + exit(1); + } + + return col_reply->pixel; +} + +int setfont(struct window *win, const char *fontname, const char *fg, + const char *bg) +{ + uint32_t fgcol; /* Focused border colour. */ + uint32_t bgcol; /* Focused border colour. */ + xcb_font_t font; + xcb_gcontext_t gc; + uint32_t mask; + uint32_t values[3]; + + fgcol = getcolor(fg); + bgcol = getcolor(bg); + + font = xcb_generate_id(conn); + xcb_open_font(conn, font, strlen(fontname), fontname); + + gc = xcb_generate_id(conn); + mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; + values[0] = fgcol; + values[1] = bgcol; + values[2] = font; + xcb_void_cookie_t cookie = xcb_create_gc_checked(conn, gc, win->id, mask, + values); + + xcb_generic_error_t *error = xcb_request_check(conn, cookie); + if (error) + { + fprintf(stderr, "ERROR: can't print text : %d\n", error->error_code); + xcb_disconnect(conn); + exit(-1); + } + + xcb_close_font(conn, font); + + win->curfontc = gc; + + return 0; +} + +void printat(struct window *win, int16_t x, int16_t y, const char *text) +{ + xcb_void_cookie_t cookie; + xcb_generic_error_t *error; + + cookie = xcb_image_text_8_checked(conn, strlen(text), + win->id, win->curfontc, x, y, text); + + error = xcb_request_check(conn, cookie); + + if (error) + { + fprintf(stderr, "ERROR: can't print text : %d\n", error->error_code); + xcb_disconnect(conn); + exit(-1); + } + + xcb_flush(conn); +} + +struct window *window(int16_t x, int16_t y, uint16_t width, uint16_t height) +{ + struct window *win; + xcb_void_cookie_t cookie; + uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + uint32_t values[2]; + + win = malloc(sizeof (struct window)); + if (NULL == win) + { + perror("malloc"); + return NULL; + } + + values[0] = screen->black_pixel; + values[1] = XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_POINTER_MOTION; + + win->id = xcb_generate_id(conn); + + cookie = xcb_create_window(conn, screen->root_depth, win->id, screen->root, + x, y, + width, height, + 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, + mask, values); + + xcb_map_window(conn, win->id); + + xcb_flush(conn); + + return win; +} + +void init(void) +{ + int scrno; + xcb_screen_iterator_t iter; + + conn = xcb_connect(NULL, &scrno); + if (!conn) + { + fprintf(stderr, "can't connect to an X server\n"); + exit(1); + } + + iter = xcb_setup_roots_iterator(xcb_get_setup(conn)); + + for (int i = 0; i < scrno; ++i) + { + xcb_screen_next(&iter); + } + + screen = iter.data; + + if (!screen) + { + fprintf(stderr, "can't get the current screen\n"); + xcb_disconnect(conn); + exit(1); + } +} + +void cleanup(void) +{ + xcb_disconnect(conn); +} + +/* + * Get a keycode from a keysym. + * + * Returns keycode value. + */ +xcb_keycode_t keysymtokeycode(xcb_keysym_t keysym, xcb_key_symbols_t *keysyms) +{ + xcb_keycode_t *keyp; + xcb_keycode_t key; + + /* We only use the first keysymbol, even if there are more. */ + keyp = xcb_key_symbols_get_keycode(keysyms, keysym); + if (NULL == keyp) + { + fprintf(stderr, "mcmenu: Couldn't look up key. Exiting.\n"); + exit(1); + return 0; + } + + key = *keyp; + free(keyp); + + return key; +} + +void grabkeys(struct window *win) +{ + xcb_key_symbols_t *keysyms; + + /* Get all the keysymbols. */ + keysyms = xcb_key_symbols_alloc(conn); + + keycode_j = keysymtokeycode(XK_J, keysyms); + keycode_k = keysymtokeycode(XK_K, keysyms); + keycode_ret = keysymtokeycode(XK_Return, keysyms); + + xcb_grab_key(conn, 1, win->id, XCB_MOD_MASK_ANY, + keycode_j, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + + xcb_grab_key(conn, 1, win->id, XCB_MOD_MASK_ANY, + keycode_k, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + + xcb_grab_key(conn, 1, win->id, XCB_MOD_MASK_ANY, + keycode_ret, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + + xcb_flush(conn); + + /* Get rid of the key symbols table. */ + xcb_key_symbols_free(keysyms); +} + +/* + * Print some rows of text in window win, stopping at max + * automatically moving fontheight pixels down at a time. + */ +void printrows(struct window *win, char *rows[], int max, int fontheight) +{ + int i; + int y; + + if (0 != setfont(win, "6x13", "white", "black")) + { + fprintf(stderr, "Couldn't set new font.\n"); + exit(1); + } + + for (i = 0, y = fontheight; i < max; i ++, y += fontheight) + { + printat(win, 1, y, rows[i]); + } +} + +/* + * Invert row row (counting from 1). + */ +void invertrow(struct window *win, char *rows[], int row, int fontheight) +{ + int y = fontheight * row; + + if (0 != setfont(win, "6x13", "black", "white")) + { + fprintf(stderr, "Couldn't set new font.\n"); + exit(1); + } + + /* TODO Pad to window width. */ + printat(win, 1, y, rows[row - 1]); +} + +void normalrow(struct window *win, char *rows[], int row, int fontheight) +{ + int y = fontheight * row; + + if (0 != setfont(win, "6x13", "white", "black")) + { + fprintf(stderr, "Couldn't set new font.\n"); + exit(1); + } + + /* TODO Pad to window width. */ + printat(win, 1, y, rows[row - 1]); +} + +int keypress(xcb_key_press_event_t *ev, struct window *win, char *menu[], + int currow, int max, int height) +{ + int oldrow; + + oldrow = currow; + + if (ev->detail == keycode_j) + { + printf("DOWN!\n"); + currow ++; + } + else if (ev->detail == keycode_k) + { + printf("UP!\n"); + currow --; + } + else if (ev->detail == keycode_ret) + { + printf("Choice: %s\n", menu[currow - 1]); + cleanup(); + exit(0); + } + else + { + printf("Unknown key pressed.\n"); + } + + if (currow < 1) + { + currow = max; + } + else if (currow > max) + { + currow = 1; + } + + invertrow(win, menu, currow, height); + + if (currow != oldrow) + { + normalrow(win, menu, oldrow, height); + } + + return currow; +} + +void redraw(struct window *win, char *menu[], int max, int cur, int height) +{ + printrows(win, menu, max, height); + invertrow(win, menu, cur, height); +} + +int main(void) +{ + struct window *win; + char *menu[] = + { + "foo", + "gurka", + "sallad" + }; + int currow = 1; + int maxrow = 3; + char *font = "6x13"; + int fontheight = 13; + xcb_generic_event_t *ev; + int fd; /* Our X file descriptor */ + fd_set in; /* For select */ + int found; /* Ditto. */ + + init(); + + /* + * This creates a new window. I might want to have a window + * created already after init(). The default window, where the + * program was started. Of course, this won't work in X but might + * work in another window systems. + */ + win = window(1, 1, WIDTH, HEIGHT); + if (NULL == win) + { + fprintf(stderr, "Couldn't create window.\n"); + exit(1); + } + + if (0 != setfont(win, font, "white", "black")) + { + fprintf(stderr, "Couldn't set new font.\n"); + exit(1); + } + + grabkeys(win); + + redraw(win, menu, maxrow, currow, fontheight); + + /* Get the file descriptor so we can do select() on it. */ + fd = xcb_get_file_descriptor(conn); + + for (sigcode = 0; 0 == sigcode;) + { + /* Prepare for select(). */ + FD_ZERO(&in); + FD_SET(fd, &in); + + /* + * Check for events, again and again. When poll returns NULL, + * we block on select() until the event file descriptor gets + * readable again. + */ + ev = xcb_poll_for_event(conn); + if (NULL == ev) + { + printf("xcb_poll_for_event() returned NULL.\n"); + + /* Check if we have an unrecoverably error. */ + if (xcb_connection_has_error(conn)) + { + cleanup(); + exit(1); + } + + found = select(fd + 1, &in, NULL, NULL, NULL); + if (-1 == found) + { + if (EINTR == errno) + { + /* We received a signal. Break out of loop. */ + break; + } + else + { + /* Something was seriously wrong with select(). */ + fprintf(stderr, "mcwm: select failed."); + cleanup(); + exit(1); + } + } + else + { + /* We found more events. Goto start of loop. */ + continue; + } + } + + switch (ev->response_type & ~0x80) + { + /* TODO Add mouse events and mouse button click. */ + + case XCB_KEY_PRESS: + { + xcb_key_press_event_t *e = (xcb_key_press_event_t *)ev; + + printf("Key %d pressed\n", e->detail); + + currow = keypress(e, win, menu, currow, maxrow, fontheight); + } + break; + + case XCB_EXPOSE: + redraw(win, menu, maxrow, currow, fontheight); + break; + + default: + printf("Unknown event.\n"); + + } /* switch */ + } /* for */ + + cleanup(); + exit(0); +} -- cgit v1.2.3 From c2378d6e3ac349b2c8a2e3415b5b76b4edeb69c2 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Thu, 7 Feb 2013 11:15:22 +0100 Subject: Wording. --- TODO | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index cd1d4a9..9133d96 100644 --- a/TODO +++ b/TODO @@ -11,11 +11,11 @@ hidden.c should list windows with _NET_WM_STATE_HIDDEN and, optionally, all with IconicState. -* When hiding a window we want it to re-appear in the same position. +* When unhiding a window we want it to re-appear in the same position. How? - Setting XCB_ICCCM_SIZE_HINT_US_POSITION before hiding would work - without adding more code, but does ICCCM allow that? + Setting XCB_ICCCM_SIZE_HINT_US_POSITION before hiding would probably + work without adding more code, but does ICCCM allow that? PPosition? -- cgit v1.2.3 From 70af048b1ccfcbcc14e2801280a9be964ae6075e Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Thu, 7 Feb 2013 11:15:36 +0100 Subject: Added FIXME. --- hidden.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hidden.c b/hidden.c index 251025c..f2df679 100644 --- a/hidden.c +++ b/hidden.c @@ -137,6 +137,7 @@ int findhidden(void) prop.name[prop.name_len] = '\0'; if (printcommand) { + /* FIXME: Need to escape : in prop.name. */ printf("'%s':'xdotool windowmap 0x%x windowraise 0x%x'\n", prop.name, children[i], children[i]); } -- cgit v1.2.3 From 05ba38097af2e83eb78cba024dd571c9bb89f148 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Thu, 7 Feb 2013 11:15:57 +0100 Subject: Add example with -i. --- mcwm.man | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mcwm.man b/mcwm.man index 265a769..b006860 100644 --- a/mcwm.man +++ b/mcwm.man @@ -194,6 +194,9 @@ xrdb \-load ~/.Xresources # Start window manager in the background. If it dies, X still lives. mcwm & +# If you want to allow windows to be hidden, use this instead: +# mcwm -i & + # Start a terminal in the foreground. If this dies, X dies. exec urxvt .fi -- cgit v1.2.3 From d79df47289fd9754e2c84d54ada0ac42d8d93c8b Mon Sep 17 00:00:00 2001 From: Per Cederqvist Date: Thu, 7 Feb 2013 15:21:33 +0100 Subject: Added support for backtabbing. Thanks ceder! --- config.h | 3 ++- mcwm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- mcwm.man | 6 +++++ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/config.h b/config.h index f26fa6b..941f12e 100644 --- a/config.h +++ b/config.h @@ -63,7 +63,7 @@ /* * Keysym codes for window operations. Look in X11/keysymdefs.h for - * actual symbols. + * actual symbols. Use XK_VoidSymbol to disable a function. */ #define USERKEY_FIX XK_F #define USERKEY_MOVE_LEFT XK_H @@ -75,6 +75,7 @@ #define USERKEY_TERMINAL XK_Return #define USERKEY_MAX XK_X #define USERKEY_CHANGE XK_Tab +#define USERKEY_BACKCHANGE XK_VoidSymbol #define USERKEY_WS1 XK_1 #define USERKEY_WS2 XK_2 #define USERKEY_WS3 XK_3 diff --git a/mcwm.c b/mcwm.c index c8764e4..3fcfa5e 100644 --- a/mcwm.c +++ b/mcwm.c @@ -110,6 +110,7 @@ typedef enum { KEY_RET, KEY_X, KEY_TAB, + KEY_BACKTAB, KEY_1, KEY_2, KEY_3, @@ -238,6 +239,7 @@ struct keys { USERKEY_TERMINAL, 0 }, { USERKEY_MAX, 0 }, { USERKEY_CHANGE, 0 }, + { USERKEY_BACKCHANGE, 0 }, { USERKEY_WS1, 0 }, { USERKEY_WS2, 0 }, { USERKEY_WS3, 0 }, @@ -331,7 +333,7 @@ static void raiseorlower(struct client *client); static void movelim(struct client *client); static void movewindow(xcb_drawable_t win, uint16_t x, uint16_t y); static struct client *findclient(xcb_drawable_t win); -static void focusnext(void); +static void focusnext(bool reverse); static void setunfocus(xcb_drawable_t win); static void setfocus(struct client *client); static int start(char *program); @@ -1268,6 +1270,12 @@ int setupkeys(void) /* Now grab the rest of the keys with the MODKEY modifier. */ for (i = KEY_F; i < KEY_MAX; i ++) { + if (XK_VoidSymbol == keys[i].keysym) + { + keys[i].keycode = 0; + continue; + } + keys[i].keycode = keysymtokeycode(keys[i].keysym, keysyms); if (0 == keys[i].keycode) { @@ -1910,7 +1918,7 @@ void movewindow(xcb_drawable_t win, uint16_t x, uint16_t y) } /* Change focus to next in window ring. */ -void focusnext(void) +void focusnext(bool reverse) { struct client *client = NULL; @@ -1954,25 +1962,54 @@ void focusnext(void) } else { - if (NULL == focuswin->wsitem[curws]->next) + if (reverse) { - /* - * We were at the end of list. Focusing on first window in - * list unless we were already there. - */ - if (focuswin->wsitem[curws] != wslist[curws]->data) + if (NULL == focuswin->wsitem[curws]->prev) + { + /* + * We were at the head of list. Focusing on last + * window in list unless we were already there. + */ + struct item *last = wslist[curws]; + while (NULL != last->next) + last = last->next; + if (focuswin->wsitem[curws] != last->data) + { + PDEBUG("Beginning of list. Focusing last in list: %p\n", + last); + client = last->data; + } + } + else { - PDEBUG("End of list. Focusing first in list: %p\n", - wslist[curws]); - client = wslist[curws]->data; + /* Otherwise, focus the next in list. */ + PDEBUG("Tabbing. Focusing next: %p.\n", + focuswin->wsitem[curws]->prev); + client = focuswin->wsitem[curws]->prev->data; } } else { - /* Otherwise, focus the next in list. */ - PDEBUG("Tabbing. Focusing next: %p.\n", - focuswin->wsitem[curws]->next); - client = focuswin->wsitem[curws]->next->data; + if (NULL == focuswin->wsitem[curws]->next) + { + /* + * We were at the end of list. Focusing on first window in + * list unless we were already there. + */ + if (focuswin->wsitem[curws] != wslist[curws]->data) + { + PDEBUG("End of list. Focusing first in list: %p\n", + wslist[curws]); + client = wslist[curws]->data; + } + } + else + { + /* Otherwise, focus the next in list. */ + PDEBUG("Tabbing. Focusing next: %p.\n", + focuswin->wsitem[curws]->next); + client = focuswin->wsitem[curws]->next->data; + } } } /* if NULL focuswin */ @@ -2960,9 +2997,10 @@ void handle_keypress(xcb_key_press_event_t *ev) for (key = KEY_MAX, i = KEY_F; i < KEY_MAX; i ++) { - if (ev->detail == keys[i].keycode) + if (ev->detail == keys[i].keycode && 0 != keys[i].keycode) { key = i; + break; } } if (key == KEY_MAX) @@ -2979,7 +3017,7 @@ void handle_keypress(xcb_key_press_event_t *ev) return; } - if (MCWM_TABBING == mode && key != KEY_TAB) + if (MCWM_TABBING == mode && key != KEY_TAB && key != KEY_BACKTAB) { /* First finish tabbing around. Then deal with the next key. */ finishtabbing(); @@ -3006,6 +3044,10 @@ void handle_keypress(xcb_key_press_event_t *ev) resizestep(focuswin, 'l'); break; + case KEY_TAB: /* shifted tab counts as backtab */ + focusnext(true); + break; + default: /* Ignore other shifted keys. */ break; @@ -3040,7 +3082,11 @@ void handle_keypress(xcb_key_press_event_t *ev) break; case KEY_TAB: /* tab */ - focusnext(); + focusnext(false); + break; + + case KEY_BACKTAB: /* backtab */ + focusnext(true); break; case KEY_M: /* m */ diff --git a/mcwm.man b/mcwm.man index b006860..24304ab 100644 --- a/mcwm.man +++ b/mcwm.man @@ -132,6 +132,12 @@ MODKEY or press another command key mcwm will change focus to the new window. A new press of MODKEY + Tab will bring you back to the window where you last had focus. .IP \(bu 2 +.B Shift-Tab +go to previous window in the current workspace window ring. This is +most useful while you are tabbing: if you accidentally pressed Tab one +time too many, you can move back by pressing Shift + TAB (all the +while holding down the MODKEY). +.IP \(bu 2 .B f fix window so it is visible on all workspaces (toggles). Note that this is also used to move windows between workspaces: First fix the -- cgit v1.2.3 From eadc9667af405353bc3ae5e94d3f903dc4fc4c2d Mon Sep 17 00:00:00 2001 From: Per Cederqvist Date: Fri, 8 Feb 2013 11:38:51 +0100 Subject: Added support for moving to previous and next workspace. Thanks ceder! --- config.h | 2 ++ mcwm.c | 21 ++++++++++++++++++++- mcwm.man | 6 ++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/config.h b/config.h index 941f12e..0bfb3c3 100644 --- a/config.h +++ b/config.h @@ -86,6 +86,8 @@ #define USERKEY_WS8 XK_8 #define USERKEY_WS9 XK_9 #define USERKEY_WS10 XK_0 +#define USERKEY_PREVWS XK_C +#define USERKEY_NEXTWS XK_V #define USERKEY_TOPLEFT XK_Y #define USERKEY_TOPRIGHT XK_U #define USERKEY_BOTLEFT XK_B diff --git a/mcwm.c b/mcwm.c index 3fcfa5e..fab3474 100644 --- a/mcwm.c +++ b/mcwm.c @@ -129,6 +129,8 @@ typedef enum { KEY_PREVSCR, KEY_NEXTSCR, KEY_ICONIFY, + KEY_PREVWS, + KEY_NEXTWS, KEY_MAX } key_enum_t; @@ -258,6 +260,8 @@ struct keys { USERKEY_PREVSCREEN, 0 }, { USERKEY_NEXTSCREEN, 0 }, { USERKEY_ICONIFY, 0 }, + { USERKEY_PREVWS, 0 }, + { USERKEY_NEXTWS, 0 }, }; /* All keycodes generating our MODKEY mask. */ @@ -3175,7 +3179,22 @@ void handle_keypress(xcb_key_press_event_t *ev) hide(focuswin); } break; - + + case KEY_PREVWS: + if (curws > 0) + { + changeworkspace(curws - 1); + } + else + { + changeworkspace(WORKSPACES - 1); + } + break; + + case KEY_NEXTWS: + changeworkspace((curws + 1) % WORKSPACES); + break; + default: /* Ignore other keys. */ break; diff --git a/mcwm.man b/mcwm.man index 24304ab..6d6cd4a 100644 --- a/mcwm.man +++ b/mcwm.man @@ -153,6 +153,12 @@ mcicon or 9icon script in the mcwm distribution. .B 0\-9 go to workspace n, 0-9. .IP \(bu 2 +.B c +go to previous workspace. +.IP \(bu 2 +.B v +go to next workspace. +.IP \(bu 2 .B End close window. .IP \(bu 2 -- cgit v1.2.3 From b4bf9e183df0588177fffbadab4f20357523c5a7 Mon Sep 17 00:00:00 2001 From: Per Cederqvist Date: Fri, 8 Feb 2013 11:46:32 +0100 Subject: Linkfix. Accepted with changes. Thanks. --- Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9d2f8c8..9fb3682 100644 --- a/Makefile +++ b/Makefile @@ -16,11 +16,14 @@ OBJS=mcwm.o list.o all: $(TARGETS) mcwm: $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) + $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $@ + +hidden: hidden.c + $(CC) $(CFLAGS) hidden.c $(LDFLAGS) -o $@ mcwm-static: $(OBJS) - $(CC) -o $@ $(OBJS) -static $(CFLAGS) $(LDFLAGS) \ - -lXau -lXdmcp + $(CC) $(OBJS) -static $(CFLAGS) $(LDFLAGS) \ + -lXau -lXdmcp -o $@ mcwm.o: mcwm.c events.h list.h config.h Makefile -- cgit v1.2.3 From 9d01018b3ccd1bef92d53c26de59726ccbabf9bc Mon Sep 17 00:00:00 2001 From: Per Cederqvist Date: Fri, 8 Feb 2013 11:49:16 +0100 Subject: Don't include xcb_ewmh. --- mcwm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mcwm.c b/mcwm.c index fab3474..5aa5197 100644 --- a/mcwm.c +++ b/mcwm.c @@ -47,7 +47,6 @@ #include #include -#include #ifdef DEBUG #include "events.h" -- cgit v1.2.3 From 3bfde00f8ea34eed67362484afec26b2d12a4d3b Mon Sep 17 00:00:00 2001 From: Per Cederqvist Date: Fri, 8 Feb 2013 11:51:08 +0100 Subject: Tell git to ignore some files. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eba3c85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +*.o +mcwm +hidden -- cgit v1.2.3 From 67532d88be82b9ae25ad5e57e2d2baf7e365082e Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 8 Feb 2013 12:05:18 +0100 Subject: New user visible changes documented. Bump version. --- Makefile | 2 +- NEWS | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9fb3682..bff3aaa 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=20120124 +VERSION=20130208 DIST=mcwm-$(VERSION) SRC=mcwm.c list.c config.h events.h list.h DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man $(SRC) diff --git a/NEWS b/NEWS index 5a4a5ee..58b3330 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,14 @@ User visible changes +2013-02-08 + + * New keys: MODKEY + c,v moves to previous or next workspace. Thanks + to Per Cederqvist. + + * New key: Shift-TAB moves backwards in on screen window list. + Thanks to Per Cederqvist. + 2012-03-05 * New key: MODKEY + i hides windows. -- cgit v1.2.3 From bceaf05444f1825cd205392eae128106a8c0fd3c Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Fri, 8 Feb 2013 19:12:45 +0100 Subject: Added hidden.c to SRC. Bumped version. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index bff3aaa..d9d302d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -VERSION=20130208 +VERSION=20130208-2 DIST=mcwm-$(VERSION) -SRC=mcwm.c list.c config.h events.h list.h +SRC=mcwm.c list.c config.h events.h list.h hidden.c DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man $(SRC) CFLAGS+=-g -std=c99 -Wall -Wextra -I/usr/local/include #-DDEBUG #-DDMALLOC -- cgit v1.2.3 From 95464ce8553f39f97d48b83de37dbddb553bd14d Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Sat, 9 Feb 2013 11:56:16 +0100 Subject: Include hidden.man in DISTFILES. Bump version. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d9d302d..eec997f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -VERSION=20130208-2 +VERSION=20130208-3 DIST=mcwm-$(VERSION) SRC=mcwm.c list.c config.h events.h list.h hidden.c -DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man $(SRC) +DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man hidden.man $(SRC) CFLAGS+=-g -std=c99 -Wall -Wextra -I/usr/local/include #-DDEBUG #-DDMALLOC LDFLAGS+=-L/usr/local/lib -lxcb -lxcb-randr -lxcb-keysyms -lxcb-icccm \ -- cgit v1.2.3 From d3d1c71b90824d60c0c7b927c264f35b659d4594 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Sat, 9 Feb 2013 12:00:50 +0100 Subject: Bump version. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index eec997f..6ef1fff 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=20130208-3 +VERSION=20130209 DIST=mcwm-$(VERSION) SRC=mcwm.c list.c config.h events.h list.h hidden.c DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man hidden.man $(SRC) -- cgit v1.2.3 From f20b857e33d1ffcb36ae3a4bcf38f500e24c2536 Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Sat, 9 Feb 2013 21:16:38 +0100 Subject: Include scripts directory in distribution. --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 6ef1fff..eeddc1d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -VERSION=20130209 +VERSION=20130209-2 DIST=mcwm-$(VERSION) SRC=mcwm.c list.c config.h events.h list.h hidden.c -DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man hidden.man $(SRC) +DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man hidden.man scripts $(SRC) CFLAGS+=-g -std=c99 -Wall -Wextra -I/usr/local/include #-DDEBUG #-DDMALLOC LDFLAGS+=-L/usr/local/lib -lxcb -lxcb-randr -lxcb-keysyms -lxcb-icccm \ @@ -44,7 +44,7 @@ deinstall: $(DIST).tar.bz2: mkdir $(DIST) - cp $(DISTFILES) $(DIST)/ + cp -r $(DISTFILES) $(DIST)/ tar cf $(DIST).tar --exclude .git $(DIST) bzip2 -9 $(DIST).tar $(RM) -rf $(DIST) -- cgit v1.2.3