changing workspaces */
static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
-static void add_ignore_event(const int sequence) {
+void add_ignore_event(const int sequence) {
struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
event->sequence = sequence;
if (event->sequence != sequence)
continue;
- SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
- free(event);
+ /* instead of removing a sequence number we better wait until it gets
+ * garbage collected. it may generate multiple events (there are multiple
+ * enter_notifies for one configure_request, for example). */
+ //SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
+ //free(event);
return true;
}
add_ignore_event(event->sequence);
manage_window(event->window, cookie, false);
+ x_push_changes(croot);
return 1;
}
#if 0
*/
int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_notify_event_t *event) {
- //add_ignore_event(event->sequence);
+ /* we need to ignore EnterNotify events which will be generated because a
+ * different window is visible now */
+ add_ignore_event(event->sequence);
- DLOG("UnmapNotify for 0x%08x (received from 0x%08x)\n", event->window, event->event);
+ DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence);
Con *con = con_by_window_id(event->window);
if (con == NULL) {
LOG("Not a managed window, ignoring\n");
return 1;
}
-#if 0
/*
* A destroy notify event is sent when the window is not unmapped, but
* immediately destroyed (for example when starting a window and immediately
*
*/
int handle_destroy_notify_event(void *data, xcb_connection_t *conn, xcb_destroy_notify_event_t *event) {
- DLOG("destroy notify for 0x%08x, 0x%08x\n", event->event, event->window);
+ DLOG("destroy notify for 0x%08x, 0x%08x\n", event->event, event->window);
- xcb_unmap_notify_event_t unmap;
- unmap.sequence = event->sequence;
- unmap.event = event->event;
- unmap.window = event->window;
+ xcb_unmap_notify_event_t unmap;
+ unmap.sequence = event->sequence;
+ unmap.event = event->event;
+ unmap.window = event->window;
- return handle_unmap_notify_event(NULL, conn, &unmap);
+ return handle_unmap_notify_event(NULL, conn, &unmap);
}
-#endif
+
/*
* Called when a window changes its title
*
#endif
}
-#if 0
/*
* Handle client messages (EWMH)
*
*/
int handle_client_message(void *data, xcb_connection_t *conn, xcb_client_message_event_t *event) {
- if (event->type == atoms[_NET_WM_STATE]) {
- if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN])
- return 0;
-
- Client *client = table_get(&by_child, event->window);
- if (client == NULL)
- return 0;
-
- /* Check if the fullscreen state should be toggled */
- if ((client->fullscreen &&
- (event->data.data32[0] == _NET_WM_STATE_REMOVE ||
- event->data.data32[0] == _NET_WM_STATE_TOGGLE)) ||
- (!client->fullscreen &&
- (event->data.data32[0] == _NET_WM_STATE_ADD ||
- event->data.data32[0] == _NET_WM_STATE_TOGGLE)))
- client_toggle_fullscreen(conn, client);
- } else {
- ELOG("unhandled clientmessage\n");
- return 0;
- }
+ LOG("ClientMessage for window 0x%08x\n", event->window);
+ if (event->type == atoms[_NET_WM_STATE]) {
+ if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN])
+ return 0;
+
+ Con *con = con_by_window_id(event->window);
+ if (con == NULL)
+ return 0;
+
+ /* Check if the fullscreen state should be toggled */
+ if ((con->fullscreen_mode != CF_NONE &&
+ (event->data.data32[0] == _NET_WM_STATE_REMOVE ||
+ event->data.data32[0] == _NET_WM_STATE_TOGGLE)) ||
+ (con->fullscreen_mode == CF_NONE &&
+ (event->data.data32[0] == _NET_WM_STATE_ADD ||
+ event->data.data32[0] == _NET_WM_STATE_TOGGLE)))
+ con_toggle_fullscreen(con);
+
+ tree_render();
+ x_push_changes(croot);
+ } else {
+ ELOG("unhandled clientmessage\n");
+ return 0;
+ }
- return 1;
+ return 1;
}
+#if 0
int handle_window_type(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t atom, xcb_get_property_reply_t *property) {
/* TODO: Implement this one. To do this, implement a little test program which sleep(1)s