From 60f0b667b195e7479da944fa2b960c3377d4f144 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 12:44:09 +0200
Subject: Basic fullscreen

---
 dwl.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/dwl.c b/dwl.c
index 730e46a..39c34a0 100644
--- a/dwl.c
+++ b/dwl.c
@@ -96,6 +96,7 @@ typedef struct {
 	struct wl_listener map;
 	struct wl_listener unmap;
 	struct wl_listener destroy;
+	struct wl_listener fullscreen;
 	struct wlr_box geom;  /* layout-relative, includes border */
 	Monitor *mon;
 #ifdef XWAYLAND
@@ -192,6 +193,7 @@ static void createxdeco(struct wl_listener *listener, void *data);
 static void cursorframe(struct wl_listener *listener, void *data);
 static void destroynotify(struct wl_listener *listener, void *data);
 static void destroyxdeco(struct wl_listener *listener, void *data);
+static void fullscreenotify(struct wl_listener *listener, void *data);
 static Monitor *dirtomon(int dir);
 static void focusclient(Client *old, Client *c, int lift);
 static void focusmon(const Arg *arg);
@@ -598,6 +600,9 @@ createnotify(struct wl_listener *listener, void *data)
 	wl_signal_add(&xdg_surface->events.unmap, &c->unmap);
 	c->destroy.notify = destroynotify;
 	wl_signal_add(&xdg_surface->events.destroy, &c->destroy);
+
+	wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen);
+	c->fullscreen.notify = fullscreenotify;
 }
 
 void
@@ -664,6 +669,12 @@ destroyxdeco(struct wl_listener *listener, void *data)
 	free(d);
 }
 
+void
+fullscreenotify(struct wl_listener *listener, void *data) {
+	Client *c = wl_container_of(listener, c, fullscreen);
+	wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, true);
+}
+
 Monitor *
 dirtomon(int dir)
 {
-- 
cgit v1.2.3


From 06982a56b554947e651f37b4ff05b2010935a270 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 14:04:19 +0200
Subject: Toggle fullscreen

---
 dwl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 39c34a0..73d31ab 100644
--- a/dwl.c
+++ b/dwl.c
@@ -672,7 +672,7 @@ destroyxdeco(struct wl_listener *listener, void *data)
 void
 fullscreenotify(struct wl_listener *listener, void *data) {
 	Client *c = wl_container_of(listener, c, fullscreen);
-	wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, true);
+	wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, !c->surface.xdg->toplevel->current.fullscreen);
 }
 
 Monitor *
-- 
cgit v1.2.3


From 4b1ab7804bdfd0f8351e70fcbd5778bb5d00c309 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 17:09:12 +0200
Subject: No borders on fullscreen windows

Some code has been borrowed from the smartBorders patch
---
 dwl.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 73d31ab..e516316 100644
--- a/dwl.c
+++ b/dwl.c
@@ -672,7 +672,9 @@ destroyxdeco(struct wl_listener *listener, void *data)
 void
 fullscreenotify(struct wl_listener *listener, void *data) {
 	Client *c = wl_container_of(listener, c, fullscreen);
-	wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, !c->surface.xdg->toplevel->current.fullscreen);
+	wlr_xdg_toplevel_set_fullscreen(
+			c->surface.xdg, !c->surface.xdg->toplevel->current.fullscreen);
+	c->bw = (int)c->surface.xdg->toplevel->current.fullscreen * borderpx;
 }
 
 Monitor *
@@ -1193,6 +1195,10 @@ renderclients(Monitor *m, struct timespec *now)
 		ox = c->geom.x, oy = c->geom.y;
 		wlr_output_layout_output_coords(output_layout, m->wlr_output,
 				&ox, &oy);
+
+		if (c->bw == 0)
+			goto render;
+
 		w = surface->current.width;
 		h = surface->current.height;
 		borders = (struct wlr_box[4]) {
@@ -1210,6 +1216,7 @@ renderclients(Monitor *m, struct timespec *now)
 					m->wlr_output->transform_matrix);
 		}
 
+ render:
 		/* This calls our render function for each surface among the
 		 * xdg_surface's toplevel and popups. */
 		rdata.output = m->wlr_output;
-- 
cgit v1.2.3


From 43bd806291ab1b4bf46cbe35cddebba9af97fd54 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 17:11:26 +0200
Subject: Restore windows after fullscreen

Store position and size of windows before going fullscreen. This is more
efficient than arrange() and also works with floating windows

All the clients keep their original position because arrange() isn't
used after quitting fullscreen
---
 dwl.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/dwl.c b/dwl.c
index e516316..f139bf6 100644
--- a/dwl.c
+++ b/dwl.c
@@ -106,6 +106,10 @@ typedef struct {
 	unsigned int tags;
 	int isfloating;
 	uint32_t resize; /* configure serial of a pending resize */
+	int prevx;
+	int prevy;
+	int prevwidth;
+	int prevheight;
 } Client;
 
 typedef struct {
@@ -675,6 +679,16 @@ fullscreenotify(struct wl_listener *listener, void *data) {
 	wlr_xdg_toplevel_set_fullscreen(
 			c->surface.xdg, !c->surface.xdg->toplevel->current.fullscreen);
 	c->bw = (int)c->surface.xdg->toplevel->current.fullscreen * borderpx;
+
+	if (c->surface.xdg->toplevel->current.fullscreen) { /* fullscreen off */
+		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
+	} else { /* fullscreen on */
+		c->prevx = c->geom.x;
+		c->prevy = c->geom.y;
+		c->prevheight = c->geom.height;
+		c->prevwidth = c->geom.width;
+		resize(c, c->mon->w.x, c->mon->w.y, c->mon->w.width, c->mon->w.height, 0);
+	}
 }
 
 Monitor *
-- 
cgit v1.2.3


From aeae3dadbb94b77ecd45f1ab89769496c71d3782 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Sat, 5 Sep 2020 10:37:59 +0200
Subject: Unlink fullscreen

---
 dwl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/dwl.c b/dwl.c
index f139bf6..4911905 100644
--- a/dwl.c
+++ b/dwl.c
@@ -653,6 +653,7 @@ destroynotify(struct wl_listener *listener, void *data)
 	wl_list_remove(&c->map.link);
 	wl_list_remove(&c->unmap.link);
 	wl_list_remove(&c->destroy.link);
+	wl_list_remove(&c->fullscreen.link);
 #ifdef XWAYLAND
 	if (c->type == X11Managed)
 		wl_list_remove(&c->activate.link);
-- 
cgit v1.2.3


From dd2adb38ae69a59de2d1fb65452f4db459cc5c6b Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 19:20:07 +0200
Subject: Fullscreen xwayland

---
 dwl.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 4911905..8bd1725 100644
--- a/dwl.c
+++ b/dwl.c
@@ -110,6 +110,7 @@ typedef struct {
 	int prevy;
 	int prevwidth;
 	int prevheight;
+	bool isfullscreen;
 } Client;
 
 typedef struct {
@@ -293,6 +294,7 @@ static struct wl_listener request_set_sel = {.notify = setsel};
 #ifdef XWAYLAND
 static void activatex11(struct wl_listener *listener, void *data);
 static void createnotifyx11(struct wl_listener *listener, void *data);
+static void fullscreenotifyx11(struct wl_listener *listener, void *data);
 static Atom getatom(xcb_connection_t *xc, const char *name);
 static void renderindependents(struct wlr_output *output, struct timespec *now);
 static void updatewindowtype(Client *c);
@@ -605,8 +607,8 @@ createnotify(struct wl_listener *listener, void *data)
 	c->destroy.notify = destroynotify;
 	wl_signal_add(&xdg_surface->events.destroy, &c->destroy);
 
-	wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen);
 	c->fullscreen.notify = fullscreenotify;
+	wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen);
 }
 
 void
@@ -1847,6 +1849,34 @@ createnotifyx11(struct wl_listener *listener, void *data)
 	wl_signal_add(&xwayland_surface->events.request_activate, &c->activate);
 	c->destroy.notify = destroynotify;
 	wl_signal_add(&xwayland_surface->events.destroy, &c->destroy);
+
+	c->fullscreen.notify = fullscreenotifyx11;
+	wl_signal_add(&xwayland_surface->events.request_fullscreen, &c->fullscreen);
+	c->isfullscreen = false;
+}
+
+void
+fullscreenotifyx11(struct wl_listener *listener, void *data) {
+	FILE *xway = fopen("/tmp/dwl/xway", "a");
+    Client *c;
+	c = wl_container_of(listener, c, fullscreen);
+	c->isfullscreen = !c->isfullscreen;
+	wlr_xwayland_surface_set_fullscreen(
+			c->surface.xwayland, c->isfullscreen);
+	c->bw = ((int)(!c->isfullscreen)) * borderpx;
+
+	fprintf(xway, "fullscreen: %d\n", c->surface.xwayland->fullscreen);
+	fclose(xway);
+
+	if (c->isfullscreen) { /* fullscreen off */
+		c->prevx = c->geom.x;
+		c->prevy = c->geom.y;
+		c->prevheight = c->geom.height;
+		c->prevwidth = c->geom.width;
+		resize(c, c->mon->w.x, c->mon->w.y, c->mon->w.width, c->mon->w.height, 0);
+	} else { /* fullscreen on */
+		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 1);
+	}
 }
 
 Atom
-- 
cgit v1.2.3


From bd222cb75d9ee43ca0a35b158b5a00e9665ecef8 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 19:56:16 +0200
Subject: Same fscreen func for xdg and xwayland

---
 dwl.c | 46 ++++++++++++++--------------------------------
 1 file changed, 14 insertions(+), 32 deletions(-)

diff --git a/dwl.c b/dwl.c
index 8bd1725..6354072 100644
--- a/dwl.c
+++ b/dwl.c
@@ -294,7 +294,6 @@ static struct wl_listener request_set_sel = {.notify = setsel};
 #ifdef XWAYLAND
 static void activatex11(struct wl_listener *listener, void *data);
 static void createnotifyx11(struct wl_listener *listener, void *data);
-static void fullscreenotifyx11(struct wl_listener *listener, void *data);
 static Atom getatom(xcb_connection_t *xc, const char *name);
 static void renderindependents(struct wlr_output *output, struct timespec *now);
 static void updatewindowtype(Client *c);
@@ -609,6 +608,7 @@ createnotify(struct wl_listener *listener, void *data)
 
 	c->fullscreen.notify = fullscreenotify;
 	wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen);
+	c->isfullscreen = false;
 }
 
 void
@@ -679,18 +679,24 @@ destroyxdeco(struct wl_listener *listener, void *data)
 void
 fullscreenotify(struct wl_listener *listener, void *data) {
 	Client *c = wl_container_of(listener, c, fullscreen);
-	wlr_xdg_toplevel_set_fullscreen(
-			c->surface.xdg, !c->surface.xdg->toplevel->current.fullscreen);
-	c->bw = (int)c->surface.xdg->toplevel->current.fullscreen * borderpx;
+	c->isfullscreen = !c->isfullscreen;
 
-	if (c->surface.xdg->toplevel->current.fullscreen) { /* fullscreen off */
-		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
-	} else { /* fullscreen on */
+#ifdef XWAYLAND
+	if (c->type == X11Managed)
+		wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, c->isfullscreen);
+	else
+#endif
+		wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, c->isfullscreen);
+
+	c->bw = ((int)(!c->isfullscreen)) * borderpx;
+	if (c->isfullscreen) {
 		c->prevx = c->geom.x;
 		c->prevy = c->geom.y;
 		c->prevheight = c->geom.height;
 		c->prevwidth = c->geom.width;
 		resize(c, c->mon->w.x, c->mon->w.y, c->mon->w.width, c->mon->w.height, 0);
+	} else {
+		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
 	}
 }
 
@@ -1850,35 +1856,11 @@ createnotifyx11(struct wl_listener *listener, void *data)
 	c->destroy.notify = destroynotify;
 	wl_signal_add(&xwayland_surface->events.destroy, &c->destroy);
 
-	c->fullscreen.notify = fullscreenotifyx11;
+	c->fullscreen.notify = fullscreenotify;
 	wl_signal_add(&xwayland_surface->events.request_fullscreen, &c->fullscreen);
 	c->isfullscreen = false;
 }
 
-void
-fullscreenotifyx11(struct wl_listener *listener, void *data) {
-	FILE *xway = fopen("/tmp/dwl/xway", "a");
-    Client *c;
-	c = wl_container_of(listener, c, fullscreen);
-	c->isfullscreen = !c->isfullscreen;
-	wlr_xwayland_surface_set_fullscreen(
-			c->surface.xwayland, c->isfullscreen);
-	c->bw = ((int)(!c->isfullscreen)) * borderpx;
-
-	fprintf(xway, "fullscreen: %d\n", c->surface.xwayland->fullscreen);
-	fclose(xway);
-
-	if (c->isfullscreen) { /* fullscreen off */
-		c->prevx = c->geom.x;
-		c->prevy = c->geom.y;
-		c->prevheight = c->geom.height;
-		c->prevwidth = c->geom.width;
-		resize(c, c->mon->w.x, c->mon->w.y, c->mon->w.width, c->mon->w.height, 0);
-	} else { /* fullscreen on */
-		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 1);
-	}
-}
-
 Atom
 getatom(xcb_connection_t *xc, const char *name)
 {
-- 
cgit v1.2.3


From 73d717a9246320ad9fccd0a0fe7726ef937e7fc2 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 19:58:00 +0200
Subject: isfullscreen int

---
 dwl.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/dwl.c b/dwl.c
index 6354072..bdc1e69 100644
--- a/dwl.c
+++ b/dwl.c
@@ -110,7 +110,7 @@ typedef struct {
 	int prevy;
 	int prevwidth;
 	int prevheight;
-	bool isfullscreen;
+	int isfullscreen;
 } Client;
 
 typedef struct {
@@ -608,7 +608,7 @@ createnotify(struct wl_listener *listener, void *data)
 
 	c->fullscreen.notify = fullscreenotify;
 	wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen);
-	c->isfullscreen = false;
+	c->isfullscreen = 0;
 }
 
 void
@@ -677,7 +677,8 @@ destroyxdeco(struct wl_listener *listener, void *data)
 }
 
 void
-fullscreenotify(struct wl_listener *listener, void *data) {
+fullscreenotify(struct wl_listener *listener, void *data)
+{
 	Client *c = wl_container_of(listener, c, fullscreen);
 	c->isfullscreen = !c->isfullscreen;
 
@@ -1858,7 +1859,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
 
 	c->fullscreen.notify = fullscreenotify;
 	wl_signal_add(&xwayland_surface->events.request_fullscreen, &c->fullscreen);
-	c->isfullscreen = false;
+	c->isfullscreen = 0;
 }
 
 Atom
-- 
cgit v1.2.3


From d9cf3e064c0972102921dae2280fff1c5272b435 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Fri, 4 Sep 2020 23:32:29 +0200
Subject: Handle new windows

Windows lose fullscreen state when a new window is created in the same
tag
---
 dwl.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index bdc1e69..c72533a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -198,11 +198,11 @@ static void createxdeco(struct wl_listener *listener, void *data);
 static void cursorframe(struct wl_listener *listener, void *data);
 static void destroynotify(struct wl_listener *listener, void *data);
 static void destroyxdeco(struct wl_listener *listener, void *data);
-static void fullscreenotify(struct wl_listener *listener, void *data);
 static Monitor *dirtomon(int dir);
 static void focusclient(Client *old, Client *c, int lift);
 static void focusmon(const Arg *arg);
 static void focusstack(const Arg *arg);
+static void fullscreenotify(struct wl_listener *listener, void *data);
 static Client *focustop(Monitor *m);
 static void getxdecomode(struct wl_listener *listener, void *data);
 static void incnmaster(const Arg *arg);
@@ -217,6 +217,7 @@ static void motionabsolute(struct wl_listener *listener, void *data);
 static void motionnotify(uint32_t time);
 static void motionrelative(struct wl_listener *listener, void *data);
 static void moveresize(const Arg *arg);
+static void quitfullscreen(Client *c);
 static void pointerfocus(Client *c, struct wlr_surface *surface,
 		double sx, double sy, uint32_t time);
 static void quit(const Arg *arg);
@@ -576,6 +577,24 @@ createmon(struct wl_listener *listener, void *data)
 	sgeom = *wlr_output_layout_get_box(output_layout, NULL);
 }
 
+void
+quitfullscreen(Client *c)
+{
+	wl_list_for_each(c, &clients, link) {
+		if (c->isfullscreen && VISIBLEON(c, c->mon)) {
+#ifdef XWAYLAND
+			if (c->type == X11Managed)
+				wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, false);
+			else
+#endif
+				wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, false);
+			c->bw = borderpx;
+			resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
+			c->isfullscreen = 0;
+		}
+	}
+}
+
 void
 createnotify(struct wl_listener *listener, void *data)
 {
@@ -591,6 +610,7 @@ createnotify(struct wl_listener *listener, void *data)
 	c = xdg_surface->data = calloc(1, sizeof(*c));
 	c->surface.xdg = xdg_surface;
 	c->bw = borderpx;
+	quitfullscreen(c);
 
 	/* Tell the client not to try anything fancy */
 	wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP |
@@ -635,7 +655,6 @@ createxdeco(struct wl_listener *listener, void *data)
 	getxdecomode(&d->request_mode, wlr_deco);
 }
 
-
 void
 cursorframe(struct wl_listener *listener, void *data)
 {
@@ -1846,6 +1865,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
 	c->surface.xwayland = xwayland_surface;
 	c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
 	c->bw = borderpx;
+	quitfullscreen(c);
 
 	/* Listen to the various events it can emit */
 	c->map.notify = maprequest;
-- 
cgit v1.2.3


From 621d4c9173af194f703a6f197a50e597a8a20498 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Sat, 5 Sep 2020 11:22:24 +0200
Subject: Toggle fullscreen on all clients

mod+e allows to toggle fullscreen any client, even those who don't
support it themselves
---
 config.def.h |  1 +
 dwl.c        | 21 ++++++++++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/config.def.h b/config.def.h
index 53021cf..d821a96 100644
--- a/config.def.h
+++ b/config.def.h
@@ -75,6 +75,7 @@ static const Key keys[] = {
 	{ MODKEY,                    XKB_KEY_m,          setlayout,      {.v = &layouts[2]} },
 	{ MODKEY,                    XKB_KEY_space,      setlayout,      {0} },
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
+	{ MODKEY, 					 XKB_KEY_e,    		togglefullscreen, {0} },
 	{ MODKEY,                    XKB_KEY_0,          view,           {.ui = ~0} },
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag,            {.ui = ~0} },
 	{ MODKEY,                    XKB_KEY_comma,      focusmon,       {.i = -1} },
diff --git a/dwl.c b/dwl.c
index c72533a..79a1116 100644
--- a/dwl.c
+++ b/dwl.c
@@ -232,6 +232,7 @@ static void setcursor(struct wl_listener *listener, void *data);
 static void setpsel(struct wl_listener *listener, void *data);
 static void setsel(struct wl_listener *listener, void *data);
 static void setfloating(Client *c, int floating);
+static void setfullscreen(Client *c, int fullscreen);
 static void setlayout(const Arg *arg);
 static void setmfact(const Arg *arg);
 static void setmon(Client *c, Monitor *m, unsigned int newtags);
@@ -242,6 +243,7 @@ static void tag(const Arg *arg);
 static void tagmon(const Arg *arg);
 static void tile(Monitor *m);
 static void togglefloating(const Arg *arg);
+static void togglefullscreen(const Arg *arg);
 static void toggletag(const Arg *arg);
 static void toggleview(const Arg *arg);
 static void unmapnotify(struct wl_listener *listener, void *data);
@@ -696,10 +698,16 @@ destroyxdeco(struct wl_listener *listener, void *data)
 }
 
 void
-fullscreenotify(struct wl_listener *listener, void *data)
+togglefullscreen(const Arg *arg)
 {
-	Client *c = wl_container_of(listener, c, fullscreen);
-	c->isfullscreen = !c->isfullscreen;
+	Client *sel = selclient();
+	setfullscreen(sel, !sel->isfullscreen);
+}
+
+void
+setfullscreen(Client *c, int fullscreen)
+{
+	c->isfullscreen = fullscreen;
 
 #ifdef XWAYLAND
 	if (c->type == X11Managed)
@@ -720,6 +728,13 @@ fullscreenotify(struct wl_listener *listener, void *data)
 	}
 }
 
+void
+fullscreenotify(struct wl_listener *listener, void *data)
+{
+	Client *c = wl_container_of(listener, c, fullscreen);
+	setfullscreen(c, !c->isfullscreen);
+}
+
 Monitor *
 dirtomon(int dir)
 {
-- 
cgit v1.2.3


From d8570d5ceb1c4e54854c38437fe1d24d8914e09c Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Sun, 6 Sep 2020 10:27:24 +0200
Subject: Allow borderpx = 0

---
 dwl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 79a1116..0822508 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1254,7 +1254,7 @@ renderclients(Monitor *m, struct timespec *now)
 		wlr_output_layout_output_coords(output_layout, m->wlr_output,
 				&ox, &oy);
 
-		if (c->bw == 0)
+		if (c->isfullscreen || borderpx == 0)
 			goto render;
 
 		w = surface->current.width;
@@ -1274,7 +1274,7 @@ renderclients(Monitor *m, struct timespec *now)
 					m->wlr_output->transform_matrix);
 		}
 
- render:
+render:
 		/* This calls our render function for each surface among the
 		 * xdg_surface's toplevel and popups. */
 		rdata.output = m->wlr_output;
-- 
cgit v1.2.3


From 8d8d24db09625d6cf83debe068e7334fd8178eea Mon Sep 17 00:00:00 2001
From: Guido Cella <guidocella91@gmail.com>
Date: Thu, 10 Sep 2020 09:09:46 +0200
Subject: fix typo

---
 dwl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dwl.c b/dwl.c
index 0822508..d143dd6 100644
--- a/dwl.c
+++ b/dwl.c
@@ -202,7 +202,7 @@ static Monitor *dirtomon(int dir);
 static void focusclient(Client *old, Client *c, int lift);
 static void focusmon(const Arg *arg);
 static void focusstack(const Arg *arg);
-static void fullscreenotify(struct wl_listener *listener, void *data);
+static void fullscreennotify(struct wl_listener *listener, void *data);
 static Client *focustop(Monitor *m);
 static void getxdecomode(struct wl_listener *listener, void *data);
 static void incnmaster(const Arg *arg);
@@ -628,7 +628,7 @@ createnotify(struct wl_listener *listener, void *data)
 	c->destroy.notify = destroynotify;
 	wl_signal_add(&xdg_surface->events.destroy, &c->destroy);
 
-	c->fullscreen.notify = fullscreenotify;
+	c->fullscreen.notify = fullscreennotify;
 	wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen);
 	c->isfullscreen = 0;
 }
@@ -729,7 +729,7 @@ setfullscreen(Client *c, int fullscreen)
 }
 
 void
-fullscreenotify(struct wl_listener *listener, void *data)
+fullscreennotify(struct wl_listener *listener, void *data)
 {
 	Client *c = wl_container_of(listener, c, fullscreen);
 	setfullscreen(c, !c->isfullscreen);
@@ -1892,7 +1892,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
 	c->destroy.notify = destroynotify;
 	wl_signal_add(&xwayland_surface->events.destroy, &c->destroy);
 
-	c->fullscreen.notify = fullscreenotify;
+	c->fullscreen.notify = fullscreennotify;
 	wl_signal_add(&xwayland_surface->events.request_fullscreen, &c->fullscreen);
 	c->isfullscreen = 0;
 }
-- 
cgit v1.2.3


From 2b286ffeeda4fcd618c8f6a3c86efb8e96050bd2 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Wed, 16 Sep 2020 09:20:07 +0200
Subject: use m->m (fullscreen on top of layers)

---
 dwl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index d143dd6..1177fa8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -722,7 +722,7 @@ setfullscreen(Client *c, int fullscreen)
 		c->prevy = c->geom.y;
 		c->prevheight = c->geom.height;
 		c->prevwidth = c->geom.width;
-		resize(c, c->mon->w.x, c->mon->w.y, c->mon->w.width, c->mon->w.height, 0);
+		resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
 	} else {
 		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
 	}
-- 
cgit v1.2.3


From 172bcfd3ffcbaafb5198b162f8b704b0172fe9a0 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Thu, 8 Oct 2020 21:04:28 +0200
Subject: Set fullscreen simpler

---
 dwl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dwl.c b/dwl.c
index 1177fa8..d7cc46f 100644
--- a/dwl.c
+++ b/dwl.c
@@ -708,16 +708,16 @@ void
 setfullscreen(Client *c, int fullscreen)
 {
 	c->isfullscreen = fullscreen;
+	c->bw = (1 - fullscreen) * borderpx;
 
 #ifdef XWAYLAND
 	if (c->type == X11Managed)
-		wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, c->isfullscreen);
+		wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen);
 	else
 #endif
-		wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, c->isfullscreen);
+		wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen);
 
-	c->bw = ((int)(!c->isfullscreen)) * borderpx;
-	if (c->isfullscreen) {
+	if (fullscreen) {
 		c->prevx = c->geom.x;
 		c->prevy = c->geom.y;
 		c->prevheight = c->geom.height;
-- 
cgit v1.2.3


From a2ed3d45bb1e2cd8c7f1df54283b3188c3b23841 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Thu, 8 Oct 2020 21:04:53 +0200
Subject: Keep windows fullscreen after redraw

This fixes the bug that happens when changing workspace (or any time
arrange() is called) where there are fullscreen windows, which are still
fullscreen but leave the space for layer surfaces like waybar (which
should be hidden when going fullscreen)

Also as soon one fullscreen window is found hte function returns to
improve efficiency
---
 dwl.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/dwl.c b/dwl.c
index d7cc46f..c0182c5 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1017,6 +1017,10 @@ monocle(Monitor *m)
 	wl_list_for_each(c, &clients, link) {
 		if (!VISIBLEON(c, m) || c->isfloating)
 			continue;
+		if (c->isfullscreen) {
+			resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
+			return;
+		}
 		resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0);
 	}
 }
@@ -1728,6 +1732,10 @@ tile(Monitor *m)
 	wl_list_for_each(c, &clients, link) {
 		if (!VISIBLEON(c, m) || c->isfloating)
 			continue;
+		if (c->isfullscreen) {
+			resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
+			return;
+		}
 		if (i < m->nmaster) {
 			h = (m->w.height - my) / (MIN(n, m->nmaster) - i);
 			resize(c, m->w.x, m->w.y + my, mw, h, 0);
-- 
cgit v1.2.3


From 0ad8473a57708b0c7145a4e6ae8590fb6a035701 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Wed, 14 Oct 2020 15:46:35 +0200
Subject: Delete quitfullscreen()

quitfullscreen() was replicating the functionalities of setfullscreen(c,
0)

Reusing setfullscreen() in quitfullscreen() leads to a 3 line function,
which is useless since quitfullscreen() is used once anyway
---
 dwl.c | 24 ++++--------------------
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/dwl.c b/dwl.c
index c0182c5..e0e3b30 100644
--- a/dwl.c
+++ b/dwl.c
@@ -217,7 +217,6 @@ static void motionabsolute(struct wl_listener *listener, void *data);
 static void motionnotify(uint32_t time);
 static void motionrelative(struct wl_listener *listener, void *data);
 static void moveresize(const Arg *arg);
-static void quitfullscreen(Client *c);
 static void pointerfocus(Client *c, struct wlr_surface *surface,
 		double sx, double sy, uint32_t time);
 static void quit(const Arg *arg);
@@ -579,24 +578,6 @@ createmon(struct wl_listener *listener, void *data)
 	sgeom = *wlr_output_layout_get_box(output_layout, NULL);
 }
 
-void
-quitfullscreen(Client *c)
-{
-	wl_list_for_each(c, &clients, link) {
-		if (c->isfullscreen && VISIBLEON(c, c->mon)) {
-#ifdef XWAYLAND
-			if (c->type == X11Managed)
-				wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, false);
-			else
-#endif
-				wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, false);
-			c->bw = borderpx;
-			resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
-			c->isfullscreen = 0;
-		}
-	}
-}
-
 void
 createnotify(struct wl_listener *listener, void *data)
 {
@@ -608,11 +589,14 @@ createnotify(struct wl_listener *listener, void *data)
 	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 		return;
 
+	wl_list_for_each(c, &clients, link)
+		if (c->isfullscreen && VISIBLEON(c, c->mon))
+			setfullscreen(c, 0);
+
 	/* Allocate a Client for this surface */
 	c = xdg_surface->data = calloc(1, sizeof(*c));
 	c->surface.xdg = xdg_surface;
 	c->bw = borderpx;
-	quitfullscreen(c);
 
 	/* Tell the client not to try anything fancy */
 	wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP |
-- 
cgit v1.2.3


From c98686cf1618da2e581f46d4723016365606b591 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Wed, 14 Oct 2020 17:28:51 +0200
Subject: Quit fullscreen on new x11 window

After the removal of quitfullscreen() dwl wouldn't compile widh xwayland
enabled because createnotifyx11 was still using the old function
---
 dwl.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/dwl.c b/dwl.c
index e0e3b30..05739a8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -588,7 +588,6 @@ createnotify(struct wl_listener *listener, void *data)
 
 	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 		return;
-
 	wl_list_for_each(c, &clients, link)
 		if (c->isfullscreen && VISIBLEON(c, c->mon))
 			setfullscreen(c, 0);
@@ -1242,7 +1241,7 @@ renderclients(Monitor *m, struct timespec *now)
 		wlr_output_layout_output_coords(output_layout, m->wlr_output,
 				&ox, &oy);
 
-		if (c->isfullscreen || borderpx == 0)
+		if (c->isfullscreen)
 			goto render;
 
 		w = surface->current.width;
@@ -1866,13 +1865,15 @@ createnotifyx11(struct wl_listener *listener, void *data)
 {
 	struct wlr_xwayland_surface *xwayland_surface = data;
 	Client *c;
+	wl_list_for_each(c, &clients, link)
+		if (c->isfullscreen && VISIBLEON(c, c->mon))
+			setfullscreen(c, 0);
 
 	/* Allocate a Client for this surface */
 	c = xwayland_surface->data = calloc(1, sizeof(*c));
 	c->surface.xwayland = xwayland_surface;
 	c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
 	c->bw = borderpx;
-	quitfullscreen(c);
 
 	/* Listen to the various events it can emit */
 	c->map.notify = maprequest;
-- 
cgit v1.2.3


From fcc869ed8480c21cd8b36d9fc3bd8dd3b8cee981 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Sat, 24 Oct 2020 16:51:22 +0200
Subject: Readme: achieve fullscreen + allow borderpx = 0

---
 README.md | 1 -
 dwl.c     | 4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 3251ccf..1439a0b 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,6 @@ dwl is a work in progress, and it has not yet reached its feature goals in a num
 - Statusbar support (built-in or external)
 - layer-shell
 - Damage tracking
-- Fullscreen/fixed windows (or whatever the Wayland analogues are)
 
 
 ## Acknowledgements
diff --git a/dwl.c b/dwl.c
index 05739a8..1a26ab6 100644
--- a/dwl.c
+++ b/dwl.c
@@ -700,6 +700,7 @@ setfullscreen(Client *c, int fullscreen)
 #endif
 		wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen);
 
+	// restore previous size instead of arrange to work with floating windows
 	if (fullscreen) {
 		c->prevx = c->geom.x;
 		c->prevy = c->geom.y;
@@ -1240,8 +1241,7 @@ renderclients(Monitor *m, struct timespec *now)
 		ox = c->geom.x, oy = c->geom.y;
 		wlr_output_layout_output_coords(output_layout, m->wlr_output,
 				&ox, &oy);
-
-		if (c->isfullscreen)
+		if (c->bw == 0)
 			goto render;
 
 		w = surface->current.width;
-- 
cgit v1.2.3


From 86ba4c8526d8b96eb0caaa60f8f42edb51b2b558 Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Thu, 24 Dec 2020 00:34:33 +0100
Subject: Remove goto render (easier merge)

---
 dwl.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/dwl.c b/dwl.c
index 1a26ab6..8e1e384 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1241,27 +1241,26 @@ renderclients(Monitor *m, struct timespec *now)
 		ox = c->geom.x, oy = c->geom.y;
 		wlr_output_layout_output_coords(output_layout, m->wlr_output,
 				&ox, &oy);
-		if (c->bw == 0)
-			goto render;
-
-		w = surface->current.width;
-		h = surface->current.height;
-		borders = (struct wlr_box[4]) {
-			{ox, oy, w + 2 * c->bw, c->bw},             /* top */
-			{ox, oy + c->bw, c->bw, h},                 /* left */
-			{ox + c->bw + w, oy + c->bw, c->bw, h},     /* right */
-			{ox, oy + c->bw + h, w + 2 * c->bw, c->bw}, /* bottom */
-		};
-
-		/* Draw window borders */
-		color = (c == sel) ? focuscolor : bordercolor;
-		for (i = 0; i < 4; i++) {
-			scalebox(&borders[i], m->wlr_output->scale);
-			wlr_render_rect(drw, &borders[i], color,
-					m->wlr_output->transform_matrix);
+
+		if (c->bw) {
+			w = surface->current.width;
+			h = surface->current.height;
+			borders = (struct wlr_box[4]) {
+				{ox, oy, w + 2 * c->bw, c->bw},             /* top */
+				{ox, oy + c->bw, c->bw, h},                 /* left */
+				{ox + c->bw + w, oy + c->bw, c->bw, h},     /* right */
+				{ox, oy + c->bw + h, w + 2 * c->bw, c->bw}, /* bottom */
+			};
+
+			/* Draw window borders */
+			color = (c == sel) ? focuscolor : bordercolor;
+			for (i = 0; i < 4; i++) {
+				scalebox(&borders[i], m->wlr_output->scale);
+				wlr_render_rect(drw, &borders[i], color,
+						m->wlr_output->transform_matrix);
+			}
 		}
 
-render:
 		/* This calls our render function for each surface among the
 		 * xdg_surface's toplevel and popups. */
 		rdata.output = m->wlr_output;
-- 
cgit v1.2.3


From 707c1710b7df87ee61db26b325eaa6529beba9ac Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Thu, 24 Dec 2020 01:02:45 +0100
Subject: quitallfullscreen() even when enabling fullscreen

Disable fullscreen on all visible clients in that monitor also before
enabling it on another client.

quitallfullscreen() is reintroduced becouse is now more useful

set c->isfullscreen later to avoid making quitallfullscreen() disable
fullscreen on the current client
---
 dwl.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/dwl.c b/dwl.c
index 8e1e384..5e1591b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -220,6 +220,7 @@ static void moveresize(const Arg *arg);
 static void pointerfocus(Client *c, struct wlr_surface *surface,
 		double sx, double sy, uint32_t time);
 static void quit(const Arg *arg);
+static void quitallfullscreen();
 static void render(struct wlr_surface *surface, int sx, int sy, void *data);
 static void renderclients(Monitor *m, struct timespec *now);
 static void rendermon(struct wl_listener *listener, void *data);
@@ -588,9 +589,7 @@ createnotify(struct wl_listener *listener, void *data)
 
 	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 		return;
-	wl_list_for_each(c, &clients, link)
-		if (c->isfullscreen && VISIBLEON(c, c->mon))
-			setfullscreen(c, 0);
+	quitallfullscreen();
 
 	/* Allocate a Client for this surface */
 	c = xdg_surface->data = calloc(1, sizeof(*c));
@@ -687,10 +686,18 @@ togglefullscreen(const Arg *arg)
 	setfullscreen(sel, !sel->isfullscreen);
 }
 
+void
+quitallfullscreen()
+{
+	Client *c;
+	wl_list_for_each(c, &clients, link)
+		if (c->isfullscreen && VISIBLEON(c, selmon))
+			setfullscreen(c, 0);
+}
+
 void
 setfullscreen(Client *c, int fullscreen)
 {
-	c->isfullscreen = fullscreen;
 	c->bw = (1 - fullscreen) * borderpx;
 
 #ifdef XWAYLAND
@@ -702,6 +709,7 @@ setfullscreen(Client *c, int fullscreen)
 
 	// restore previous size instead of arrange to work with floating windows
 	if (fullscreen) {
+		quitallfullscreen();
 		c->prevx = c->geom.x;
 		c->prevy = c->geom.y;
 		c->prevheight = c->geom.height;
@@ -710,6 +718,7 @@ setfullscreen(Client *c, int fullscreen)
 	} else {
 		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
 	}
+	c->isfullscreen = fullscreen;
 }
 
 void
@@ -1864,9 +1873,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
 {
 	struct wlr_xwayland_surface *xwayland_surface = data;
 	Client *c;
-	wl_list_for_each(c, &clients, link)
-		if (c->isfullscreen && VISIBLEON(c, c->mon))
-			setfullscreen(c, 0);
+	quitallfullscreen();
 
 	/* Allocate a Client for this surface */
 	c = xwayland_surface->data = calloc(1, sizeof(*c));
-- 
cgit v1.2.3


From d21d5ee26227e6ec70973cfdac326f4828b7237c Mon Sep 17 00:00:00 2001
From: Stivvo <stivvo01@gmail.com>
Date: Thu, 24 Dec 2020 17:30:12 +0100
Subject: Change fullscreen policies

When a new client is spawned, fullscreen isn't disabled for all clients
in that monitor any more.

Instead, all fullscreen clients are kept fullscreen, while other clients
spawn in the background.

When fullscreen is disabled, all clients are rearranged.

This is made to make dwl more flexible allowing multiple fullscreen
clients at the same time, have floating clients on top of a fullscreen
one and let stuff happen without quitting fullscreen, like many other
WMs and DEs.
---
 dwl.c | 55 ++++++++++++++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/dwl.c b/dwl.c
index 5e1591b..20d1c98 100644
--- a/dwl.c
+++ b/dwl.c
@@ -152,6 +152,7 @@ struct Monitor {
 	unsigned int tagset[2];
 	double mfact;
 	int nmaster;
+	Client *fullscreenclient;
 };
 
 typedef struct {
@@ -212,6 +213,7 @@ static void keypress(struct wl_listener *listener, void *data);
 static void keypressmod(struct wl_listener *listener, void *data);
 static void killclient(const Arg *arg);
 static void maprequest(struct wl_listener *listener, void *data);
+static void maximizeclient(Client *c);
 static void monocle(Monitor *m);
 static void motionabsolute(struct wl_listener *listener, void *data);
 static void motionnotify(uint32_t time);
@@ -220,7 +222,6 @@ static void moveresize(const Arg *arg);
 static void pointerfocus(Client *c, struct wlr_surface *surface,
 		double sx, double sy, uint32_t time);
 static void quit(const Arg *arg);
-static void quitallfullscreen();
 static void render(struct wlr_surface *surface, int sx, int sy, void *data);
 static void renderclients(Monitor *m, struct timespec *now);
 static void rendermon(struct wl_listener *listener, void *data);
@@ -380,6 +381,8 @@ arrange(Monitor *m)
 	m->w = m->m;
 	if (m->lt[m->sellt]->arrange)
 		m->lt[m->sellt]->arrange(m);
+	else if (m->fullscreenclient)
+		maximizeclient(m->fullscreenclient);
 	/* XXX recheck pointer focus here... or in resize()? */
 }
 
@@ -589,7 +592,6 @@ createnotify(struct wl_listener *listener, void *data)
 
 	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 		return;
-	quitallfullscreen();
 
 	/* Allocate a Client for this surface */
 	c = xdg_surface->data = calloc(1, sizeof(*c));
@@ -687,17 +689,16 @@ togglefullscreen(const Arg *arg)
 }
 
 void
-quitallfullscreen()
+maximizeclient(Client *c)
 {
-	Client *c;
-	wl_list_for_each(c, &clients, link)
-		if (c->isfullscreen && VISIBLEON(c, selmon))
-			setfullscreen(c, 0);
+	resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
+	/* used for fullscreen clients */
 }
 
 void
 setfullscreen(Client *c, int fullscreen)
 {
+	c->isfullscreen = fullscreen;
 	c->bw = (1 - fullscreen) * borderpx;
 
 #ifdef XWAYLAND
@@ -707,18 +708,20 @@ setfullscreen(Client *c, int fullscreen)
 #endif
 		wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen);
 
-	// restore previous size instead of arrange to work with floating windows
 	if (fullscreen) {
-		quitallfullscreen();
 		c->prevx = c->geom.x;
 		c->prevy = c->geom.y;
 		c->prevheight = c->geom.height;
 		c->prevwidth = c->geom.width;
-		resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
+		c->mon->fullscreenclient = c;
+		maximizeclient(c);
 	} else {
+		/* restore previous size instead of arrange for floating windows since
+		 * client positions are set by the user and cannot be recalculated */
 		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
+		c->mon->fullscreenclient = NULL;
+		arrange(c->mon);
 	}
-	c->isfullscreen = fullscreen;
 }
 
 void
@@ -969,7 +972,7 @@ void
 maprequest(struct wl_listener *listener, void *data)
 {
 	/* Called when the surface is mapped, or ready to display on-screen. */
-	Client *c = wl_container_of(listener, c, map);
+	Client *c = wl_container_of(listener, c, map), *oldfocus = selclient();
 
 #ifdef XWAYLAND
 	if (c->type == X11Unmanaged) {
@@ -1000,6 +1003,14 @@ maprequest(struct wl_listener *listener, void *data)
 
 	/* Set initial monitor, tags, floating status, and focus */
 	applyrules(c);
+
+	if (c->mon->fullscreenclient && c->mon->fullscreenclient == oldfocus
+			&& !c->isfloating && c->mon->lt[c->mon->sellt]->arrange) {
+		maximizeclient(c->mon->fullscreenclient);
+		focusclient(c, c->mon->fullscreenclient, 1);
+		/* give the focus back the fullscreen client on that monitor if exists,
+		 * is focused and the new client isn't floating */
+	}
 }
 
 void
@@ -1010,11 +1021,10 @@ monocle(Monitor *m)
 	wl_list_for_each(c, &clients, link) {
 		if (!VISIBLEON(c, m) || c->isfloating)
 			continue;
-		if (c->isfullscreen) {
-			resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
-			return;
-		}
-		resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0);
+		if (c->isfullscreen)
+			maximizeclient(c);
+		else
+			resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0);
 	}
 }
 
@@ -1452,8 +1462,6 @@ setcursor(struct wl_listener *listener, void *data)
 void
 setfloating(Client *c, int floating)
 {
-	if (c->isfloating == floating)
-		return;
 	c->isfloating = floating;
 	arrange(c->mon);
 }
@@ -1723,11 +1731,9 @@ tile(Monitor *m)
 	wl_list_for_each(c, &clients, link) {
 		if (!VISIBLEON(c, m) || c->isfloating)
 			continue;
-		if (c->isfullscreen) {
-			resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
-			return;
-		}
-		if (i < m->nmaster) {
+		if (c->isfullscreen)
+			maximizeclient(c);
+		else if (i < m->nmaster) {
 			h = (m->w.height - my) / (MIN(n, m->nmaster) - i);
 			resize(c, m->w.x, m->w.y + my, mw, h, 0);
 			my += c->geom.height;
@@ -1873,7 +1879,6 @@ createnotifyx11(struct wl_listener *listener, void *data)
 {
 	struct wlr_xwayland_surface *xwayland_surface = data;
 	Client *c;
-	quitallfullscreen();
 
 	/* Allocate a Client for this surface */
 	c = xwayland_surface->data = calloc(1, sizeof(*c));
-- 
cgit v1.2.3