summaryrefslogtreecommitdiff
path: root/dwl.c
diff options
context:
space:
mode:
authorLeonardo Hernández Hernández <leohdz172@proton.me>2023-07-13 22:36:48 -0600
committerLeonardo Hernández Hernández <leohdz172@proton.me>2023-07-13 22:36:48 -0600
commitaecff8cb261a7189bee41a8cf1f6224a1a1f4ab1 (patch)
tree6d9dd18a64a26271a5a569afe225a4107c5773cc /dwl.c
parentff7c0e9508a380bb271886c2780e6f21679da1ee (diff)
parentca4a97b9335296c40f558baa1ead14578b166d70 (diff)
Merge branch 'main' into wlroots-next
Diffstat (limited to 'dwl.c')
-rw-r--r--dwl.c90
1 files changed, 36 insertions, 54 deletions
diff --git a/dwl.c b/dwl.c
index 7a2c323..11bc510 100644
--- a/dwl.c
+++ b/dwl.c
@@ -264,6 +264,7 @@ static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
+static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
static int keybinding(uint32_t mods, xkb_keysym_t sym);
@@ -287,7 +288,6 @@ static void pointerfocus(Client *c, struct wlr_surface *surface,
double sx, double sy, uint32_t time);
static void printstatus(void);
static void quit(const Arg *arg);
-static void quitsignal(int signo);
static void rendermon(struct wl_listener *listener, void *data);
static void requeststartdrag(struct wl_listener *listener, void *data);
static void requestmonstate(struct wl_listener *listener, void *data);
@@ -303,7 +303,6 @@ static void setmon(Client *c, Monitor *m, uint32_t newtags);
static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
-static void sigchld(int unused);
static void spawn(const Arg *arg);
static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg);
@@ -335,6 +334,7 @@ static struct wl_display *dpy;
static struct wlr_backend *backend;
static struct wlr_scene *scene;
static struct wlr_scene_tree *layers[NUM_LAYERS];
+static struct wlr_scene_tree *drag_icon;
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay };
static struct wlr_renderer *drw;
@@ -637,6 +637,7 @@ cleanup(void)
waitpid(child_pid, NULL, 0);
}
wlr_backend_destroy(backend);
+ wlr_scene_node_destroy(&scene->tree.node);
wlr_renderer_destroy(drw);
wlr_allocator_destroy(alloc);
wlr_xcursor_manager_destroy(cursor_mgr);
@@ -1312,6 +1313,27 @@ fullscreennotify(struct wl_listener *listener, void *data)
}
void
+handlesig(int signo)
+{
+ if (signo == SIGCHLD) {
+#ifdef XWAYLAND
+ siginfo_t in;
+ /* wlroots expects to reap the XWayland process itself, so we
+ * use WNOWAIT to keep the child waitable until we know it's not
+ * XWayland.
+ */
+ while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
+ && (!xwayland || in.si_pid != xwayland->server->pid))
+ waitpid(in.si_pid, NULL, 0);
+#else
+ while (waitpid(-1, NULL, WNOHANG) > 0);
+#endif
+ } else if (signo == SIGINT || signo == SIGTERM) {
+ quit(NULL);
+ }
+}
+
+void
incnmaster(const Arg *arg)
{
if (!arg || !selmon)
@@ -1607,7 +1629,6 @@ motionnotify(uint32_t time)
LayerSurface *l = NULL;
int type;
struct wlr_surface *surface = NULL;
- struct wlr_drag_icon *icon;
/* time is 0 in internal calls meant to restore pointer focus. */
if (time) {
@@ -1618,10 +1639,9 @@ motionnotify(uint32_t time)
selmon = xytomon(cursor->x, cursor->y);
}
- /* Update drag icon's position if any */
- if (seat->drag && (icon = seat->drag->icon))
- wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->current.dx,
- cursor->y + icon->surface->current.dy);
+ /* Update drag icon's position */
+ wlr_scene_node_set_position(&drag_icon->node, cursor->x, cursor->y);
+
/* If we are currently grabbing the mouse, handle and return */
if (cursor_mode == CurMove) {
/* Move the grabbed client to the new position. */
@@ -1846,12 +1866,6 @@ quit(const Arg *arg)
}
void
-quitsignal(int signo)
-{
- quit(NULL);
-}
-
-void
rendermon(struct wl_listener *listener, void *data)
{
/* This function is called every time an output is ready to display a frame,
@@ -1922,8 +1936,6 @@ run(char *startup_cmd)
{
/* Add a Unix socket to the Wayland display. */
const char *socket = wl_display_add_socket_auto(dpy);
- struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = SIG_IGN};
- sigemptyset(&sa.sa_mask);
if (!socket)
die("startup: display_add_socket_auto");
setenv("WAYLAND_DISPLAY", socket, 1);
@@ -1951,8 +1963,6 @@ run(char *startup_cmd)
close(piperw[1]);
close(piperw[0]);
}
- /* If nobody is reading the status output, don't terminate */
- sigaction(SIGPIPE, &sa, NULL);
printstatus();
/* At this point the outputs are initialized, choose initial selmon based on
@@ -2125,16 +2135,12 @@ setsel(struct wl_listener *listener, void *data)
void
setup(void)
{
- int layer;
-
- /* Set up signal handlers */
- struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = sigchld};
+ int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
+ struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
sigemptyset(&sa.sa_mask);
- sigaction(SIGCHLD, &sa, NULL);
- sa.sa_handler = quitsignal;
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
+ for (i = 0; i < LENGTH(sig); i++)
+ sigaction(sig[i], &sa, NULL);
/* The Wayland display is managed by libwayland. It handles accepting
* clients from the Unix socket, manging Wayland globals, and so on. */
@@ -2153,8 +2159,10 @@ setup(void)
/* Initialize the scene graph used to lay out windows */
scene = wlr_scene_create();
- for (layer = 0; layer < NUM_LAYERS; layer++)
- layers[layer] = wlr_scene_tree_create(&scene->tree);
+ for (i = 0; i < NUM_LAYERS; i++)
+ layers[i] = wlr_scene_tree_create(&scene->tree);
+ drag_icon = wlr_scene_tree_create(&scene->tree);
+ wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node);
/* Create a renderer with the default implementation */
if (!(drw = wlr_renderer_autocreate(backend)))
@@ -2319,28 +2327,6 @@ setup(void)
}
void
-sigchld(int unused)
-{
-#ifdef XWAYLAND
- siginfo_t in;
- /* We should be able to remove this function in favor of a simple
- * struct sigaction sa = {.sa_handler = SIG_IGN};
- * sigaction(SIGCHLD, &sa, NULL);
- * but the Xwayland implementation in wlroots currently prevents us from
- * setting our own disposition for SIGCHLD.
- */
- /* WNOWAIT leaves the child in a waitable state, in case this is the
- * XWayland process
- */
- while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
- && (!xwayland || in.si_pid != xwayland->server->pid))
- waitpid(in.si_pid, NULL, 0);
-#else
- while (waitpid(-1, NULL, WNOHANG) > 0);
-#endif
-}
-
-void
spawn(const Arg *arg)
{
if (fork() == 0) {
@@ -2355,14 +2341,10 @@ void
startdrag(struct wl_listener *listener, void *data)
{
struct wlr_drag *drag = data;
- struct wlr_scene_tree *icon;
-
if (!drag->icon)
return;
- icon = drag->icon->data = wlr_scene_drag_icon_create(&scene->tree, drag->icon);
- wlr_scene_node_place_below(&icon->node, &layers[LyrBlock]->node);
- motionnotify(0);
+ drag->icon->data = &wlr_scene_drag_icon_create(drag_icon, drag->icon)->node;
LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon);
}