aboutsummaryrefslogtreecommitdiff
path: root/client.h
diff options
context:
space:
mode:
authorDevin J. Pohly <djpohly@gmail.com>2020-12-25 01:33:55 -0500
committerDevin J. Pohly <djpohly@gmail.com>2020-12-25 01:39:07 -0500
commit388c5580cbb032c9e5c3a9b2b578f0e0e27fc97b (patch)
treecfcf6be715a3525dc1042f64c3561adf0fc9ef01 /client.h
parentbac3221a038d8f0b49f28a4046a89e58646e8622 (diff)
consolidate some of the ugliness into a separate file
Similar to Linux kernel approach, encapsulate some of the uglier conditional compilation into inline functions in header files. The goal is to make dwl.c more attractive to people who embrace the suckless philosophy - simple, short, hackable, and easy to understand. We want dwm users to feel comfortable here, not scare them off. Plus, if we do this right, the main dwl.c code should require only minimal changes once XWayland is no longer a necessary evil. According to `cloc`, this also brings dwl.c down below 2000 lines of non-blank, non-comment code.
Diffstat (limited to 'client.h')
-rw-r--r--client.h163
1 files changed, 163 insertions, 0 deletions
diff --git a/client.h b/client.h
new file mode 100644
index 0000000..f4735c2
--- /dev/null
+++ b/client.h
@@ -0,0 +1,163 @@
+/*
+ * Attempt to consolidate unavoidable suck into one file, away from dwl.c. This
+ * file is not meant to be pretty. We use a .h file with static inline
+ * functions instead of a separate .c module, or function pointers like sway, so
+ * that they will simply compile out if the chosen #defines leave them unused.
+ */
+
+/* Leave this function first; it's used in the others */
+static inline int
+client_is_x11(Client *c)
+{
+#ifdef XWAYLAND
+ return c->type == X11Managed || c->type == X11Unmanaged;
+#else
+ return 0;
+#endif
+}
+
+/* The others */
+static inline void
+client_activate_surface(struct wlr_surface *s, int activated)
+{
+#ifdef XWAYLAND
+ if (wlr_surface_is_xwayland_surface(s)) {
+ wlr_xwayland_surface_activate(
+ wlr_xwayland_surface_from_wlr_surface(s), activated);
+ return;
+ }
+#endif
+ if (wlr_surface_is_xdg_surface(s))
+ wlr_xdg_toplevel_set_activated(
+ wlr_xdg_surface_from_wlr_surface(s), activated);
+}
+
+static inline void
+client_for_each_surface(Client *c, wlr_surface_iterator_func_t fn, void *data)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c)) {
+ wlr_surface_for_each_surface(c->surface.xwayland->surface,
+ fn, data);
+ return;
+ }
+#endif
+ wlr_xdg_surface_for_each_surface(c->surface.xdg, fn, data);
+}
+
+static inline const char *
+client_get_appid(Client *c)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c))
+ return c->surface.xwayland->class;
+#endif
+ return c->surface.xdg->toplevel->app_id;
+}
+
+static inline void
+client_get_geometry(Client *c, struct wlr_box *geom)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c)) {
+ geom->x = c->surface.xwayland->x;
+ geom->y = c->surface.xwayland->y;
+ geom->width = c->surface.xwayland->width;
+ geom->height = c->surface.xwayland->height;
+ return;
+ }
+#endif
+ wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
+}
+
+static inline const char *
+client_get_title(Client *c)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c))
+ return c->surface.xwayland->title;
+#endif
+ return c->surface.xdg->toplevel->title;
+}
+
+static inline int
+client_is_float_type(Client *c)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c))
+ for (size_t i = 0; i < c->surface.xwayland->window_type_len; i++)
+ if (c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeDialog] ||
+ c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeSplash] ||
+ c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeToolbar] ||
+ c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeUtility])
+ return 1;
+#endif
+ return 0;
+}
+
+static inline int
+client_is_unmanaged(Client *c)
+{
+#ifdef XWAYLAND
+ return c->type == X11Unmanaged;
+#endif
+ return 0;
+}
+
+static inline void
+client_send_close(Client *c)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c)) {
+ wlr_xwayland_surface_close(c->surface.xwayland);
+ return;
+ }
+#endif
+ wlr_xdg_toplevel_send_close(c->surface.xdg);
+}
+
+static inline void
+client_set_fullscreen(Client *c, int fullscreen)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c)) {
+ wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen);
+ return;
+ }
+#endif
+ wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen);
+}
+
+static inline uint32_t
+client_set_size(Client *c, uint32_t width, uint32_t height)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c)) {
+ wlr_xwayland_surface_configure(c->surface.xwayland,
+ c->geom.x, c->geom.y, width, height);
+ return 0;
+ }
+#endif
+ return wlr_xdg_toplevel_set_size(c->surface.xdg, width, height);
+}
+
+static inline struct wlr_surface *
+client_surface(Client *c)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c))
+ return c->surface.xwayland->surface;
+#endif
+ return c->surface.xdg->surface;
+}
+
+static inline struct wlr_surface *
+client_surface_at(Client *c, double cx, double cy, double *sx, double *sy)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c))
+ return wlr_surface_surface_at(c->surface.xwayland->surface,
+ cx, cy, sx, sy);
+#endif
+ return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy);
+}