summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dwl.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/dwl.c b/dwl.c
index d72d13e..77b3d5d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -58,6 +58,7 @@ typedef struct Monitor Monitor;
typedef struct {
struct wl_list link;
struct wl_list flink;
+ struct wl_list slink;
struct wlr_xdg_surface *xdg_surface;
struct wl_listener map;
struct wl_listener unmap;
@@ -145,6 +146,7 @@ static void motionnotify(uint32_t time);
static void motionrelative(struct wl_listener *listener, void *data);
static void movemouse(const Arg *arg);
static void quit(const Arg *arg);
+static void raiseclient(Client *c);
static void refocus(void);
static void render(struct wlr_surface *surface, int sx, int sy, void *data);
static void rendermon(struct wl_listener *listener, void *data);
@@ -179,6 +181,7 @@ static struct wlr_xdg_shell *xdg_shell;
static struct wl_listener new_xdg_surface;
static struct wl_list clients; /* tiling order */
static struct wl_list fstack; /* focus order */
+static struct wl_list stack; /* stacking z-order */
static struct wlr_cursor *cursor;
static struct wlr_xcursor_manager *cursor_mgr;
@@ -240,8 +243,10 @@ buttonpress(struct wl_listener *listener, void *data)
cursor_mode = CurNormal;
} else {
/* Change focus if the button was _pressed_ over a client */
- if (c)
+ if (c) {
focus(c, surface);
+ raiseclient(c);
+ }
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat);
uint32_t mods = wlr_keyboard_get_modifiers(keyboard);
@@ -491,6 +496,7 @@ focusstack(const Arg *arg)
}
/* If only one client is visible on selmon, then c == sel */
focus(c, NULL);
+ raiseclient(c);
}
void
@@ -601,6 +607,7 @@ maprequest(struct wl_listener *listener, void *data)
c->tags = c->mon->tagset[c->mon->seltags];
wl_list_insert(&clients, &c->link);
wl_list_insert(&fstack, &c->flink);
+ wl_list_insert(&stack, &c->slink);
focus(c, NULL);
}
@@ -732,10 +739,20 @@ refocus(void)
break;
}
}
+ /* XXX consider: should this ever? always? raise the client? */
focus(c, NULL);
}
void
+raiseclient(Client *c)
+{
+ if (!c)
+ return;
+ wl_list_remove(&c->slink);
+ wl_list_insert(&stack, &c->slink);
+}
+
+void
render(struct wlr_surface *surface, int sx, int sy, void *data)
{
/* This function is called for every surface that needs to be rendered. */
@@ -822,9 +839,9 @@ rendermon(struct wl_listener *listener, void *data)
wlr_renderer_clear(drw, rootcolor);
/* Each subsequent window we render is rendered on top of the last. Because
- * our focus stack is ordered front-to-back, we iterate over it backwards. */
+ * our stacking list is ordered front-to-back, we iterate over it backwards. */
Client *c;
- wl_list_for_each_reverse(c, &fstack, flink) {
+ wl_list_for_each_reverse(c, &stack, slink) {
/* Only render clients which are on this monitor. */
/* XXX consider checking wlr_output_layout_intersects, in case a
* window can be seen on multiple outputs */
@@ -1045,7 +1062,7 @@ setup(void)
new_output.notify = createmon;
wl_signal_add(&backend->events.new_output, &new_output);
- /* Set up our lists of clients and the xdg-shell. The xdg-shell is a
+ /* Set up our client lists and the xdg-shell. The xdg-shell is a
* Wayland protocol which is used for application windows. For more
* detail on shells, refer to the article:
*
@@ -1053,6 +1070,7 @@ setup(void)
*/
wl_list_init(&clients);
wl_list_init(&fstack);
+ wl_list_init(&stack);
xdg_shell = wlr_xdg_shell_create(dpy);
new_xdg_surface.notify = createnotify;
wl_signal_add(&xdg_shell->events.new_surface,
@@ -1220,6 +1238,7 @@ unmapnotify(struct wl_listener *listener, void *data)
int hadfocus = (c == selclient());
wl_list_remove(&c->link);
wl_list_remove(&c->flink);
+ wl_list_remove(&c->slink);
if (hadfocus)
refocus();
@@ -1241,9 +1260,9 @@ xytoclient(double x, double y,
struct wlr_surface **surface, double *sx, double *sy)
{
/* This iterates over all of our surfaces and attempts to find one under the
- * cursor. This relies on fstack being ordered from top-to-bottom. */
+ * cursor. This relies on stack being ordered from top-to-bottom. */
Client *c;
- wl_list_for_each(c, &fstack, flink) {
+ wl_list_for_each(c, &stack, slink) {
/* Skip clients that aren't visible */
if (!VISIBLEON(c, c->mon))
continue;