mirror of
				https://codeberg.org/dwl/dwl.git
				synced 2025-10-28 02:34:15 +00:00 
			
		
		
		
	xwayland: add server and basic window functionality (#10)
* xwayland: add server and basic window functionality * xwayland: add server and basic window functionality * xwayland: add server and basic window functionality * xwayland: add server and basic window functionality
This commit is contained in:
		
							parent
							
								
									91b18d4d4d
								
							
						
					
					
						commit
						57fef50310
					
				
							
								
								
									
										160
									
								
								dwl.c
									
									
									
									
									
								
							
							
						
						
									
										160
									
								
								dwl.c
									
									
									
									
									
								
							| @ -31,6 +31,7 @@ | |||||||
| #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 <xkbcommon/xkbcommon.h> | #include <xkbcommon/xkbcommon.h> | ||||||
| 
 | 
 | ||||||
| /* macros */ | /* macros */ | ||||||
| @ -41,6 +42,7 @@ | |||||||
| #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) | ||||||
|  | #define WLR_SURFACE(C)          (c->isxdg ? c->xdg_surface->surface : c->xwayland_surface->surface) | ||||||
| 
 | 
 | ||||||
| /* enums */ | /* enums */ | ||||||
| enum { CurNormal, CurMove, CurResize }; /* cursor */ | enum { CurNormal, CurMove, CurResize }; /* cursor */ | ||||||
| @ -64,11 +66,15 @@ typedef struct { | |||||||
| 	struct wl_list link; | 	struct wl_list link; | ||||||
| 	struct wl_list flink; | 	struct wl_list flink; | ||||||
| 	struct wl_list slink; | 	struct wl_list slink; | ||||||
| 	struct wlr_xdg_surface *xdg_surface; | 	union { | ||||||
|  | 		struct wlr_xdg_surface *xdg_surface; | ||||||
|  | 		struct wlr_xwayland_surface *xwayland_surface; | ||||||
|  | 	}; | ||||||
| 	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 */ | ||||||
|  | 	int isxdg; | ||||||
| 	Monitor *mon; | 	Monitor *mon; | ||||||
| 	int bw; | 	int bw; | ||||||
| 	unsigned int tags; | 	unsigned int tags; | ||||||
| @ -148,7 +154,8 @@ static void buttonpress(struct wl_listener *listener, void *data); | |||||||
| static void chvt(const Arg *arg); | static void chvt(const Arg *arg); | ||||||
| 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 createnotifyxdg(struct wl_listener *listener, void *data); | ||||||
|  | static void createnotifyxwayland(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); | ||||||
| @ -205,6 +212,8 @@ static const char broken[] = "broken"; | |||||||
| static struct wl_display *dpy; | 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_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 */ | ||||||
| @ -235,7 +244,8 @@ static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute}; | |||||||
| static struct wl_listener new_input = {.notify = inputdevice}; | 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 = createnotifyxdg}; | ||||||
|  | static struct wl_listener new_xwayland_surface = {.notify = createnotifyxwayland}; | ||||||
| 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}; | ||||||
| @ -271,10 +281,15 @@ applyrules(Client *c) | |||||||
| 
 | 
 | ||||||
| 	/* rule matching */ | 	/* rule matching */ | ||||||
| 	c->isfloating = 0; | 	c->isfloating = 0; | ||||||
| 	if (!(appid = c->xdg_surface->toplevel->app_id)) | 	if (c->isxdg) { | ||||||
| 		appid = broken; | 		if (!(appid = c->xdg_surface->toplevel->app_id)) | ||||||
| 	if (!(title = c->xdg_surface->toplevel->title)) | 			appid = broken; | ||||||
| 		title = broken; | 		if (!(title = c->xdg_surface->toplevel->title)) | ||||||
|  | 			title = broken; | ||||||
|  | 	} else { | ||||||
|  | 		if (!(title = c->xwayland_surface->title)) | ||||||
|  | 			title = broken; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	for (r = rules; r < END(rules); r++) { | 	for (r = rules; r < END(rules); r++) { | ||||||
| 		if ((!r->title || strstr(title, r->title)) | 		if ((!r->title || strstr(title, r->title)) | ||||||
| @ -328,9 +343,14 @@ buttonpress(struct wl_listener *listener, void *data) | |||||||
| 	case WLR_BUTTON_PRESSED:; | 	case WLR_BUTTON_PRESSED:; | ||||||
| 		/* Change focus if the button was _pressed_ over a client */ | 		/* Change focus if the button was _pressed_ over a client */ | ||||||
| 		if ((c = xytoclient(cursor->x, cursor->y))) { | 		if ((c = xytoclient(cursor->x, cursor->y))) { | ||||||
| 			surface = wlr_xdg_surface_surface_at(c->xdg_surface, | 			if (c->isxdg) | ||||||
| 					cursor->x - c->geom.x - c->bw, | 				surface = wlr_xdg_surface_surface_at(c->xdg_surface, | ||||||
| 					cursor->y - c->geom.y - c->bw, NULL, NULL); | 						cursor->x - c->geom.x - c->bw, | ||||||
|  | 						cursor->y - c->geom.y - c->bw, NULL, NULL); | ||||||
|  | 			else | ||||||
|  | 				surface = wlr_surface_surface_at(c->xwayland_surface->surface, | ||||||
|  | 						cursor->x - c->geom.x - c->bw, | ||||||
|  | 						cursor->y - c->geom.y - c->bw, NULL, NULL); | ||||||
| 			focusclient(c, surface, 1); | 			focusclient(c, surface, 1); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -458,7 +478,7 @@ createmon(struct wl_listener *listener, void *data) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| createnotify(struct wl_listener *listener, void *data) | createnotifyxdg(struct wl_listener *listener, void *data) | ||||||
| { | { | ||||||
| 	/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
 | 	/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
 | ||||||
| 	 * client, either a toplevel (application window) or popup. */ | 	 * client, either a toplevel (application window) or popup. */ | ||||||
| @ -471,6 +491,7 @@ 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->xdg_surface = xdg_surface; | 	c->xdg_surface = xdg_surface; | ||||||
|  | 	c->isxdg = 1; | ||||||
| 	c->bw = borderpx; | 	c->bw = borderpx; | ||||||
| 
 | 
 | ||||||
| 	/* Tell the client not to try anything fancy */ | 	/* Tell the client not to try anything fancy */ | ||||||
| @ -486,6 +507,27 @@ 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 | ||||||
|  | createnotifyxwayland(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->xwayland_surface = xwayland_surface; | ||||||
|  | 	c->isxdg = 0; | ||||||
|  | 	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->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) | ||||||
| { | { | ||||||
| @ -566,8 +608,8 @@ focusclient(Client *c, struct wlr_surface *surface, int lift) | |||||||
| 	Client *sel = selclient(); | 	Client *sel = selclient(); | ||||||
| 	struct wlr_keyboard *kb; | 	struct wlr_keyboard *kb; | ||||||
| 	/* Previous and new xdg toplevel surfaces */ | 	/* Previous and new xdg toplevel surfaces */ | ||||||
| 	struct wlr_xdg_surface *ptl = sel ? sel->xdg_surface : NULL; | 	Client *ptl = sel; | ||||||
| 	struct wlr_xdg_surface *tl = c ? c->xdg_surface : NULL; | 	Client *tl = c; | ||||||
| 	/* Previously focused surface */ | 	/* Previously focused surface */ | ||||||
| 	struct wlr_surface *psurface = seat->keyboard_state.focused_surface; | 	struct wlr_surface *psurface = seat->keyboard_state.focused_surface; | ||||||
| 
 | 
 | ||||||
| @ -575,7 +617,7 @@ focusclient(Client *c, struct wlr_surface *surface, int lift) | |||||||
| 		/* assert(VISIBLEON(c, c->mon)); ? */ | 		/* assert(VISIBLEON(c, c->mon)); ? */ | ||||||
| 		/* Use top-level wlr_surface if nothing more specific given */ | 		/* Use top-level wlr_surface if nothing more specific given */ | ||||||
| 		if (!surface) | 		if (!surface) | ||||||
| 			surface = c->xdg_surface->surface; | 			surface = WLR_SURFACE(c); | ||||||
| 
 | 
 | ||||||
| 		/* Focus the correct monitor (must come after selclient!) */ | 		/* Focus the correct monitor (must come after selclient!) */ | ||||||
| 		selmon = c->mon; | 		selmon = c->mon; | ||||||
| @ -610,10 +652,18 @@ focusclient(Client *c, struct wlr_surface *surface, int lift) | |||||||
| 	 * activate the new one.  This lets the clients know to repaint | 	 * activate the new one.  This lets the clients know to repaint | ||||||
| 	 * accordingly, e.g. show/hide a caret. | 	 * accordingly, e.g. show/hide a caret. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (tl != ptl && ptl) | 	if (tl != ptl && ptl) { | ||||||
| 		wlr_xdg_toplevel_set_activated(ptl, 0); | 		if (ptl->isxdg) | ||||||
| 	if (tl != ptl && tl) | 			wlr_xdg_toplevel_set_activated(ptl->xdg_surface, 0); | ||||||
| 		wlr_xdg_toplevel_set_activated(tl, 1); | 		else | ||||||
|  | 			wlr_xwayland_surface_activate(ptl->xwayland_surface, 0); | ||||||
|  | 	} | ||||||
|  | 	if (tl != ptl && tl) { | ||||||
|  | 		if (tl->isxdg) | ||||||
|  | 			wlr_xdg_toplevel_set_activated(tl->xdg_surface, 1); | ||||||
|  | 		else | ||||||
|  | 			wlr_xwayland_surface_activate(tl->xwayland_surface, 1); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -783,9 +833,17 @@ maprequest(struct wl_listener *listener, void *data) | |||||||
| 	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); | ||||||
| 	wlr_xdg_surface_get_geometry(c->xdg_surface, &c->geom); | 
 | ||||||
| 	c->geom.width += 2 * c->bw; | 	if (c->isxdg) { | ||||||
| 	c->geom.height += 2 * c->bw; | 		wlr_xdg_surface_get_geometry(c->xdg_surface, &c->geom); | ||||||
|  | 		c->geom.width += 2 * c->bw; | ||||||
|  | 		c->geom.height += 2 * c->bw; | ||||||
|  | 	} else { | ||||||
|  | 		c->geom.x = c->xwayland_surface->x; | ||||||
|  | 		c->geom.y = c->xwayland_surface->y; | ||||||
|  | 		c->geom.width = c->xwayland_surface->width + 2 * c->bw; | ||||||
|  | 		c->geom.height = c->xwayland_surface->height + 2 * c->bw; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Set initial monitor, tags, floating status, and focus */ | 	/* Set initial monitor, tags, floating status, and focus */ | ||||||
| 	applyrules(c); | 	applyrules(c); | ||||||
| @ -830,10 +888,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. */ | ||||||
| 	if ((c = xytoclient(cursor->x, cursor->y))) | 	if ((c = xytoclient(cursor->x, cursor->y))) { | ||||||
| 		surface = wlr_xdg_surface_surface_at(c->xdg_surface, | 		if (c->isxdg) | ||||||
| 				cursor->x - c->geom.x - c->bw, | 			surface = wlr_xdg_surface_surface_at(c->xdg_surface, | ||||||
| 				cursor->y - c->geom.y - c->bw, &sx, &sy); | 					cursor->x - c->geom.x - c->bw, | ||||||
|  | 					cursor->y - c->geom.y - c->bw, &sx, &sy); | ||||||
|  | 		else | ||||||
|  | 			surface = wlr_surface_surface_at(c->xwayland_surface->surface, | ||||||
|  | 					cursor->x - c->geom.x - c->bw, | ||||||
|  | 					cursor->y - c->geom.y - c->bw, &sx, &sy); | ||||||
|  | 	} | ||||||
| 	/* If there's no client surface under the cursor, set the cursor image to a
 | 	/* If there's no client surface under the cursor, set the cursor image to a
 | ||||||
| 	 * default. This is what makes the cursor image appear when you move it | 	 * default. This is what makes the cursor image appear when you move it | ||||||
| 	 * off of a client or over its border. */ | 	 * off of a client or over its border. */ | ||||||
| @ -893,7 +957,8 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, | |||||||
| { | { | ||||||
| 	/* Use top level surface if nothing more specific given */ | 	/* Use top level surface if nothing more specific given */ | ||||||
| 	if (c && !surface) | 	if (c && !surface) | ||||||
| 		surface = c->xdg_surface->surface; | 		surface = WLR_SURFACE(c); | ||||||
|  | 
 | ||||||
| 	/* If surface is already focused, only notify of motion */ | 	/* If surface is already focused, only notify of motion */ | ||||||
| 	if (surface && surface == seat->pointer_state.focused_surface) { | 	if (surface && surface == seat->pointer_state.focused_surface) { | ||||||
| 		wlr_seat_pointer_notify_motion(seat, time, sx, sy); | 		wlr_seat_pointer_notify_motion(seat, time, sx, sy); | ||||||
| @ -985,6 +1050,7 @@ renderclients(Monitor *m, struct timespec *now) | |||||||
| 	int i, w, h; | 	int i, w, h; | ||||||
| 	struct render_data rdata; | 	struct render_data rdata; | ||||||
| 	struct wlr_box *borders; | 	struct wlr_box *borders; | ||||||
|  | 	struct wlr_surface *surface; | ||||||
| 	/* Each subsequent window we render is rendered on top of the last. Because
 | 	/* Each subsequent window we render is rendered on top of the last. Because
 | ||||||
| 	 * our stacking list is ordered front-to-back, we iterate over it backwards. */ | 	 * our stacking list is ordered front-to-back, we iterate over it backwards. */ | ||||||
| 	wl_list_for_each_reverse(c, &stack, slink) { | 	wl_list_for_each_reverse(c, &stack, slink) { | ||||||
| @ -993,11 +1059,12 @@ renderclients(Monitor *m, struct timespec *now) | |||||||
| 					output_layout, m->wlr_output, &c->geom)) | 					output_layout, m->wlr_output, &c->geom)) | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
|  | 		surface = WLR_SURFACE(c); | ||||||
| 		ox = c->geom.x, oy = c->geom.y; | 		ox = c->geom.x, oy = c->geom.y; | ||||||
| 		wlr_output_layout_output_coords(output_layout, m->wlr_output, | 		wlr_output_layout_output_coords(output_layout, m->wlr_output, | ||||||
| 				&ox, &oy); | 				&ox, &oy); | ||||||
| 		w = c->xdg_surface->surface->current.width; | 		w = surface->current.width; | ||||||
| 		h = c->xdg_surface->surface->current.height; | 		h = surface->current.height; | ||||||
| 		borders = (struct wlr_box[4]) { | 		borders = (struct wlr_box[4]) { | ||||||
| 			{ox, oy, w + 2 * c->bw, c->bw},             /* top */ | 			{ox, oy, w + 2 * c->bw, c->bw},             /* top */ | ||||||
| 			{ox, oy + c->bw, c->bw, h},                 /* left */ | 			{ox, oy + c->bw, c->bw, h},                 /* left */ | ||||||
| @ -1015,8 +1082,11 @@ renderclients(Monitor *m, struct timespec *now) | |||||||
| 		rdata.output = m->wlr_output, | 		rdata.output = m->wlr_output, | ||||||
| 		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; | ||||||
| 		wlr_xdg_surface_for_each_surface(c->xdg_surface, render, &rdata); | 		if (c->isxdg) | ||||||
|  | 			wlr_xdg_surface_for_each_surface(c->xdg_surface, render, &rdata); | ||||||
|  | 		else | ||||||
|  | 			wlr_surface_for_each_surface(c->xwayland_surface->surface, render, &rdata); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -1069,8 +1139,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 */ | ||||||
| 	wlr_xdg_toplevel_set_size(c->xdg_surface, | 	if (c->isxdg) | ||||||
| 			c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); | 		wlr_xdg_toplevel_set_size(c->xdg_surface, | ||||||
|  | 				c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); | ||||||
|  | 	else | ||||||
|  | 		wlr_xwayland_surface_configure(c->xwayland_surface, | ||||||
|  | 				c->geom.x, c->geom.y, | ||||||
|  | 				c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -1214,19 +1289,20 @@ setmon(Client *c, Monitor *m, unsigned int newtags) | |||||||
| { | { | ||||||
| 	int hadfocus; | 	int hadfocus; | ||||||
| 	Monitor *oldmon = c->mon; | 	Monitor *oldmon = c->mon; | ||||||
|  | 	struct wlr_surface *surface = WLR_SURFACE(c); | ||||||
| 	if (oldmon == m) | 	if (oldmon == m) | ||||||
| 		return; | 		return; | ||||||
| 	hadfocus = (c == selclient()); | 	hadfocus = (c == selclient()); | ||||||
| 	c->mon = m; | 	c->mon = m; | ||||||
| 	/* XXX leave/enter is not optimal but works */ | 	/* XXX leave/enter is not optimal but works */ | ||||||
| 	if (oldmon) { | 	if (oldmon) { | ||||||
| 		wlr_surface_send_leave(c->xdg_surface->surface, oldmon->wlr_output); | 		wlr_surface_send_leave(surface, oldmon->wlr_output); | ||||||
| 		arrange(oldmon); | 		arrange(oldmon); | ||||||
| 	} | 	} | ||||||
| 	if (m) { | 	if (m) { | ||||||
| 		/* Make sure window actually overlaps with the monitor */ | 		/* Make sure window actually overlaps with the monitor */ | ||||||
| 		applybounds(c, &m->m); | 		applybounds(c, &m->m); | ||||||
| 		wlr_surface_send_enter(c->xdg_surface->surface, m->wlr_output); | 		wlr_surface_send_enter(surface, m->wlr_output); | ||||||
| 		c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ | 		c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ | ||||||
| 		arrange(m); | 		arrange(m); | ||||||
| 	} | 	} | ||||||
| @ -1282,7 +1358,7 @@ setup(void) | |||||||
| 	 * to dig your fingers in and play with their behavior if you want. Note that | 	 * to dig your fingers in and play with their behavior if you want. Note that | ||||||
| 	 * the clients cannot set the selection directly without compositor approval, | 	 * the clients cannot set the selection directly without compositor approval, | ||||||
| 	 * see the setsel() function. */ | 	 * see the setsel() function. */ | ||||||
| 	wlr_compositor_create(dpy, drw); | 	compositor = wlr_compositor_create(dpy, drw); | ||||||
| 	wlr_screencopy_manager_v1_create(dpy); | 	wlr_screencopy_manager_v1_create(dpy); | ||||||
| 	wlr_data_device_manager_create(dpy); | 	wlr_data_device_manager_create(dpy); | ||||||
| 	wlr_primary_selection_v1_device_manager_create(dpy); | 	wlr_primary_selection_v1_device_manager_create(dpy); | ||||||
| @ -1360,6 +1436,19 @@ setup(void) | |||||||
| 			&request_set_sel); | 			&request_set_sel); | ||||||
| 	wl_signal_add(&seat->events.request_set_primary_selection, | 	wl_signal_add(&seat->events.request_set_primary_selection, | ||||||
| 			&request_set_psel); | 			&request_set_psel); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Initialise the XWayland X server. | ||||||
|  | 	 * It will be started when the first X client is started. | ||||||
|  | 	 */ | ||||||
|  | 	xwayland = wlr_xwayland_create(dpy, compositor, true); | ||||||
|  | 	if (xwayland) { | ||||||
|  | 		wl_signal_add(&xwayland->events.new_surface, &new_xwayland_surface); | ||||||
|  | 
 | ||||||
|  | 		setenv("DISPLAY", xwayland->display_name, true); | ||||||
|  | 	} else { | ||||||
|  | 		fprintf(stderr, "failed to setup XWayland X server, continuing without it\n"); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -1550,6 +1639,7 @@ 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. */ | ||||||
|  | 	wlr_xwayland_destroy(xwayland); | ||||||
| 	wl_display_destroy_clients(dpy); | 	wl_display_destroy_clients(dpy); | ||||||
| 	wl_display_destroy(dpy); | 	wl_display_destroy(dpy); | ||||||
| 	return EXIT_SUCCESS; | 	return EXIT_SUCCESS; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Alexander Courtis
						Alexander Courtis