summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xshare/autostart1
-rw-r--r--src/clientlist.c64
-rw-r--r--src/clientlist.h5
-rw-r--r--src/layout.c4
-rw-r--r--src/main.c1
-rw-r--r--src/utils.c12
-rw-r--r--src/utils.h1
7 files changed, 86 insertions, 2 deletions
diff --git a/share/autostart b/share/autostart
index 225fd4bf..1cf74441 100755
--- a/share/autostart
+++ b/share/autostart
@@ -30,6 +30,7 @@ hc keybind $Mod-space cycle_layout 1
hc keybind $Mod-u split vertical 0.5
hc keybind $Mod-o split horizontal 0.5
hc keybind $Mod-s floating toggle
+hc keybind $Mod-f fullscreen toggle
# resizing
RESIZESTEP=0.05
diff --git a/src/clientlist.c b/src/clientlist.c
index 0b5e865d..620e990d 100644
--- a/src/clientlist.c
+++ b/src/clientlist.c
@@ -10,6 +10,7 @@
#include "utils.h"
#include "hook.h"
#include "mouse.h"
+#include "ipc-protocol.h"
// system
#include <glib.h>
#include <assert.h>
@@ -46,6 +47,7 @@ static HSClient* create_client() {
hc->float_size.width = 100;
hc->float_size.height = 100;
hc->urgent = false;
+ hc->fullscreen = false;
return hc;
}
@@ -233,6 +235,18 @@ void client_setup_border(HSClient* client, bool focused) {
XSetWindowBorder(g_display, client->window, colors[focused ? 1 : 0]);
}
+void client_resize_fullscreen(HSClient* client, HSMonitor* m) {
+ if (!client || !m) {
+ HSDebug("client_resize_fullscreen() got invalid parameters\n");
+ return;
+ }
+ XSetWindowBorderWidth(g_display, client->window, 0);
+ client->last_size = m->rect;
+ XMoveResizeWindow(g_display, client->window,
+ m->rect.x, m->rect.y, m->rect.width, m->rect.height);
+
+}
+
void client_resize(HSClient* client, XRectangle rect) {
// ensure minimum size
if (rect.width < WINDOW_MIN_WIDTH) {
@@ -272,8 +286,25 @@ void client_resize(HSClient* client, XRectangle rect) {
//XSendEvent(g_display, win, False, StructureNotifyMask, (XEvent *)&ce);
}
+void client_resize_tiling(HSClient* client, XRectangle rect) {
+ HSMonitor* m;
+ if (client->fullscreen && (m = find_monitor_with_tag(client->tag))) {
+ printf("applying %lx to fs\n", client->window);
+ client_resize_fullscreen(client, m);
+ } else {
+ printf("applying %lx to tiling\n", client->window);
+ client_resize(client, rect);
+ }
+}
+
void client_resize_floating(HSClient* client, HSMonitor* m) {
if (!client || !m) return;
+ if (client->fullscreen) {
+ client_resize_fullscreen(client, m);
+ return;
+ }
+
+ // ensure minimal size
if (client->float_size.width < WINDOW_MIN_WIDTH)
client->float_size.width = WINDOW_MIN_WIDTH;
if (client->float_size.height < WINDOW_MIN_HEIGHT)
@@ -281,6 +312,8 @@ void client_resize_floating(HSClient* client, HSMonitor* m) {
client->last_size = client->float_size;
client->last_size.x += m->rect.x + m->pad_left;
client->last_size.y += m->rect.y + m->pad_up;
+
+ // ensure position is on monitor
int space = g_monitor_float_treshold;
client->last_size.x =
CLAMP(client->last_size.x,
@@ -291,6 +324,7 @@ void client_resize_floating(HSClient* client, HSMonitor* m) {
m->rect.y + m->pad_up - client->last_size.height + space,
m->rect.y + m->rect.height - m->pad_up - m->pad_down - space);
XRectangle rect = client->last_size;
+ XSetWindowBorderWidth(g_display, client->window, *g_window_border_width);
XMoveResizeWindow(g_display, client->window,
rect.x, rect.y, rect.width, rect.height);
}
@@ -396,3 +430,33 @@ void client_update_wm_hints(HSClient* client) {
}
}
+HSClient* get_current_client() {
+ Window win = frame_focused_window(g_cur_frame);
+ if (!win) return NULL;
+ return get_client_from_window(win);
+}
+
+void client_set_fullscreen(HSClient* client, bool state) {
+ client->fullscreen = state;
+ if (state) {
+ // TODO: do proper stacking layer handling
+ XRaiseWindow(g_display, client->window);
+ }
+ monitor_apply_layout(get_current_monitor());
+}
+
+int client_set_fullscreen_command(int argc, char** argv) {
+ if (argc < 2) {
+ return HERBST_INVALID_ARGUMENT;
+ }
+
+ HSClient* client = get_current_client();
+ if (!client) {
+ // nothing to do
+ return 0;
+ }
+ bool state = string_to_bool(argv[1], client->fullscreen);
+ client_set_fullscreen(client, state);
+ return 0;
+}
+
diff --git a/src/clientlist.h b/src/clientlist.h
index e5adf966..2e933e4a 100644
--- a/src/clientlist.h
+++ b/src/clientlist.h
@@ -22,6 +22,7 @@ typedef struct HSClient {
HSTag* tag;
XRectangle float_size;
bool urgent;
+ bool fullscreen;
} HSClient;
void clientlist_init();
@@ -46,15 +47,19 @@ void window_enforce_last_size(Window in);
void destroy_client(HSClient* client);
HSClient* get_client_from_window(Window window);
+HSClient* get_current_client();
XRectangle client_outer_floating_rect(HSClient* client);
void client_setup_border(HSClient* client, bool focused);
void client_resize(HSClient* client, XRectangle rect);
+void client_resize_tiling(HSClient* client, XRectangle rect);
void client_resize_floating(HSClient* client, HSMonitor* m);
void client_clear_urgent(HSClient* client);
void client_update_wm_hints(HSClient* client);
int window_close_current();
+void client_set_fullscreen(HSClient* client, bool state);
+int client_set_fullscreen_command(int argc, char** argv);
bool is_window_class_ignored(char* window_class);
bool is_window_ignored(Window win);
diff --git a/src/layout.c b/src/layout.c
index 6acee88e..59adb61c 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -628,7 +628,7 @@ void frame_apply_client_layout_linear(HSFrame* frame, XRectangle rect, bool vert
cur.height += (i == count-1) ? last_step_y : 0;
cur.width += (i == count-1) ? last_step_x : 0;
client_setup_border(client, (g_cur_frame == frame) && (i == selection));
- client_resize(client, cur);
+ client_resize_tiling(client, cur);
cur.y += step_y;
cur.x += step_x;
}
@@ -649,7 +649,7 @@ void frame_apply_client_layout_max(HSFrame* frame, XRectangle rect) {
for (int i = 0; i < count; i++) {
HSClient* client = get_client_from_window(buf[i]);
client_setup_border(client, (g_cur_frame == frame) && (i == selection));
- client_resize(client, rect);
+ client_resize_tiling(client, rect);
if (i == selection) {
XRaiseWindow(g_display, buf[i]);
}
diff --git a/src/main.c b/src/main.c
index 56518e83..f1c8b6fd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -105,6 +105,7 @@ CommandBinding g_commands[] = {
CMD_BIND_NO_OUTPUT( "add", tag_add_command),
CMD_BIND_NO_OUTPUT( "use", monitor_set_tag_command),
CMD_BIND( "floating", tag_set_floating_command),
+ CMD_BIND_NO_OUTPUT( "fullscreen", client_set_fullscreen_command),
CMD_BIND( "tag_status", print_tag_status_command),
CMD_BIND_NO_OUTPUT( "merge_tag", tag_remove_command),
CMD_BIND_NO_OUTPUT( "rename", tag_rename_command),
diff --git a/src/utils.c b/src/utils.c
index 53ebe23c..a74892ec 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -147,3 +147,15 @@ char* strlasttoken(char* str, char* delim) {
return str;
}
+bool string_to_bool(char* string, bool oldvalue) {
+ bool val = oldvalue;
+ if (!strcmp(string, "on")) {
+ val = true;
+ } else if (!strcmp(string, "off")) {
+ val = false;
+ } else if (!strcmp(string, "toggle")) {
+ val = ! oldvalue;
+ }
+ return val;
+}
+
diff --git a/src/utils.h b/src/utils.h
index ee6f10bd..8293ba21 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -28,6 +28,7 @@ bool is_herbstluft_window(Display* dpy, Window window);
bool is_window_mapable(Display* dpy, Window window);
bool is_window_mapped(Display* dpy, Window window);
+bool string_to_bool(char* string, bool oldvalue);
char* strlasttoken(char* str, char* delim);