mirror of
				https://codeberg.org/dwl/dwl.git
				synced 2025-11-03 09:01:45 -05:00 
			
		
		
		
	Merge branch 'master' into 31-independents-mouse-focus
This commit is contained in:
		
						commit
						4788baee8d
					
				
					 3 changed files with 224 additions and 156 deletions
				
			
		
							
								
								
									
										7
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -1,9 +1,10 @@
 | 
				
			||||||
 | 
					include config.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99 -Werror=declaration-after-statement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
 | 
					WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
 | 
				
			||||||
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
 | 
					WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-error=unused-function
 | 
					 | 
				
			||||||
CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99 -Werror=declaration-after-statement
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PKGS = wlroots wayland-server xcb xkbcommon
 | 
					PKGS = wlroots wayland-server xcb xkbcommon
 | 
				
			||||||
CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p)))
 | 
					CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p)))
 | 
				
			||||||
LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
 | 
					LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								config.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								config.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					# Default compile flags (overridable by environment)
 | 
				
			||||||
 | 
					CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-error=unused-function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Uncomment to build XWayland support
 | 
				
			||||||
 | 
					#CFLAGS += -DXWAYLAND
 | 
				
			||||||
							
								
								
									
										368
									
								
								dwl.c
									
										
									
									
									
								
							
							
						
						
									
										368
									
								
								dwl.c
									
										
									
									
									
								
							| 
						 | 
					@ -33,9 +33,11 @@
 | 
				
			||||||
#include <wlr/types/wlr_xdg_output_v1.h>
 | 
					#include <wlr/types/wlr_xdg_output_v1.h>
 | 
				
			||||||
#include <wlr/types/wlr_xdg_shell.h>
 | 
					#include <wlr/types/wlr_xdg_shell.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
#include <wlr/xwayland.h>
 | 
					 | 
				
			||||||
#include <X11/Xlib.h>
 | 
					 | 
				
			||||||
#include <xkbcommon/xkbcommon.h>
 | 
					#include <xkbcommon/xkbcommon.h>
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
 | 
					#include <X11/Xlib.h>
 | 
				
			||||||
 | 
					#include <wlr/xwayland.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* macros */
 | 
					/* macros */
 | 
				
			||||||
#define MAX(A, B)               ((A) > (B) ? (A) : (B))
 | 
					#define MAX(A, B)               ((A) > (B) ? (A) : (B))
 | 
				
			||||||
| 
						 | 
					@ -45,13 +47,19 @@
 | 
				
			||||||
#define LENGTH(X)               (sizeof X / sizeof X[0])
 | 
					#define LENGTH(X)               (sizeof X / sizeof X[0])
 | 
				
			||||||
#define END(A)                  ((A) + LENGTH(A))
 | 
					#define END(A)                  ((A) + LENGTH(A))
 | 
				
			||||||
#define TAGMASK                 ((1 << LENGTH(tags)) - 1)
 | 
					#define TAGMASK                 ((1 << LENGTH(tags)) - 1)
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
#define WLR_SURFACE(C)          ((C)->type != XDGShell ? (C)->surface.xwayland->surface : (C)->surface.xdg->surface)
 | 
					#define WLR_SURFACE(C)          ((C)->type != XDGShell ? (C)->surface.xwayland->surface : (C)->surface.xdg->surface)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define WLR_SURFACE(C)          ((C)->surface.xdg->surface)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* enums */
 | 
					/* enums */
 | 
				
			||||||
enum { CurNormal, CurMove, CurResize }; /* cursor */
 | 
					enum { CurNormal, CurMove, CurResize }; /* cursor */
 | 
				
			||||||
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
 | 
					enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
 | 
				
			||||||
	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
 | 
						NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
enum { XDGShell, X11Managed, X11Unmanaged }; /* client types */
 | 
					enum { XDGShell, X11Managed, X11Unmanaged }; /* client types */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef union {
 | 
					typedef union {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -74,16 +82,22 @@ typedef struct {
 | 
				
			||||||
	struct wl_list slink;
 | 
						struct wl_list slink;
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		struct wlr_xdg_surface *xdg;
 | 
							struct wlr_xdg_surface *xdg;
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		struct wlr_xwayland_surface *xwayland;
 | 
							struct wlr_xwayland_surface *xwayland;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	} surface;
 | 
						} surface;
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	struct wl_listener activate;
 | 
						struct wl_listener activate;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	struct wl_listener commit;
 | 
						struct wl_listener commit;
 | 
				
			||||||
	struct wl_listener map;
 | 
						struct wl_listener map;
 | 
				
			||||||
	struct wl_listener unmap;
 | 
						struct wl_listener unmap;
 | 
				
			||||||
	struct wl_listener destroy;
 | 
						struct wl_listener destroy;
 | 
				
			||||||
	struct wlr_box geom;  /* layout-relative, includes border */
 | 
						struct wlr_box geom;  /* layout-relative, includes border */
 | 
				
			||||||
	Monitor *mon;
 | 
						Monitor *mon;
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	unsigned int type;
 | 
						unsigned int type;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	int bw;
 | 
						int bw;
 | 
				
			||||||
	unsigned int tags;
 | 
						unsigned int tags;
 | 
				
			||||||
	int isfloating;
 | 
						int isfloating;
 | 
				
			||||||
| 
						 | 
					@ -157,7 +171,6 @@ struct render_data {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* function declarations */
 | 
					/* function declarations */
 | 
				
			||||||
static void activatex11(struct wl_listener *listener, void *data);
 | 
					 | 
				
			||||||
static void applybounds(Client *c, struct wlr_box *bbox);
 | 
					static void applybounds(Client *c, struct wlr_box *bbox);
 | 
				
			||||||
static void applyrules(Client *c);
 | 
					static void applyrules(Client *c);
 | 
				
			||||||
static void arrange(Monitor *m);
 | 
					static void arrange(Monitor *m);
 | 
				
			||||||
| 
						 | 
					@ -169,7 +182,6 @@ static void cleanupmon(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void createkeyboard(struct wlr_input_device *device);
 | 
					static void createkeyboard(struct wlr_input_device *device);
 | 
				
			||||||
static void createmon(struct wl_listener *listener, void *data);
 | 
					static void createmon(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void createnotify(struct wl_listener *listener, void *data);
 | 
					static void createnotify(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void createnotifyx11(struct wl_listener *listener, void *data);
 | 
					 | 
				
			||||||
static void createpointer(struct wlr_input_device *device);
 | 
					static void createpointer(struct wlr_input_device *device);
 | 
				
			||||||
static void createxdeco(struct wl_listener *listener, void *data);
 | 
					static void createxdeco(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void cursorframe(struct wl_listener *listener, void *data);
 | 
					static void cursorframe(struct wl_listener *listener, void *data);
 | 
				
			||||||
| 
						 | 
					@ -180,7 +192,6 @@ static void focusclient(Client *old, Client *c, int lift);
 | 
				
			||||||
static void focusmon(const Arg *arg);
 | 
					static void focusmon(const Arg *arg);
 | 
				
			||||||
static void focusstack(const Arg *arg);
 | 
					static void focusstack(const Arg *arg);
 | 
				
			||||||
static Client *focustop(Monitor *m);
 | 
					static Client *focustop(Monitor *m);
 | 
				
			||||||
static Atom getatom(xcb_connection_t *xc, const char *name);
 | 
					 | 
				
			||||||
static void getxdecomode(struct wl_listener *listener, void *data);
 | 
					static void getxdecomode(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void incnmaster(const Arg *arg);
 | 
					static void incnmaster(const Arg *arg);
 | 
				
			||||||
static void inputdevice(struct wl_listener *listener, void *data);
 | 
					static void inputdevice(struct wl_listener *listener, void *data);
 | 
				
			||||||
| 
						 | 
					@ -219,12 +230,9 @@ static void tile(Monitor *m);
 | 
				
			||||||
static void togglefloating(const Arg *arg);
 | 
					static void togglefloating(const Arg *arg);
 | 
				
			||||||
static void toggletag(const Arg *arg);
 | 
					static void toggletag(const Arg *arg);
 | 
				
			||||||
static void toggleview(const Arg *arg);
 | 
					static void toggleview(const Arg *arg);
 | 
				
			||||||
static void updatewindowtype(Client *c);
 | 
					 | 
				
			||||||
static void unmapnotify(struct wl_listener *listener, void *data);
 | 
					static void unmapnotify(struct wl_listener *listener, void *data);
 | 
				
			||||||
static void xwaylandready(struct wl_listener *listener, void *data);
 | 
					 | 
				
			||||||
static void view(const Arg *arg);
 | 
					static void view(const Arg *arg);
 | 
				
			||||||
static Client *xytoclient(double x, double y);
 | 
					static Client *xytoclient(double x, double y);
 | 
				
			||||||
static Client *xytoindependent(double x, double y);
 | 
					 | 
				
			||||||
static Monitor *xytomon(double x, double y);
 | 
					static Monitor *xytomon(double x, double y);
 | 
				
			||||||
static void zoom(const Arg *arg);
 | 
					static void zoom(const Arg *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -234,7 +242,6 @@ static struct wl_display *dpy;
 | 
				
			||||||
static struct wlr_backend *backend;
 | 
					static struct wlr_backend *backend;
 | 
				
			||||||
static struct wlr_renderer *drw;
 | 
					static struct wlr_renderer *drw;
 | 
				
			||||||
static struct wlr_compositor *compositor;
 | 
					static struct wlr_compositor *compositor;
 | 
				
			||||||
static struct wlr_xwayland *xwayland;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_xdg_shell *xdg_shell;
 | 
					static struct wlr_xdg_shell *xdg_shell;
 | 
				
			||||||
static struct wl_list clients; /* tiling order */
 | 
					static struct wl_list clients; /* tiling order */
 | 
				
			||||||
| 
						 | 
					@ -257,8 +264,6 @@ static struct wlr_box sgeom;
 | 
				
			||||||
static struct wl_list mons;
 | 
					static struct wl_list mons;
 | 
				
			||||||
static Monitor *selmon;
 | 
					static Monitor *selmon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Atom netatom[NetLast];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* global event handlers */
 | 
					/* global event handlers */
 | 
				
			||||||
static struct wl_listener cursor_axis = {.notify = axisnotify};
 | 
					static struct wl_listener cursor_axis = {.notify = axisnotify};
 | 
				
			||||||
static struct wl_listener cursor_button = {.notify = buttonpress};
 | 
					static struct wl_listener cursor_button = {.notify = buttonpress};
 | 
				
			||||||
| 
						 | 
					@ -269,11 +274,23 @@ static struct wl_listener new_input = {.notify = inputdevice};
 | 
				
			||||||
static struct wl_listener new_output = {.notify = createmon};
 | 
					static struct wl_listener new_output = {.notify = createmon};
 | 
				
			||||||
static struct wl_listener new_xdeco = {.notify = createxdeco};
 | 
					static struct wl_listener new_xdeco = {.notify = createxdeco};
 | 
				
			||||||
static struct wl_listener new_xdg_surface = {.notify = createnotify};
 | 
					static struct wl_listener new_xdg_surface = {.notify = createnotify};
 | 
				
			||||||
static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};
 | 
					 | 
				
			||||||
static struct wl_listener request_cursor = {.notify = setcursor};
 | 
					static struct wl_listener request_cursor = {.notify = setcursor};
 | 
				
			||||||
static struct wl_listener request_set_psel = {.notify = setpsel};
 | 
					static struct wl_listener request_set_psel = {.notify = setpsel};
 | 
				
			||||||
static struct wl_listener request_set_sel = {.notify = setsel};
 | 
					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 Atom getatom(xcb_connection_t *xc, const char *name);
 | 
				
			||||||
 | 
					static void renderindependents(struct wlr_output *output, struct timespec *now);
 | 
				
			||||||
 | 
					static void updatewindowtype(Client *c);
 | 
				
			||||||
 | 
					static void xwaylandready(struct wl_listener *listener, void *data);
 | 
				
			||||||
 | 
					static Client *xytoindependent(double x, double y);
 | 
				
			||||||
 | 
					static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};
 | 
				
			||||||
static struct wl_listener xwayland_ready = {.notify = xwaylandready};
 | 
					static struct wl_listener xwayland_ready = {.notify = xwaylandready};
 | 
				
			||||||
 | 
					static struct wlr_xwayland *xwayland;
 | 
				
			||||||
 | 
					static Atom netatom[NetLast];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* configuration, allows nested code to access above variables */
 | 
					/* configuration, allows nested code to access above variables */
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
| 
						 | 
					@ -282,16 +299,6 @@ static struct wl_listener xwayland_ready = {.notify = xwaylandready};
 | 
				
			||||||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
 | 
					struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* function implementations */
 | 
					/* function implementations */
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
activatex11(struct wl_listener *listener, void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
       Client *c = wl_container_of(listener, c, activate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       /* Only "managed" windows can be activated */
 | 
					 | 
				
			||||||
       if (c->type == X11Managed)
 | 
					 | 
				
			||||||
               wlr_xwayland_surface_activate(c->surface.xwayland, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
applybounds(Client *c, struct wlr_box *bbox)
 | 
					applybounds(Client *c, struct wlr_box *bbox)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -319,10 +326,17 @@ applyrules(Client *c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* rule matching */
 | 
						/* rule matching */
 | 
				
			||||||
	c->isfloating = 0;
 | 
						c->isfloating = 0;
 | 
				
			||||||
	appid = c->type != XDGShell ? c->surface.xwayland->class :
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		c->surface.xdg->toplevel->app_id;
 | 
						updatewindowtype(c);
 | 
				
			||||||
	title = c->type != XDGShell ? c->surface.xwayland->title :
 | 
						if (c->type != XDGShell) {
 | 
				
			||||||
		c->surface.xdg->toplevel->title;
 | 
							appid = c->surface.xwayland->class;
 | 
				
			||||||
 | 
							title = c->surface.xwayland->title;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							appid = c->surface.xdg->toplevel->app_id;
 | 
				
			||||||
 | 
							title = c->surface.xdg->toplevel->title;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (!appid)
 | 
						if (!appid)
 | 
				
			||||||
		appid = broken;
 | 
							appid = broken;
 | 
				
			||||||
	if (!title)
 | 
						if (!title)
 | 
				
			||||||
| 
						 | 
					@ -339,7 +353,6 @@ applyrules(Client *c)
 | 
				
			||||||
					mon = m;
 | 
										mon = m;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	updatewindowtype(c);
 | 
					 | 
				
			||||||
	setmon(c, mon, newtags);
 | 
						setmon(c, mon, newtags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -553,7 +566,6 @@ createnotify(struct wl_listener *listener, void *data)
 | 
				
			||||||
	/* Allocate a Client for this surface */
 | 
						/* Allocate a Client for this surface */
 | 
				
			||||||
	c = xdg_surface->data = calloc(1, sizeof(*c));
 | 
						c = xdg_surface->data = calloc(1, sizeof(*c));
 | 
				
			||||||
	c->surface.xdg = xdg_surface;
 | 
						c->surface.xdg = xdg_surface;
 | 
				
			||||||
	c->type = XDGShell;
 | 
					 | 
				
			||||||
	c->bw = borderpx;
 | 
						c->bw = borderpx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Tell the client not to try anything fancy */
 | 
						/* Tell the client not to try anything fancy */
 | 
				
			||||||
| 
						 | 
					@ -571,29 +583,6 @@ createnotify(struct wl_listener *listener, void *data)
 | 
				
			||||||
	wl_signal_add(&xdg_surface->events.destroy, &c->destroy);
 | 
						wl_signal_add(&xdg_surface->events.destroy, &c->destroy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
createnotifyx11(struct wl_listener *listener, void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct wlr_xwayland_surface *xwayland_surface = data;
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* 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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Listen to the various events it can emit */
 | 
					 | 
				
			||||||
	c->map.notify = maprequest;
 | 
					 | 
				
			||||||
	wl_signal_add(&xwayland_surface->events.map, &c->map);
 | 
					 | 
				
			||||||
	c->unmap.notify = unmapnotify;
 | 
					 | 
				
			||||||
	wl_signal_add(&xwayland_surface->events.unmap, &c->unmap);
 | 
					 | 
				
			||||||
	c->activate.notify = activatex11;
 | 
					 | 
				
			||||||
	wl_signal_add(&xwayland_surface->events.request_activate, &c->activate);
 | 
					 | 
				
			||||||
	c->destroy.notify = destroynotify;
 | 
					 | 
				
			||||||
	wl_signal_add(&xwayland_surface->events.destroy, &c->destroy);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
createpointer(struct wlr_input_device *device)
 | 
					createpointer(struct wlr_input_device *device)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -638,10 +627,12 @@ destroynotify(struct wl_listener *listener, void *data)
 | 
				
			||||||
	wl_list_remove(&c->map.link);
 | 
						wl_list_remove(&c->map.link);
 | 
				
			||||||
	wl_list_remove(&c->unmap.link);
 | 
						wl_list_remove(&c->unmap.link);
 | 
				
			||||||
	wl_list_remove(&c->destroy.link);
 | 
						wl_list_remove(&c->destroy.link);
 | 
				
			||||||
	if (c->type == XDGShell)
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		wl_list_remove(&c->commit.link);
 | 
					 | 
				
			||||||
	if (c->type == X11Managed)
 | 
						if (c->type == X11Managed)
 | 
				
			||||||
		wl_list_remove(&c->activate.link);
 | 
							wl_list_remove(&c->activate.link);
 | 
				
			||||||
 | 
						else if (c->type == XDGShell)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							wl_list_remove(&c->commit.link);
 | 
				
			||||||
	free(c);
 | 
						free(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -689,9 +680,11 @@ focusclient(Client *old, Client *c, int lift)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Deactivate old client if focus is changing */
 | 
						/* Deactivate old client if focus is changing */
 | 
				
			||||||
	if (c != old && old) {
 | 
						if (c != old && old) {
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		if (old->type != XDGShell)
 | 
							if (old->type != XDGShell)
 | 
				
			||||||
			wlr_xwayland_surface_activate(old->surface.xwayland, 0);
 | 
								wlr_xwayland_surface_activate(old->surface.xwayland, 0);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			wlr_xdg_toplevel_set_activated(old->surface.xdg, 0);
 | 
								wlr_xdg_toplevel_set_activated(old->surface.xdg, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -712,9 +705,11 @@ focusclient(Client *old, Client *c, int lift)
 | 
				
			||||||
	selmon = c->mon;
 | 
						selmon = c->mon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Activate the new client */
 | 
						/* Activate the new client */
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	if (c->type != XDGShell)
 | 
						if (c->type != XDGShell)
 | 
				
			||||||
		wlr_xwayland_surface_activate(c->surface.xwayland, 1);
 | 
							wlr_xwayland_surface_activate(c->surface.xwayland, 1);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		wlr_xdg_toplevel_set_activated(c->surface.xdg, 1);
 | 
							wlr_xdg_toplevel_set_activated(c->surface.xdg, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -763,21 +758,6 @@ focustop(Monitor *m)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Atom
 | 
					 | 
				
			||||||
getatom(xcb_connection_t *xc, const char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Atom atom = 0;
 | 
					 | 
				
			||||||
	xcb_intern_atom_cookie_t cookie;
 | 
					 | 
				
			||||||
	xcb_intern_atom_reply_t *reply;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cookie = xcb_intern_atom(xc, 0, strlen(name), name);
 | 
					 | 
				
			||||||
	if ((reply = xcb_intern_atom_reply(xc, cookie, NULL)))
 | 
					 | 
				
			||||||
		atom = reply->atom;
 | 
					 | 
				
			||||||
	free(reply);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return atom;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
getxdecomode(struct wl_listener *listener, void *data)
 | 
					getxdecomode(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -896,9 +876,11 @@ killclient(const Arg *arg)
 | 
				
			||||||
	if (!sel)
 | 
						if (!sel)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	if (sel->type != XDGShell)
 | 
						if (sel->type != XDGShell)
 | 
				
			||||||
		wlr_xwayland_surface_close(sel->surface.xwayland);
 | 
							wlr_xwayland_surface_close(sel->surface.xwayland);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		wlr_xdg_toplevel_send_close(sel->surface.xdg);
 | 
							wlr_xdg_toplevel_send_close(sel->surface.xdg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -908,23 +890,28 @@ maprequest(struct wl_listener *listener, void *data)
 | 
				
			||||||
	/* Called when the surface is mapped, or ready to display on-screen. */
 | 
						/* 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	if (c->type == X11Unmanaged) {
 | 
						if (c->type == X11Unmanaged) {
 | 
				
			||||||
		/* Insert this independent into independents lists. */
 | 
							/* Insert this independent into independents lists. */
 | 
				
			||||||
		wl_list_insert(&independents, &c->link);
 | 
							wl_list_insert(&independents, &c->link);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Insert this client into client lists. */
 | 
						/* Insert this client into client lists. */
 | 
				
			||||||
	wl_list_insert(&clients, &c->link);
 | 
						wl_list_insert(&clients, &c->link);
 | 
				
			||||||
	wl_list_insert(&fstack, &c->flink);
 | 
						wl_list_insert(&fstack, &c->flink);
 | 
				
			||||||
	wl_list_insert(&stack, &c->slink);
 | 
						wl_list_insert(&stack, &c->slink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	if (c->type != XDGShell) {
 | 
						if (c->type != XDGShell) {
 | 
				
			||||||
		c->geom.x = c->surface.xwayland->x;
 | 
							c->geom.x = c->surface.xwayland->x;
 | 
				
			||||||
		c->geom.y = c->surface.xwayland->y;
 | 
							c->geom.y = c->surface.xwayland->y;
 | 
				
			||||||
		c->geom.width = c->surface.xwayland->width + 2 * c->bw;
 | 
							c->geom.width = c->surface.xwayland->width + 2 * c->bw;
 | 
				
			||||||
		c->geom.height = c->surface.xwayland->height + 2 * c->bw;
 | 
							c->geom.height = c->surface.xwayland->height + 2 * c->bw;
 | 
				
			||||||
	} else {
 | 
						} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		wlr_xdg_surface_get_geometry(c->surface.xdg, &c->geom);
 | 
							wlr_xdg_surface_get_geometry(c->surface.xdg, &c->geom);
 | 
				
			||||||
		c->geom.width += 2 * c->bw;
 | 
							c->geom.width += 2 * c->bw;
 | 
				
			||||||
		c->geom.height += 2 * c->bw;
 | 
							c->geom.height += 2 * c->bw;
 | 
				
			||||||
| 
						 | 
					@ -984,6 +971,7 @@ motionnotify(uint32_t time)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	/* Find an independent under the pointer and send the event along. */
 | 
						/* Find an independent under the pointer and send the event along. */
 | 
				
			||||||
	if ((c = xytoindependent(cursor->x, cursor->y))) {
 | 
						if ((c = xytoindependent(cursor->x, cursor->y))) {
 | 
				
			||||||
		surface = wlr_surface_surface_at(c->surface.xwayland->surface,
 | 
							surface = wlr_surface_surface_at(c->surface.xwayland->surface,
 | 
				
			||||||
| 
						 | 
					@ -992,11 +980,16 @@ motionnotify(uint32_t time)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Otherwise, find the client under the pointer and send the event along. */
 | 
						/* Otherwise, find the client under the pointer and send the event along. */
 | 
				
			||||||
	} else if ((c = xytoclient(cursor->x, cursor->y))) {
 | 
						} else if ((c = xytoclient(cursor->x, cursor->y))) {
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if ((c = xytoclient(cursor->x, cursor->y))) {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		if (c->type != XDGShell)
 | 
							if (c->type != XDGShell)
 | 
				
			||||||
			surface = wlr_surface_surface_at(c->surface.xwayland->surface,
 | 
								surface = wlr_surface_surface_at(c->surface.xwayland->surface,
 | 
				
			||||||
					cursor->x - c->geom.x - c->bw,
 | 
										cursor->x - c->geom.x - c->bw,
 | 
				
			||||||
					cursor->y - c->geom.y - c->bw, &sx, &sy);
 | 
										cursor->y - c->geom.y - c->bw, &sx, &sy);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			surface = wlr_xdg_surface_surface_at(c->surface.xdg,
 | 
								surface = wlr_xdg_surface_surface_at(c->surface.xdg,
 | 
				
			||||||
					cursor->x - c->geom.x - c->bw,
 | 
										cursor->x - c->geom.x - c->bw,
 | 
				
			||||||
					cursor->y - c->geom.y - c->bw, &sx, &sy);
 | 
										cursor->y - c->geom.y - c->bw, &sx, &sy);
 | 
				
			||||||
| 
						 | 
					@ -1077,7 +1070,13 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
 | 
				
			||||||
	/* Otherwise, let the client know that the mouse cursor has entered one
 | 
						/* Otherwise, let the client know that the mouse cursor has entered one
 | 
				
			||||||
	 * of its surfaces, and make keyboard focus follow if desired. */
 | 
						 * of its surfaces, and make keyboard focus follow if desired. */
 | 
				
			||||||
	wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
 | 
						wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
 | 
				
			||||||
	if (sloppyfocus && c->type != X11Unmanaged)
 | 
					
 | 
				
			||||||
 | 
					#if XWAYLAND
 | 
				
			||||||
 | 
						if (c->type == X11Unmanaged)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sloppyfocus)
 | 
				
			||||||
		focusclient(selclient(), c, 0);
 | 
							focusclient(selclient(), c, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1190,39 +1189,15 @@ renderclients(Monitor *m, struct timespec *now)
 | 
				
			||||||
		rdata.when = now;
 | 
							rdata.when = now;
 | 
				
			||||||
		rdata.x = c->geom.x + c->bw;
 | 
							rdata.x = c->geom.x + c->bw;
 | 
				
			||||||
		rdata.y = c->geom.y + c->bw;
 | 
							rdata.y = c->geom.y + c->bw;
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		if (c->type != XDGShell)
 | 
							if (c->type != XDGShell)
 | 
				
			||||||
			wlr_surface_for_each_surface(c->surface.xwayland->surface, render, &rdata);
 | 
								wlr_surface_for_each_surface(c->surface.xwayland->surface, render, &rdata);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			wlr_xdg_surface_for_each_surface(c->surface.xdg, render, &rdata);
 | 
								wlr_xdg_surface_for_each_surface(c->surface.xdg, render, &rdata);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
renderindependents(struct wlr_output *output, struct timespec *now)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
	struct render_data rdata;
 | 
					 | 
				
			||||||
	struct wlr_box geom;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_list_for_each_reverse(c, &independents, link) {
 | 
					 | 
				
			||||||
		geom.x = c->surface.xwayland->x;
 | 
					 | 
				
			||||||
		geom.y = c->surface.xwayland->y;
 | 
					 | 
				
			||||||
		geom.width = c->surface.xwayland->width;
 | 
					 | 
				
			||||||
		geom.height = c->surface.xwayland->height;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Only render visible clients which show on this output */
 | 
					 | 
				
			||||||
		if (!wlr_output_layout_intersects(output_layout, output, &geom))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rdata.output = output;
 | 
					 | 
				
			||||||
		rdata.when = now;
 | 
					 | 
				
			||||||
		rdata.x = c->surface.xwayland->x;
 | 
					 | 
				
			||||||
		rdata.y = c->surface.xwayland->y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		wlr_surface_for_each_surface(c->surface.xwayland->surface, render, &rdata);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
rendermon(struct wl_listener *listener, void *data)
 | 
					rendermon(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1254,7 +1229,9 @@ rendermon(struct wl_listener *listener, void *data)
 | 
				
			||||||
		wlr_renderer_clear(drw, rootcolor);
 | 
							wlr_renderer_clear(drw, rootcolor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		renderclients(m, &now);
 | 
							renderclients(m, &now);
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
		renderindependents(m->wlr_output, &now);
 | 
							renderindependents(m->wlr_output, &now);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Hardware cursors are rendered by the GPU on a separate plane, and can be
 | 
							/* Hardware cursors are rendered by the GPU on a separate plane, and can be
 | 
				
			||||||
		 * moved around without re-rendering what's beneath them - which is more
 | 
							 * moved around without re-rendering what's beneath them - which is more
 | 
				
			||||||
| 
						 | 
					@ -1287,11 +1264,13 @@ resize(Client *c, int x, int y, int w, int h, int interact)
 | 
				
			||||||
	c->geom.height = h;
 | 
						c->geom.height = h;
 | 
				
			||||||
	applybounds(c, bbox);
 | 
						applybounds(c, bbox);
 | 
				
			||||||
	/* wlroots makes this a no-op if size hasn't changed */
 | 
						/* wlroots makes this a no-op if size hasn't changed */
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	if (c->type != XDGShell)
 | 
						if (c->type != XDGShell)
 | 
				
			||||||
		wlr_xwayland_surface_configure(c->surface.xwayland,
 | 
							wlr_xwayland_surface_configure(c->surface.xwayland,
 | 
				
			||||||
				c->geom.x, c->geom.y,
 | 
									c->geom.x, c->geom.y,
 | 
				
			||||||
				c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw);
 | 
									c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		c->resize = wlr_xdg_toplevel_set_size(c->surface.xdg,
 | 
							c->resize = wlr_xdg_toplevel_set_size(c->surface.xdg,
 | 
				
			||||||
				c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw);
 | 
									c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1586,6 +1565,7 @@ setup(void)
 | 
				
			||||||
	wl_signal_add(&seat->events.request_set_primary_selection,
 | 
						wl_signal_add(&seat->events.request_set_primary_selection,
 | 
				
			||||||
			&request_set_psel);
 | 
								&request_set_psel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Initialise the XWayland X server.
 | 
						 * Initialise the XWayland X server.
 | 
				
			||||||
	 * It will be started when the first X client is started.
 | 
						 * It will be started when the first X client is started.
 | 
				
			||||||
| 
						 | 
					@ -1599,6 +1579,7 @@ setup(void)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		fprintf(stderr, "failed to setup XWayland X server, continuing without it\n");
 | 
							fprintf(stderr, "failed to setup XWayland X server, continuing without it\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -1710,49 +1691,15 @@ unmapnotify(struct wl_listener *listener, void *data)
 | 
				
			||||||
	/* Called when the surface is unmapped, and should no longer be shown. */
 | 
						/* Called when the surface is unmapped, and should no longer be shown. */
 | 
				
			||||||
	Client *c = wl_container_of(listener, c, unmap);
 | 
						Client *c = wl_container_of(listener, c, unmap);
 | 
				
			||||||
	wl_list_remove(&c->link);
 | 
						wl_list_remove(&c->link);
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	if (c->type == X11Unmanaged)
 | 
						if (c->type == X11Unmanaged)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	setmon(c, NULL, 0);
 | 
						setmon(c, NULL, 0);
 | 
				
			||||||
	wl_list_remove(&c->flink);
 | 
						wl_list_remove(&c->flink);
 | 
				
			||||||
	wl_list_remove(&c->slink);
 | 
						wl_list_remove(&c->slink);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
updatewindowtype(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	size_t i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (c->type != XDGShell)
 | 
					 | 
				
			||||||
		for (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])
 | 
					 | 
				
			||||||
				c->isfloating = 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
xwaylandready(struct wl_listener *listener, void *data) {
 | 
					 | 
				
			||||||
	xcb_connection_t *xc = xcb_connect(xwayland->display_name, NULL);
 | 
					 | 
				
			||||||
	int err = xcb_connection_has_error(xc);
 | 
					 | 
				
			||||||
	if (err) {
 | 
					 | 
				
			||||||
		fprintf(stderr, "xcb_connect to X server failed with code %d\n. Continuing with degraded functionality.\n", err);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Collect atoms we are interested in.  If getatom returns 0, we will
 | 
					 | 
				
			||||||
	 * not detect that window type. */
 | 
					 | 
				
			||||||
	netatom[NetWMWindowTypeDialog] = getatom(xc, "_NET_WM_WINDOW_TYPE_DIALOG");
 | 
					 | 
				
			||||||
	netatom[NetWMWindowTypeSplash] = getatom(xc, "_NET_WM_WINDOW_TYPE_SPLASH");
 | 
					 | 
				
			||||||
	netatom[NetWMWindowTypeUtility] = getatom(xc, "_NET_WM_WINDOW_TYPE_TOOLBAR");
 | 
					 | 
				
			||||||
	netatom[NetWMWindowTypeToolbar] = getatom(xc, "_NET_WM_WINDOW_TYPE_UTILITY");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* assign the one and only seat */
 | 
					 | 
				
			||||||
	wlr_xwayland_set_seat(xwayland, seat);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	xcb_disconnect(xc);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
view(const Arg *arg)
 | 
					view(const Arg *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1778,27 +1725,6 @@ xytoclient(double x, double y)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Client *
 | 
					 | 
				
			||||||
xytoindependent(double x, double y)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* Find the topmost visible independent at point (x, y).
 | 
					 | 
				
			||||||
	 * For independents, the most recently created can be used as the "top".
 | 
					 | 
				
			||||||
	 * We rely on the X11 convention of unmapping unmanaged when the "owning"
 | 
					 | 
				
			||||||
	 * client loses focus, which ensures that unmanaged are only visible on
 | 
					 | 
				
			||||||
	 * the current tag. */
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
	struct wlr_box geom;
 | 
					 | 
				
			||||||
	wl_list_for_each_reverse(c, &independents, link) {
 | 
					 | 
				
			||||||
		geom.x = c->surface.xwayland->x;
 | 
					 | 
				
			||||||
		geom.y = c->surface.xwayland->y;
 | 
					 | 
				
			||||||
		geom.width = c->surface.xwayland->width;
 | 
					 | 
				
			||||||
		geom.height = c->surface.xwayland->height;
 | 
					 | 
				
			||||||
		if (wlr_box_contains_point(&geom, x, y))
 | 
					 | 
				
			||||||
			return c;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Monitor *
 | 
					Monitor *
 | 
				
			||||||
xytomon(double x, double y)
 | 
					xytomon(double x, double y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1838,6 +1764,140 @@ zoom(const Arg *arg)
 | 
				
			||||||
	arrange(selmon);
 | 
						arrange(selmon);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					activatex11(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					       Client *c = wl_container_of(listener, c, activate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       /* Only "managed" windows can be activated */
 | 
				
			||||||
 | 
					       if (c->type == X11Managed)
 | 
				
			||||||
 | 
					               wlr_xwayland_surface_activate(c->surface.xwayland, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					createnotifyx11(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wlr_xwayland_surface *xwayland_surface = data;
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Listen to the various events it can emit */
 | 
				
			||||||
 | 
						c->map.notify = maprequest;
 | 
				
			||||||
 | 
						wl_signal_add(&xwayland_surface->events.map, &c->map);
 | 
				
			||||||
 | 
						c->unmap.notify = unmapnotify;
 | 
				
			||||||
 | 
						wl_signal_add(&xwayland_surface->events.unmap, &c->unmap);
 | 
				
			||||||
 | 
						c->activate.notify = activatex11;
 | 
				
			||||||
 | 
						wl_signal_add(&xwayland_surface->events.request_activate, &c->activate);
 | 
				
			||||||
 | 
						c->destroy.notify = destroynotify;
 | 
				
			||||||
 | 
						wl_signal_add(&xwayland_surface->events.destroy, &c->destroy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Atom
 | 
				
			||||||
 | 
					getatom(xcb_connection_t *xc, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Atom atom = 0;
 | 
				
			||||||
 | 
						xcb_intern_atom_cookie_t cookie;
 | 
				
			||||||
 | 
						xcb_intern_atom_reply_t *reply;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cookie = xcb_intern_atom(xc, 0, strlen(name), name);
 | 
				
			||||||
 | 
						if ((reply = xcb_intern_atom_reply(xc, cookie, NULL)))
 | 
				
			||||||
 | 
							atom = reply->atom;
 | 
				
			||||||
 | 
						free(reply);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					renderindependents(struct wlr_output *output, struct timespec *now)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
						struct render_data rdata;
 | 
				
			||||||
 | 
						struct wlr_box geom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_for_each_reverse(c, &independents, link) {
 | 
				
			||||||
 | 
							geom.x = c->surface.xwayland->x;
 | 
				
			||||||
 | 
							geom.y = c->surface.xwayland->y;
 | 
				
			||||||
 | 
							geom.width = c->surface.xwayland->width;
 | 
				
			||||||
 | 
							geom.height = c->surface.xwayland->height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Only render visible clients which show on this output */
 | 
				
			||||||
 | 
							if (!wlr_output_layout_intersects(output_layout, output, &geom))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rdata.output = output;
 | 
				
			||||||
 | 
							rdata.when = now;
 | 
				
			||||||
 | 
							rdata.x = c->surface.xwayland->x;
 | 
				
			||||||
 | 
							rdata.y = c->surface.xwayland->y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wlr_surface_for_each_surface(c->surface.xwayland->surface, render, &rdata);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					updatewindowtype(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->type != XDGShell)
 | 
				
			||||||
 | 
							for (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])
 | 
				
			||||||
 | 
									c->isfloating = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					xwaylandready(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						xcb_connection_t *xc = xcb_connect(xwayland->display_name, NULL);
 | 
				
			||||||
 | 
						int err = xcb_connection_has_error(xc);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							fprintf(stderr, "xcb_connect to X server failed with code %d\n. Continuing with degraded functionality.\n", err);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Collect atoms we are interested in.  If getatom returns 0, we will
 | 
				
			||||||
 | 
						 * not detect that window type. */
 | 
				
			||||||
 | 
						netatom[NetWMWindowTypeDialog] = getatom(xc, "_NET_WM_WINDOW_TYPE_DIALOG");
 | 
				
			||||||
 | 
						netatom[NetWMWindowTypeSplash] = getatom(xc, "_NET_WM_WINDOW_TYPE_SPLASH");
 | 
				
			||||||
 | 
						netatom[NetWMWindowTypeUtility] = getatom(xc, "_NET_WM_WINDOW_TYPE_TOOLBAR");
 | 
				
			||||||
 | 
						netatom[NetWMWindowTypeToolbar] = getatom(xc, "_NET_WM_WINDOW_TYPE_UTILITY");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* assign the one and only seat */
 | 
				
			||||||
 | 
						wlr_xwayland_set_seat(xwayland, seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xcb_disconnect(xc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Client *
 | 
				
			||||||
 | 
					xytoindependent(double x, double y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Find the topmost visible independent at point (x, y).
 | 
				
			||||||
 | 
						 * For independents, the most recently created can be used as the "top".
 | 
				
			||||||
 | 
						 * We rely on the X11 convention of unmapping unmanaged when the "owning"
 | 
				
			||||||
 | 
						 * client loses focus, which ensures that unmanaged are only visible on
 | 
				
			||||||
 | 
						 * the current tag. */
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
						struct wlr_box geom;
 | 
				
			||||||
 | 
						wl_list_for_each_reverse(c, &independents, link) {
 | 
				
			||||||
 | 
							geom.x = c->surface.xwayland->x;
 | 
				
			||||||
 | 
							geom.y = c->surface.xwayland->y;
 | 
				
			||||||
 | 
							geom.width = c->surface.xwayland->width;
 | 
				
			||||||
 | 
							geom.height = c->surface.xwayland->height;
 | 
				
			||||||
 | 
							if (wlr_box_contains_point(&geom, x, y))
 | 
				
			||||||
 | 
								return c;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main(int argc, char *argv[])
 | 
					main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1882,7 +1942,9 @@ main(int argc, char *argv[])
 | 
				
			||||||
	run(startup_cmd);
 | 
						run(startup_cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Once wl_display_run returns, we shut down the server. */
 | 
						/* Once wl_display_run returns, we shut down the server. */
 | 
				
			||||||
 | 
					#ifdef XWAYLAND
 | 
				
			||||||
	wlr_xwayland_destroy(xwayland);
 | 
						wlr_xwayland_destroy(xwayland);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	wl_display_destroy_clients(dpy);
 | 
						wl_display_destroy_clients(dpy);
 | 
				
			||||||
	wl_display_destroy(dpy);
 | 
						wl_display_destroy(dpy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue