re-add fullscreen mode

This commit is contained in:
Michael Stapelberg 2010-04-13 20:51:43 +02:00
parent a3e0ce53a9
commit 24725cd94a
6 changed files with 65 additions and 31 deletions

View File

@ -13,6 +13,9 @@
#include <xcb/randr.h> #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 * There was a key press. We compare this key code with our bindings table and
* pass the bound action to parse_command(). * pass the bound action to parse_command().

View File

@ -123,34 +123,55 @@ Con *con_get_workspace(Con *con) {
return result; 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. * Returns the first fullscreen node below this node.
* *
*/ */
Con *con_get_fullscreen_con(Con *con) { Con *con_get_fullscreen_con(Con *con) {
Con *current; Con *current, *child;
LOG("looking for fullscreen node\n"); LOG("looking for fullscreen node\n");
/* TODO: is breadth-first-search really appropriate? (check as soon as /* TODO: is breadth-first-search really appropriate? (check as soon as
* fullscreen levels and fullscreen for containers is implemented) */ * fullscreen levels and fullscreen for containers is implemented) */
Con **queue = NULL; TAILQ_HEAD(bfs_head, bfs_entry) bfs_head = TAILQ_HEAD_INITIALIZER(bfs_head);
int queue_len = 0; struct bfs_entry *entry = smalloc(sizeof(struct bfs_entry));
TAILQ_FOREACH(current, &(con->nodes_head), nodes) { entry->con = con;
queue_len++; TAILQ_INSERT_TAIL(&bfs_head, entry, entries);
queue = srealloc(queue, queue_len * sizeof(Con*));
queue[queue_len-1] = current;
}
while (queue_len > 0) { while (!TAILQ_EMPTY(&bfs_head)) {
current = queue[queue_len-1]; entry = TAILQ_FIRST(&bfs_head);
current = entry->con;
LOG("checking %p\n", current); LOG("checking %p\n", current);
if (current->fullscreen_mode != CF_NONE) { if (current != con && current->fullscreen_mode != CF_NONE) {
free(queue); /* empty the queue */
while (!TAILQ_EMPTY(&bfs_head)) {
entry = TAILQ_FIRST(&bfs_head);
TAILQ_REMOVE(&bfs_head, entry, entries);
free(entry);
}
return current; return current;
} }
LOG("deleting from queue\n"); LOG("deleting from queue\n");
queue_len--; TAILQ_REMOVE(&bfs_head, entry, entries);
queue = realloc(queue, queue_len * sizeof(Con*)); 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; return NULL;

View File

@ -19,7 +19,7 @@
changing workspaces */ changing workspaces */
static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events; 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)); struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
event->sequence = sequence; event->sequence = sequence;
@ -48,8 +48,11 @@ static bool event_is_ignored(const int sequence) {
if (event->sequence != sequence) if (event->sequence != sequence)
continue; continue;
SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events); /* instead of removing a sequence number we better wait until it gets
free(event); * 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; return true;
} }

View File

@ -89,8 +89,11 @@ void parse_command(const char *command) {
workspace_show(command + strlen("workspace ")); workspace_show(command + strlen("workspace "));
else if (strcasecmp(command, "stack") == 0) { else if (strcasecmp(command, "stack") == 0) {
focused->layout = L_STACKED; 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) else if (strcasecmp(command, "move before h") == 0)
tree_move('p', HORIZ); tree_move('p', HORIZ);

View File

@ -37,6 +37,18 @@ void render_con(Con *con) {
printf("mapped = true\n"); printf("mapped = true\n");
con->mapped = true; 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 */ /* Check for fullscreen nodes */
Con *fullscreen = con_get_fullscreen_con(con); Con *fullscreen = con_get_fullscreen_con(con);
if (fullscreen) { if (fullscreen) {
@ -46,7 +58,6 @@ void render_con(Con *con) {
return; return;
} }
TAILQ_FOREACH(child, &(con->nodes_head), nodes) { TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
/* default layout */ /* default layout */
@ -105,16 +116,6 @@ void render_con(Con *con) {
printf("child at (%d, %d) with (%d x %d)\n", printf("child at (%d, %d) with (%d x %d)\n",
child->rect.x, child->rect.y, child->rect.width, child->rect.height); child->rect.x, child->rect.y, child->rect.width, child->rect.height);
printf("x now %d, y now %d\n", x, y); 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); x_raise_con(child);
render_con(child); render_con(child);
i++; i++;

View File

@ -318,10 +318,13 @@ int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *t
* *
*/ */
void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) { 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_X |
XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_Y |
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_WIDTH |
XCB_CONFIG_WINDOW_HEIGHT, XCB_CONFIG_WINDOW_HEIGHT,
&(r.x)); &(r.x));
/* ignore events which are generated because we configured a window */
add_ignore_event(cookie.sequence);
} }