From 9222bea3b222ff425077cef3cee56e2d6278ebc4 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 5 Aug 2009 18:33:44 +0200 Subject: [PATCH] Implement borderless / 1-px-bordered windows Use bn (normal), bp (1-px), bb (borderless) as commands to change the border style of the currently focused window. Feel free to use i3-msg to do this. --- include/client.h | 7 +++++++ include/data.h | 4 ++++ src/client.c | 39 +++++++++++++++++++++++++++++++++++++++ src/commands.c | 10 ++++++++++ src/layout.c | 17 ++++++++++++----- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/include/client.h b/include/client.h index 8fbd4434..5d87b2ee 100644 --- a/include/client.h +++ b/include/client.h @@ -78,4 +78,11 @@ void client_set_below_floating(xcb_connection_t *conn, Client *client); */ bool client_is_floating(Client *client); +/** + * Change the border type for the given client to normal (n), 1px border (p) or + * completely borderless (b). + * + */ +void client_change_border(xcb_connection_t *conn, Client *client, char border_type); + #endif diff --git a/include/data.h b/include/data.h index 99e79ab2..c2d83783 100644 --- a/include/data.h +++ b/include/data.h @@ -360,6 +360,10 @@ struct Client { * initialization later */ enum { TITLEBAR_TOP = 0, TITLEBAR_LEFT, TITLEBAR_RIGHT, TITLEBAR_BOTTOM, TITLEBAR_OFF } titlebar_position; + /** Contains a bool specifying whether this window should not be drawn + * with the usual decorations */ + bool borderless; + /** If a client is set as a dock, it is placed at the very bottom of * the screen and its requested size is used */ bool dock; diff --git a/src/client.c b/src/client.c index c3a80c36..81430b2f 100644 --- a/src/client.c +++ b/src/client.c @@ -248,3 +248,42 @@ void client_set_below_floating(xcb_connection_t *conn, Client *client) { bool client_is_floating(Client *client) { return (client->floating >= FLOATING_AUTO_ON); } + +/* + * Change the border type for the given client to normal (n), 1px border (p) or + * completely borderless (b). + * + */ +void client_change_border(xcb_connection_t *conn, Client *client, char border_type) { + switch (border_type) { + case 'n': + LOG("Changing to normal border\n"); + client->titlebar_position = TITLEBAR_TOP; + client->borderless = false; + break; + case 'p': + LOG("Changing to 1px border\n"); + client->titlebar_position = TITLEBAR_OFF; + client->borderless = false; + break; + case 'b': + LOG("Changing to borderless\n"); + client->titlebar_position = TITLEBAR_OFF; + client->borderless = true; + break; + default: + LOG("Unknown border mode\n"); + return; + } + + /* Ensure that the child’s position inside our window gets updated */ + client->force_reconfigure = true; + + /* For clients inside a container, we can simply render the container. + * If the client is floating, we need to render the whole layout */ + if (client->container != NULL) + render_container(conn, client->container); + else render_layout(conn); + + redecorate_window(conn, client); +} diff --git a/src/commands.c b/src/commands.c index 16b2152a..69a6de52 100644 --- a/src/commands.c +++ b/src/commands.c @@ -967,6 +967,16 @@ void parse_command(xcb_connection_t *conn, const char *command) { return; } + /* Is it 'bn' (border normal), 'bp' (border 1pixel) or 'bb' (border borderless)? */ + if (command[0] == 'b') { + if (last_focused == NULL) { + LOG("No window focused, cannot change border type\n"); + return; + } + client_change_border(conn, last_focused, command[1]); + return; + } + if (command[0] == 'H') { LOG("Hiding all floating windows\n"); floating_toggle_hide(conn, c_ws); diff --git a/src/layout.c b/src/layout.c index d094ca42..44ce1b1d 100644 --- a/src/layout.c +++ b/src/layout.c @@ -145,10 +145,12 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw xcb_poly_fill_rectangle(conn, client->frame, client->titlegc, 1, &crect); } - /* Draw the lines */ - xcb_draw_line(conn, drawable, gc, color->border, 0, offset, client->rect.width, offset); - xcb_draw_line(conn, drawable, gc, color->border, 2, offset + font->height + 3, - client->rect.width - 3, offset + font->height + 3); + if (client->titlebar_position != TITLEBAR_OFF) { + /* Draw the lines */ + xcb_draw_line(conn, drawable, gc, color->border, 0, offset, client->rect.width, offset); + xcb_draw_line(conn, drawable, gc, color->border, 2, offset + font->height + 3, + client->rect.width - 3, offset + font->height + 3); + } /* If the client has a title, we draw it */ if (client->name != NULL) { @@ -227,11 +229,16 @@ void resize_client(xcb_connection_t *conn, Client *client) { rect->height = client->rect.height - 2; break; default: - if (client->titlebar_position == TITLEBAR_OFF) { + if (client->titlebar_position == TITLEBAR_OFF && client->borderless) { rect->x = 0; rect->y = 0; rect->width = client->rect.width; rect->height = client->rect.height; + } else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless) { + rect->x = 1; + rect->y = 1; + rect->width = client->rect.width - 1 - 1; + rect->height = client->rect.height - 1 - 1; } else { rect->x = 2; rect->y = font->height + 2 + 2; -- 2.39.5