aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h6
-rw-r--r--dwl.c55
2 files changed, 54 insertions, 7 deletions
diff --git a/config.def.h b/config.def.h
index 9f8c2e3..b3a278b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,6 +7,12 @@ static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+static const Rule rules[] = {
+ /* app_id title tags mask isfloating monitor */
+ { "Gimp", NULL, 0, 1, -1 },
+ { "Firefox", NULL, 1 << 8, 0, -1 },
+};
+
/* layout(s) */
static const Layout layouts[] = {
/* symbol arrange function */
diff --git a/dwl.c b/dwl.c
index 9222a7c..0f40a33 100644
--- a/dwl.c
+++ b/dwl.c
@@ -115,6 +115,14 @@ typedef struct {
enum wl_output_transform rr;
} MonitorRule;
+typedef struct {
+ const char *id;
+ const char *title;
+ unsigned int tags;
+ int isfloating;
+ int monitor;
+} Rule;
+
/* Used to move all of the data necessary to render a surface from the top-level
* frame handler to the per-surface render function. */
struct render_data {
@@ -125,6 +133,7 @@ struct render_data {
/* function declarations */
static void applybounds(Client *c, struct wlr_box *bbox);
+static void applyrules(Client *c);
static void arrange(Monitor *m);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
@@ -180,6 +189,7 @@ static Client *xytoclient(double x, double y,
static Monitor *xytomon(double x, double y);
/* variables */
+static const char broken[] = "broken";
static struct wl_display *dpy;
static struct wlr_backend *backend;
static struct wlr_renderer *drw;
@@ -215,6 +225,7 @@ static Monitor *selmon;
/* configuration, allows nested code to access above variables */
#include "config.h"
+/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
{
@@ -233,6 +244,36 @@ applybounds(Client *c, struct wlr_box *bbox)
}
void
+applyrules(Client *c)
+{
+ const char *appid, *title;
+ unsigned int i, newtags = 0;
+ const Rule *r;
+ Monitor *mon = selmon, *m;
+
+ /* rule matching */
+ c->isfloating = 0;
+ if (!(appid = c->xdg_surface->toplevel->app_id))
+ appid = broken;
+ if (!(title = c->xdg_surface->toplevel->title))
+ title = broken;
+
+ for (r = rules; r < END(rules); r++) {
+ if ((!r->title || strstr(title, r->title))
+ && (!r->id || strstr(appid, r->id)))
+ {
+ c->isfloating = r->isfloating;
+ newtags |= r->tags;
+ i = 0;
+ wl_list_for_each(m, &mons, link)
+ if (r->monitor == i++)
+ mon = m;
+ }
+ }
+ setmon(c, mon, newtags);
+}
+
+void
arrange(Monitor *m)
{
/* Get effective monitor geometry to use for window area */
@@ -671,16 +712,16 @@ 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);
- /* XXX Apply client rules here */
- wlr_xdg_surface_get_geometry(c->xdg_surface, &c->geom);
- c->geom.width += 2 * c->bw;
- c->geom.height += 2 * c->bw;
- /* Insert this client into the list and put it on selmon. */
+ /* Insert this client into client lists. */
wl_list_insert(&clients, &c->link);
wl_list_insert(&fstack, &c->flink);
wl_list_insert(&stack, &c->slink);
- setmon(c, selmon);
- focusclient(c, c->xdg_surface->surface, 0);
+ wlr_xdg_surface_get_geometry(c->xdg_surface, &c->geom);
+ c->geom.width += 2 * c->bw;
+ c->geom.height += 2 * c->bw;
+
+ /* Set initial monitor, tags, floating status, and focus */
+ applyrules(c);
}
void