summaryrefslogtreecommitdiff
path: root/mcwm.c
diff options
context:
space:
mode:
authorMC <mc@hack.org>2010-07-09 23:03:50 +0200
committerMC <mc@brain.hack.org>2010-07-09 23:03:50 +0200
commite451e99ff498b7238e0a8ddab601f14588bb1fa3 (patch)
tree545d58066f6ed68ba968ed56f170f4d0cab394ab /mcwm.c
parent16dcfef443d6f0a6f0e6829f077064ae2db75351 (diff)
downloadmcwm-e451e99ff498b7238e0a8ddab601f14588bb1fa3.zip
Handle UnmapNotify events. We find the window in the current workspace
list and then also forget about it completely. We will add it again if it gets mapped. Ignore UnmapNotify events if we unmapped windows ourselves and count the number of events we expected, then resume normal unmap handling.
Diffstat (limited to 'mcwm.c')
-rw-r--r--mcwm.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/mcwm.c b/mcwm.c
index ad6110a..97ca141 100644
--- a/mcwm.c
+++ b/mcwm.c
@@ -64,12 +64,20 @@
/* Internal Constants. */
+
+/* We're currently moving a window with the mouse. */
#define MCWM_MOVE 2
+
+/* We're currently resizing a window with the mouse. */
#define MCWM_RESIZE 3
+/* Our highest workspace. */
#define WORKSPACE_MAX 9
+/* Value in WM hint which means this window is fixed on all workspaces. */
#define NET_WM_FIXED 0xffffffff
+
+/* This means we didn't get any window hint at all. */
#define MCWM_NOWS 0xfffffffe
@@ -109,8 +117,8 @@ struct client
int32_t max_width, max_height;
int32_t width_inc, height_inc;
int32_t base_width, base_height;
- bool vertmaxed;
- bool maxed;
+ bool vertmaxed; /* Vertically maximized? */
+ bool maxed; /* Totally maximized? */
bool fixed; /* Visible on all workspaces? */
struct item *winitem; /* Pointer to our place in list of all windows. */
};
@@ -119,7 +127,7 @@ struct client
/* Globals */
xcb_connection_t *conn; /* Connection to X server. */
xcb_screen_t *screen; /* Our current screen. */
-uint32_t curws = 0; /* Current workspace. */
+uint32_t curws = 0; /* Current workspace. */
struct client *focuswin; /* Current focus window. */
struct item *winlist = NULL;
struct item *wslist[10] =
@@ -175,6 +183,8 @@ struct conf
xcb_atom_t atom_desktop;
+int unmaps_to_expect;
+
/* Functions declerations. */
void arrangewindows(int32_t rootwidth, int32_t rootheight);
@@ -185,6 +195,7 @@ void delfromworkspace(struct client *client, uint32_t ws);
void changeworkspace(uint32_t ws);
void fixwindow(struct client *client, bool setcolour);
uint32_t getcolor(const char *colstr);
+void forgetclient(struct client *client);
void forgetwin(xcb_window_t win);
void newwin(xcb_window_t win);
struct client *setupwin(xcb_window_t win);
@@ -439,6 +450,7 @@ void changeworkspace(uint32_t ws)
}
/* Go through list of current ws. Unmap everything that isn't fixed. */
+ unmaps_to_expect = 0;
for (item = wslist[curws]; item != NULL; )
{
client = item->data;
@@ -465,6 +477,12 @@ void changeworkspace(uint32_t ws)
{
xcb_unmap_window(conn, client->id);
item = item->next;
+
+ /*
+ * Keep track of how many UnmapNotify events we can expect
+ * before going back to ordinary unmap handling.
+ */
+ unmaps_to_expect ++;
}
} /* for */
@@ -554,6 +572,17 @@ uint32_t getcolor(const char *colstr)
return col_reply->pixel;
}
+void forgetclient(struct client *client)
+{
+
+ /* Delete window from workspace list. */
+ delfromworkspace(client, curws);
+
+ free(client->winitem->data);
+
+ delitem(&winlist, client->winitem);
+}
+
void forgetwin(xcb_window_t win)
{
struct item *item;
@@ -852,8 +881,6 @@ int setupscreen(void)
* with a MapRequest if we had been running, so in the
* normal case we wouldn't have seen them.
*
- * Usually, this mode is used for menu windows and the
- * like.
*/
if (!attr->override_redirect)
{
@@ -1837,7 +1864,7 @@ void events(void)
xcb_generic_event_t *ev;
xcb_drawable_t win;
xcb_get_geometry_reply_t *geom;
- int mode = 0;
+ int mode = 0; /* Internal mode. */
uint16_t mode_x;
uint16_t mode_y;
@@ -2243,7 +2270,62 @@ void events(void)
}
break;
-
+
+ case XCB_UNMAP_NOTIFY:
+ {
+ xcb_unmap_notify_event_t *e =
+ (xcb_unmap_notify_event_t *)ev;
+ struct item *item;
+ struct client *client;
+
+ PDEBUG("\n root: %d\n event: %d\n window: %d\n", screen->root,
+ e->event, e->window);
+
+ /*
+ * If we're currently changing workspace, unmaps_to_expect
+ * is larger than 0.
+ *
+ * Count all incoming UnmapNotify events. When we reach
+ * the number of windows that was on the last workspace,
+ * we stop counting and resume ordinary unmap handling.
+ */
+ if (unmaps_to_expect > 0)
+ {
+ unmaps_to_expect --;
+#if DEBUG
+ if (0 == unmaps_to_expect)
+ {
+ PDEBUG("Got all UnmapNotify events we wanted.\n");
+ }
+#endif
+ }
+ else
+ {
+ /*
+ * Ordinary unmap handling. Find the window in current
+ * workspace list, then forget about it. If it gets
+ * mapped, we add it to our lists again then.
+ *
+ * Note that the window we might not know about the
+ * window we got the UnmapNotify event for. This might
+ * be an override_redirect window, for example. We
+ * don't have any way to know.
+ */
+ for (item = wslist[curws]; item != NULL; item = item->next)
+ {
+ client = item->data;
+
+ if (client->id == e->window)
+ {
+ PDEBUG("Forgetting about %d\n", e->window);
+ forgetclient(client);
+ break;
+ }
+ } /* for */
+ }
+ }
+ break;
+
} /* switch */
free(ev);