#include <xcb/randr.h>
+
+void add_ignore_event(const int sequence);
+
/**
* There was a key press. We compare this key code with our bindings table and
* pass the bound action to parse_command().
return result;
}
+/*
+ * helper data structure for the breadth-first-search in
+ * con_get_fullscreen_con()
+ *
+ */
+struct bfs_entry {
+ Con *con;
+
+ TAILQ_ENTRY(bfs_entry) entries;
+};
+
/*
* Returns the first fullscreen node below this node.
*
*/
Con *con_get_fullscreen_con(Con *con) {
- Con *current;
+ Con *current, *child;
LOG("looking for fullscreen node\n");
/* TODO: is breadth-first-search really appropriate? (check as soon as
* fullscreen levels and fullscreen for containers is implemented) */
- Con **queue = NULL;
- int queue_len = 0;
- TAILQ_FOREACH(current, &(con->nodes_head), nodes) {
- queue_len++;
- queue = srealloc(queue, queue_len * sizeof(Con*));
- queue[queue_len-1] = current;
- }
-
- while (queue_len > 0) {
- current = queue[queue_len-1];
+ TAILQ_HEAD(bfs_head, bfs_entry) bfs_head = TAILQ_HEAD_INITIALIZER(bfs_head);
+ struct bfs_entry *entry = smalloc(sizeof(struct bfs_entry));
+ entry->con = con;
+ TAILQ_INSERT_TAIL(&bfs_head, entry, entries);
+
+ while (!TAILQ_EMPTY(&bfs_head)) {
+ entry = TAILQ_FIRST(&bfs_head);
+ current = entry->con;
LOG("checking %p\n", current);
- if (current->fullscreen_mode != CF_NONE) {
- free(queue);
+ if (current != con && current->fullscreen_mode != CF_NONE) {
+ /* empty the queue */
+ while (!TAILQ_EMPTY(&bfs_head)) {
+ entry = TAILQ_FIRST(&bfs_head);
+ TAILQ_REMOVE(&bfs_head, entry, entries);
+ free(entry);
+ }
return current;
}
+
LOG("deleting from queue\n");
- queue_len--;
- queue = realloc(queue, queue_len * sizeof(Con*));
+ TAILQ_REMOVE(&bfs_head, entry, entries);
+ free(entry);
+
+ TAILQ_FOREACH(child, &(current->nodes_head), nodes) {
+ entry = smalloc(sizeof(struct bfs_entry));
+ entry->con = child;
+ TAILQ_INSERT_TAIL(&bfs_head, entry, entries);
+ }
}
return NULL;
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;
}
workspace_show(command + strlen("workspace "));
else if (strcasecmp(command, "stack") == 0) {
focused->layout = L_STACKED;
- x_push_changes(croot);
-
+ }
+ else if (strcasecmp(command, "fullscreen") == 0) {
+ if (focused->fullscreen_mode == CF_NONE)
+ focused->fullscreen_mode = CF_OUTPUT;
+ else focused->fullscreen_mode = CF_NONE;
}
else if (strcasecmp(command, "move before h") == 0)
tree_move('p', HORIZ);
printf("mapped = true\n");
con->mapped = true;
+ /* if this container contains a window, set the coordinates */
+ if (con->window) {
+ /* depending on the border style, the rect of the child window
+ * needs to be smaller */
+ Rect *inset = &(con->window_rect);
+ *inset = (Rect){0, 0, con->rect.width, con->rect.height};
+ /* TODO: different border styles */
+ inset->x += 2;
+ inset->width -= 2 * 2;
+ inset->height -= 2;
+ }
+
/* Check for fullscreen nodes */
Con *fullscreen = con_get_fullscreen_con(con);
if (fullscreen) {
return;
}
-
TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
/* default layout */
printf("child at (%d, %d) with (%d x %d)\n",
child->rect.x, child->rect.y, child->rect.width, child->rect.height);
printf("x now %d, y now %d\n", x, y);
- if (child->window) {
- /* depending on the border style, the rect of the child window
- * needs to be smaller */
- Rect *inset = &(child->window_rect);
- *inset = (Rect){0, 0, child->rect.width, child->rect.height};
- /* TODO: different border styles */
- inset->x += 2;
- inset->width -= 2 * 2;
- inset->height -= 2;
- }
x_raise_con(child);
render_con(child);
i++;
*
*/
void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) {
- xcb_configure_window(conn, window,
+ xcb_void_cookie_t cookie;
+ cookie = xcb_configure_window(conn, window,
XCB_CONFIG_WINDOW_X |
XCB_CONFIG_WINDOW_Y |
XCB_CONFIG_WINDOW_WIDTH |
XCB_CONFIG_WINDOW_HEIGHT,
&(r.x));
+ /* ignore events which are generated because we configured a window */
+ add_ignore_event(cookie.sequence);
}