From 18543c6bcebec07ed4889d858c21e2f873c6e01d Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 14 Feb 2009 20:12:50 +0100 Subject: [PATCH] Implement fullscreen mode (Mod1+f) --- TODO | 1 - include/util.h | 6 +++++ src/commands.c | 10 ++++++- src/handlers.c | 55 +------------------------------------- src/mainx.c | 2 ++ src/util.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 56 deletions(-) diff --git a/TODO b/TODO index 43cd8bf9..3d5b7708 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,6 @@ TODO list, in order of importance: * freely resizable (e.g. using your mouse, for now) percentage of rows/cols * fullscreen (handling of applications, mplayer, firefox, xpdf, wmctrl) - * fullscreen (implementing a mode, like default, stacked) * xinerama * document stuff! * more documentation! diff --git a/include/util.h b/include/util.h index 479e0ced..f194da86 100644 --- a/include/util.h +++ b/include/util.h @@ -8,10 +8,16 @@ * See file LICENSE for license information. * */ +#include + +#include "data.h" + #ifndef _UTIL_H #define _UTIL_H void start_application(const char *command); void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message); +void set_focus(xcb_connection_t *conn, Client *client); +void toggle_fullscreen(xcb_connection_t *conn, Client *client); #endif diff --git a/src/commands.c b/src/commands.c index 95475dfb..7f63f9b1 100644 --- a/src/commands.c +++ b/src/commands.c @@ -301,6 +301,14 @@ void parse_command(xcb_connection_t *conn, const char *command) { return; } + /* Is it 'f' for fullscreen? */ + if (command[0] == 'f') { + if (CUR_CELL->currently_focused == NULL) + return; + toggle_fullscreen(conn, CUR_CELL->currently_focused); + return; + } + /* Is it a ? */ if (command[0] == 'w') { /* TODO: implement */ @@ -315,7 +323,7 @@ void parse_command(xcb_connection_t *conn, const char *command) { direction_t direction; times = strtol(command, &rest, 10); if (rest == NULL) { - printf("Invalid command: Consists only of a movement\n"); + printf("Invalid command (\"%s\")\n", command); return; } if (*rest == 'm' || *rest == 's') { diff --git a/src/handlers.c b/src/handlers.c index 01f5efef..6de25e73 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -25,60 +25,7 @@ #include "data.h" #include "font.h" #include "xcb.h" - -static void set_focus(xcb_connection_t *conn, Client *client) { - /* Update container */ - Client *old_client = client->container->currently_focused; - client->container->currently_focused = client; - - current_col = client->container->col; - current_row = client->container->row; - - /* Set focus to the entered window, and flush xcb buffer immediately */ - xcb_set_input_focus(conn, XCB_INPUT_FOCUS_NONE, client->child, XCB_CURRENT_TIME); - /* Update last/current client’s titlebar */ - if (old_client != NULL) - decorate_window(conn, old_client); - decorate_window(conn, client); - xcb_flush(conn); -} - -static void toggle_fullscreen(xcb_connection_t *conn, Client *client) { - Workspace *workspace = client->container->workspace; - - workspace->fullscreen_client = (client->fullscreen ? NULL : client); - - client->fullscreen = !client->fullscreen; - - if (client->fullscreen) { - printf("Entering fullscreen mode...\n"); - /* We just entered fullscreen mode, let’s configure the window */ - uint32_t mask = XCB_CONFIG_WINDOW_X | - XCB_CONFIG_WINDOW_Y | - XCB_CONFIG_WINDOW_WIDTH | - XCB_CONFIG_WINDOW_HEIGHT; - uint32_t values[4] = {workspace->x, - workspace->y, - workspace->width, - workspace->height}; - - printf("child itself will be at %dx%d with size %dx%d\n", - values[0], values[1], values[2], values[3]); - - /* Raise the window */ - xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, client->frame); - - xcb_configure_window(conn, client->frame, mask, values); - xcb_configure_window(conn, client->child, mask, values); - - xcb_flush(conn); - } else { - printf("left fullscreen\n"); - client->force_reconfigure = true; - /* We left fullscreen mode, redraw the layout */ - render_layout(conn); - } -} +#include "util.h" /* * Due to bindings like Mode_switch + , we need to bind some keys in XCB_GRAB_MODE_SYNC. diff --git a/src/mainx.c b/src/mainx.c index 92b9468f..ef371f55 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -396,6 +396,8 @@ int main(int argc, char *argv[], char *env[]) { BIND(30, 0, "exec /usr/pkg/bin/urxvt"); + BIND(41, BIND_MOD_1, "f"); + BIND(44, BIND_MOD_1, "h"); BIND(45, BIND_MOD_1, "j"); BIND(46, BIND_MOD_1, "k"); diff --git a/src/util.c b/src/util.c index 525fb434..6a33ffbe 100644 --- a/src/util.c +++ b/src/util.c @@ -15,6 +15,9 @@ #include #include "i3.h" +#include "data.h" +#include "table.h" +#include "layout.h" /* * Starts the given application by passing it through a shell. We use double fork @@ -59,3 +62,71 @@ void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *e exit(-1); } } + +/* + * Sets the given client as focused by updating the data structures correctly, + * updating the X input focus and finally re-decorating both windows (to signalize + * the user the new focus situation) + * + */ +void set_focus(xcb_connection_t *conn, Client *client) { + /* Update container */ + Client *old_client = client->container->currently_focused; + client->container->currently_focused = client; + + current_col = client->container->col; + current_row = client->container->row; + + /* Set focus to the entered window, and flush xcb buffer immediately */ + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_NONE, client->child, XCB_CURRENT_TIME); + /* Update last/current client’s titlebar */ + if (old_client != NULL) + decorate_window(conn, old_client); + decorate_window(conn, client); + xcb_flush(conn); +} + +/* + * Toggles fullscreen mode for the given client. It updates the data structures and + * reconfigures (= resizes/moves) the client and its frame to the full size of the + * screen. When leaving fullscreen, re-rendering the layout is forced. + * + */ +void toggle_fullscreen(xcb_connection_t *conn, Client *client) { + Workspace *workspace = client->container->workspace; + + workspace->fullscreen_client = (client->fullscreen ? NULL : client); + + client->fullscreen = !client->fullscreen; + + if (client->fullscreen) { + printf("Entering fullscreen mode...\n"); + /* We just entered fullscreen mode, let’s configure the window */ + uint32_t mask = XCB_CONFIG_WINDOW_X | + XCB_CONFIG_WINDOW_Y | + XCB_CONFIG_WINDOW_WIDTH | + XCB_CONFIG_WINDOW_HEIGHT; + uint32_t values[4] = {workspace->x, + workspace->y, + workspace->width, + workspace->height}; + + printf("child itself will be at %dx%d with size %dx%d\n", + values[0], values[1], values[2], values[3]); + + /* Raise the window */ + xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, client->frame); + + xcb_configure_window(conn, client->frame, mask, values); + xcb_configure_window(conn, client->child, mask, values); + + xcb_flush(conn); + } else { + printf("left fullscreen\n"); + /* Because the coordinates of the window haven’t changed, it would not be + re-configured if we don’t set the following flag */ + client->force_reconfigure = true; + /* We left fullscreen mode, redraw the layout */ + render_layout(conn); + } +}