Implement stacking

This commit is contained in:
Michael Stapelberg
2009-02-24 00:30:04 +01:00
parent 6e81d1c5e4
commit 0e3a378c39
12 changed files with 215 additions and 51 deletions

View File

@ -23,6 +23,7 @@
#include "table.h"
#include "layout.h"
#include "util.h"
#include "xcb.h"
int min(int a, int b) {
return (a < b ? a : b);
@ -138,11 +139,74 @@ void set_focus(xcb_connection_t *conn, Client *client) {
//xcb_warp_pointer(conn, XCB_NONE, client->child, 0, 0, 0, 0, 10, 10);
/* Update last/current clients titlebar */
if (old_client != NULL)
decorate_window(conn, old_client);
decorate_window(conn, client);
decorate_window(conn, old_client, old_client->frame, old_client->titlegc, 0);
decorate_window(conn, client, client->frame, client->titlegc, 0);
/* If were in stacking mode, we render the container to update changes in the title
bars and to raise the focused client */
if (client->container->mode == MODE_STACK)
render_container(conn, client->container);
xcb_flush(conn);
}
/*
* Switches the layout of the given container taking care of the necessary house-keeping
*
*/
void switch_layout_mode(xcb_connection_t *conn, Container *container, int mode) {
if (mode == MODE_STACK) {
/* When entering stacking mode, we need to open a window on which we can draw the
title bars of the clients */
Rect rect = {container->x, container->y, container->width, 15 /* TODO: exact */ };
/* Dont generate events for our new window, it should *not* be managed */
uint32_t mask = 0;
uint32_t values[2];
mask |= XCB_CW_OVERRIDE_REDIRECT;
values[0] = 1;
/* We want to know when… */
mask |= XCB_CW_EVENT_MASK;
values[1] = XCB_EVENT_MASK_BUTTON_PRESS | /* …mouse is pressed */
XCB_EVENT_MASK_EXPOSURE; /* …our window needs to be redrawn */
struct Stack_Window *stack_win = &(container->stack_win);
stack_win->window = create_window(conn, rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, mask, values);
/* Generate a graphics context for the titlebar */
stack_win->gc = xcb_generate_id(conn);
xcb_create_gc(conn, stack_win->gc, stack_win->window, 0, 0);
stack_win->container = container;
SLIST_INSERT_HEAD(&stack_wins, stack_win, stack_windows);
} else {
if (container->mode == MODE_STACK) {
/* When going out of stacking mode, we need to close the window */
struct Stack_Window *stack_win = &(container->stack_win);
SLIST_REMOVE(&stack_wins, stack_win, Stack_Window, stack_windows);
xcb_free_gc(conn, stack_win->gc);
xcb_destroy_window(conn, stack_win->window);
stack_win->width = -1;
stack_win->height = -1;
}
}
container->mode = mode;
/* Force reconfiguration of each client */
Client *client;
CIRCLEQ_FOREACH(client, &(container->clients), clients)
client->force_reconfigure = true;
render_layout(conn);
}
/*
* Warps the pointer into the given client (in the middle of it, to be specific), therefore
* selecting it