Merge remote-tracking branch 'upstream/main' into wlroots-next
This commit is contained in:
		
							
								
								
									
										9
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
									
									
									
									
								
							| @@ -15,8 +15,8 @@ LDLIBS    = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) | ||||
|  | ||||
| all: dwl | ||||
| dwl: dwl.o util.o | ||||
| 	$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@ | ||||
| dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h | ||||
| 	$(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ | ||||
| dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h | ||||
| util.o: util.c util.h | ||||
|  | ||||
| # wayland-scanner is a tool which generates C headers and rigging for Wayland | ||||
| @@ -34,6 +34,9 @@ pointer-constraints-unstable-v1-protocol.h: | ||||
| wlr-layer-shell-unstable-v1-protocol.h: | ||||
| 	$(WAYLAND_SCANNER) enum-header \ | ||||
| 		protocols/wlr-layer-shell-unstable-v1.xml $@ | ||||
| wlr-output-power-management-unstable-v1-protocol.h: | ||||
| 	$(WAYLAND_SCANNER) server-header \ | ||||
| 		protocols/wlr-output-power-management-unstable-v1.xml $@ | ||||
| xdg-shell-protocol.h: | ||||
| 	$(WAYLAND_SCANNER) server-header \ | ||||
| 		$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ | ||||
| @@ -66,4 +69,4 @@ uninstall: | ||||
|  | ||||
| .SUFFIXES: .c .o | ||||
| .c.o: | ||||
| 	$(CC) $(CPPFLAGS) $(DWLCFLAGS) -c $< | ||||
| 	$(CC) $(CPPFLAGS) $(DWLCFLAGS) -o $@ -c $< | ||||
|   | ||||
							
								
								
									
										20
									
								
								client.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								client.h
									
									
									
									
									
								
							| @@ -172,11 +172,11 @@ client_get_parent(Client *c) | ||||
| { | ||||
| 	Client *p = NULL; | ||||
| #ifdef XWAYLAND | ||||
|     if (client_is_x11(c)) { | ||||
|         if (c->surface.xwayland->parent) | ||||
|             toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); | ||||
|         return p; | ||||
|     } | ||||
| 	if (client_is_x11(c)) { | ||||
| 		if (c->surface.xwayland->parent) | ||||
| 			toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); | ||||
| 		return p; | ||||
| 	} | ||||
| #endif | ||||
| 	if (c->surface.xdg->toplevel->parent) | ||||
| 		toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); | ||||
| @@ -187,12 +187,12 @@ static inline int | ||||
| client_has_children(Client *c) | ||||
| { | ||||
| #ifdef XWAYLAND | ||||
|     if (client_is_x11(c)) | ||||
|         return !wl_list_empty(&c->surface.xwayland->children); | ||||
| 	if (client_is_x11(c)) | ||||
| 		return !wl_list_empty(&c->surface.xwayland->children); | ||||
| #endif | ||||
|     /* surface.xdg->link is never empty because it always contains at least the | ||||
|      * surface itself. */ | ||||
|     return wl_list_length(&c->surface.xdg->link) > 1; | ||||
| 	/* surface.xdg->link is never empty because it always contains at least the | ||||
| 	 * surface itself. */ | ||||
| 	return wl_list_length(&c->surface.xdg->link) > 1; | ||||
| } | ||||
|  | ||||
| static inline const char * | ||||
|   | ||||
| @@ -13,3 +13,5 @@ XLIBS = | ||||
| # Uncomment to build XWayland support | ||||
| #XWAYLAND = -DXWAYLAND | ||||
| #XLIBS = xcb xcb-icccm | ||||
|  | ||||
| CC = gcc | ||||
|   | ||||
							
								
								
									
										84
									
								
								dwl.c
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								dwl.c
									
									
									
									
									
								
							| @@ -35,6 +35,7 @@ | ||||
| #include <wlr/types/wlr_output.h> | ||||
| #include <wlr/types/wlr_output_layout.h> | ||||
| #include <wlr/types/wlr_output_management_v1.h> | ||||
| #include <wlr/types/wlr_output_power_management_v1.h> | ||||
| #include <wlr/types/wlr_pointer.h> | ||||
| #include <wlr/types/wlr_pointer_constraints_v1.h> | ||||
| #include <wlr/types/wlr_presentation_time.h> | ||||
| @@ -207,6 +208,7 @@ struct Monitor { | ||||
| 	int gamma_lut_changed; | ||||
| 	int nmaster; | ||||
| 	char ltsymbol[16]; | ||||
| 	int asleep; | ||||
| }; | ||||
|  | ||||
| typedef struct { | ||||
| @@ -314,6 +316,7 @@ static void outputmgrtest(struct wl_listener *listener, void *data); | ||||
| static void pointerfocus(Client *c, struct wlr_surface *surface, | ||||
| 		double sx, double sy, uint32_t time); | ||||
| static void printstatus(void); | ||||
| static void powermgrsetmode(struct wl_listener *listener, void *data); | ||||
| static void quit(const Arg *arg); | ||||
| static void rendermon(struct wl_listener *listener, void *data); | ||||
| static void requestdecorationmode(struct wl_listener *listener, void *data); | ||||
| @@ -386,6 +389,7 @@ static struct wlr_gamma_control_manager_v1 *gamma_control_mgr; | ||||
| static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; | ||||
| static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; | ||||
| static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; | ||||
| static struct wlr_output_power_manager_v1 *power_mgr; | ||||
|  | ||||
| static struct wlr_pointer_constraints_v1 *pointer_constraints; | ||||
| static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr; | ||||
| @@ -402,7 +406,6 @@ static struct wl_listener lock_listener = {.notify = locksession}; | ||||
|  | ||||
| static struct wlr_seat *seat; | ||||
| static KeyboardGroup *kb_group; | ||||
| static struct wlr_surface *held_grab; | ||||
| static unsigned int cursor_mode; | ||||
| static Client *grabc; | ||||
| static int grabcx, grabcy; /* client-relative */ | ||||
| @@ -608,7 +611,6 @@ buttonpress(struct wl_listener *listener, void *data) | ||||
| 	switch (event->state) { | ||||
| 	case WL_POINTER_BUTTON_STATE_PRESSED: | ||||
| 		cursor_mode = CurPressed; | ||||
| 		held_grab = seat->pointer_state.focused_surface; | ||||
| 		if (locked) | ||||
| 			break; | ||||
|  | ||||
| @@ -628,7 +630,6 @@ buttonpress(struct wl_listener *listener, void *data) | ||||
| 		} | ||||
| 		break; | ||||
| 	case WL_POINTER_BUTTON_STATE_RELEASED: | ||||
| 		held_grab = NULL; | ||||
| 		/* If you released any buttons, we exit interactive move/resize mode. */ | ||||
| 		/* TODO should reset to the pointer focus's current setcursor */ | ||||
| 		if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { | ||||
| @@ -682,7 +683,7 @@ cleanup(void) | ||||
| #endif | ||||
| 	wl_display_destroy_clients(dpy); | ||||
| 	if (child_pid > 0) { | ||||
| 		kill(child_pid, SIGTERM); | ||||
| 		kill(-child_pid, SIGTERM); | ||||
| 		waitpid(child_pid, NULL, 0); | ||||
| 	} | ||||
| 	wlr_xcursor_manager_destroy(cursor_mgr); | ||||
| @@ -738,6 +739,9 @@ closemon(Monitor *m) | ||||
| 		do /* don't switch to disabled mons */ | ||||
| 			selmon = wl_container_of(mons.next, selmon, link); | ||||
| 		while (!selmon->wlr_output->enabled && i++ < nmons); | ||||
|  | ||||
| 		if (!selmon->wlr_output->enabled) | ||||
| 			selmon = NULL; | ||||
| 	} | ||||
|  | ||||
| 	wl_list_for_each(c, &clients, link) { | ||||
| @@ -1807,6 +1811,18 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d | ||||
| 	struct wlr_surface *surface = NULL; | ||||
| 	struct wlr_pointer_constraint_v1 *constraint; | ||||
|  | ||||
| 	/* Find the client under the pointer and send the event along. */ | ||||
| 	xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); | ||||
|  | ||||
| 	if (cursor_mode == CurPressed && !seat->drag | ||||
| 			&& surface != seat->pointer_state.focused_surface | ||||
| 			&& toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) { | ||||
| 		c = w; | ||||
| 		surface = seat->pointer_state.focused_surface; | ||||
| 		sx = cursor->x - (l ? l->geom.x : w->geom.x); | ||||
| 		sy = cursor->y - (l ? l->geom.y : w->geom.y); | ||||
| 	} | ||||
|  | ||||
| 	/* time is 0 in internal calls meant to restore pointer focus. */ | ||||
| 	if (time) { | ||||
| 		wlr_relative_pointer_manager_v1_send_relative_motion( | ||||
| @@ -1855,17 +1871,6 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* Find the client under the pointer and send the event along. */ | ||||
| 	xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); | ||||
|  | ||||
| 	if (cursor_mode == CurPressed && !seat->drag && surface != held_grab | ||||
| 			&& toplevel_from_wlr_surface(held_grab, &w, &l) >= 0) { | ||||
| 		c = w; | ||||
| 		surface = held_grab; | ||||
| 		sx = cursor->x - (l ? l->geom.x : w->geom.x); | ||||
| 		sy = cursor->y - (l ? l->geom.y : w->geom.y); | ||||
| 	} | ||||
|  | ||||
| 	/* 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 | ||||
| 	 * off of a client or over its border. */ | ||||
| @@ -1942,6 +1947,10 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) | ||||
| 		Monitor *m = wlr_output->data; | ||||
| 		struct wlr_output_state state; | ||||
|  | ||||
| 		/* Ensure displays previously disabled by wlr-output-power-management-v1 | ||||
| 		 * are properly handled*/ | ||||
| 		m->asleep = 0; | ||||
|  | ||||
| 		wlr_output_state_init(&state); | ||||
| 		wlr_output_state_set_enabled(&state, config_head->state.enabled); | ||||
| 		if (!config_head->state.enabled) | ||||
| @@ -1955,11 +1964,6 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) | ||||
| 					config_head->state.custom_mode.height, | ||||
| 					config_head->state.custom_mode.refresh); | ||||
|  | ||||
| 		/* Don't move monitors if position wouldn't change, this to avoid | ||||
| 		 * wlroots marking the output as manually configured */ | ||||
| 		if (m->m.x != config_head->state.x || m->m.y != config_head->state.y) | ||||
| 			wlr_output_layout_add(output_layout, wlr_output, | ||||
| 					config_head->state.x, config_head->state.y); | ||||
| 		wlr_output_state_set_transform(&state, config_head->state.transform); | ||||
| 		wlr_output_state_set_scale(&state, config_head->state.scale); | ||||
| 		wlr_output_state_set_adaptive_sync_enabled(&state, | ||||
| @@ -1969,6 +1973,13 @@ apply_or_test: | ||||
| 		ok &= test ? wlr_output_test_state(wlr_output, &state) | ||||
| 				: wlr_output_commit_state(wlr_output, &state); | ||||
|  | ||||
| 		/* Don't move monitors if position wouldn't change, this to avoid | ||||
| 		* wlroots marking the output as manually configured. | ||||
| 		* wlr_output_layout_add does not like disabled outputs */ | ||||
| 		if (!test && wlr_output->enabled && (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) | ||||
| 			wlr_output_layout_add(output_layout, wlr_output, | ||||
| 					config_head->state.x, config_head->state.y); | ||||
|  | ||||
| 		wlr_output_state_finish(&state); | ||||
| 	} | ||||
|  | ||||
| @@ -2058,6 +2069,21 @@ printstatus(void) | ||||
| 	fflush(stdout); | ||||
| } | ||||
|  | ||||
| void | ||||
| powermgrsetmode(struct wl_listener *listener, void *data) | ||||
| { | ||||
| 	struct wlr_output_power_v1_set_mode_event *event = data; | ||||
| 	struct wlr_output_state state = {0}; | ||||
|  | ||||
| 	if (!event->output->data) | ||||
| 		return; | ||||
|  | ||||
| 	wlr_output_state_set_enabled(&state, event->mode); | ||||
| 	wlr_output_commit_state(event->output, &state); | ||||
|  | ||||
| 	((Monitor *)(event->output->data))->asleep = !event->mode; | ||||
| } | ||||
|  | ||||
| void | ||||
| quit(const Arg *arg) | ||||
| { | ||||
| @@ -2148,8 +2174,14 @@ requestmonstate(struct wl_listener *listener, void *data) | ||||
| void | ||||
| resize(Client *c, struct wlr_box geo, int interact) | ||||
| { | ||||
| 	struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; | ||||
| 	struct wlr_box *bbox; | ||||
| 	struct wlr_box clip; | ||||
|  | ||||
| 	if (!c->mon) | ||||
| 		return; | ||||
|  | ||||
| 	bbox = interact ? &sgeom : &c->mon->w; | ||||
|  | ||||
| 	client_set_bounds(c, geo.width, geo.height); | ||||
| 	c->geom = geo; | ||||
| 	applybounds(c, bbox); | ||||
| @@ -2194,6 +2226,7 @@ run(char *startup_cmd) | ||||
| 		if ((child_pid = fork()) < 0) | ||||
| 			die("startup: fork:"); | ||||
| 		if (child_pid == 0) { | ||||
| 			setsid(); | ||||
| 			dup2(piperw[0], STDIN_FILENO); | ||||
| 			close(piperw[0]); | ||||
| 			close(piperw[1]); | ||||
| @@ -2467,6 +2500,9 @@ setup(void) | ||||
| 	gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); | ||||
| 	LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); | ||||
|  | ||||
| 	power_mgr = wlr_output_power_manager_v1_create(dpy); | ||||
| 	LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); | ||||
|  | ||||
| 	/* Creates an output layout, which a wlroots utility for working with an | ||||
| 	 * arrangement of screens in a physical layout. */ | ||||
| 	output_layout = wlr_output_layout_create(dpy); | ||||
| @@ -2785,7 +2821,7 @@ updatemons(struct wl_listener *listener, void *data) | ||||
|  | ||||
| 	/* First remove from the layout the disabled monitors */ | ||||
| 	wl_list_for_each(m, &mons, link) { | ||||
| 		if (m->wlr_output->enabled) | ||||
| 		if (m->wlr_output->enabled || m->asleep) | ||||
| 			continue; | ||||
| 		config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); | ||||
| 		config_head->state.enabled = 0; | ||||
| @@ -2844,6 +2880,10 @@ updatemons(struct wl_listener *listener, void *data) | ||||
|  | ||||
| 		config_head->state.x = m->m.x; | ||||
| 		config_head->state.y = m->m.y; | ||||
|  | ||||
| 		if (!selmon) { | ||||
| 			selmon = m; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (selmon && selmon->wlr_output->enabled) { | ||||
|   | ||||
							
								
								
									
										128
									
								
								protocols/wlr-output-power-management-unstable-v1.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								protocols/wlr-output-power-management-unstable-v1.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <protocol name="wlr_output_power_management_unstable_v1"> | ||||
|   <copyright> | ||||
|     Copyright © 2019 Purism SPC | ||||
|  | ||||
|     Permission is hereby granted, free of charge, to any person obtaining a | ||||
|     copy of this software and associated documentation files (the "Software"), | ||||
|     to deal in the Software without restriction, including without limitation | ||||
|     the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|     and/or sell copies of the Software, and to permit persons to whom the | ||||
|     Software is furnished to do so, subject to the following conditions: | ||||
|  | ||||
|     The above copyright notice and this permission notice (including the next | ||||
|     paragraph) shall be included in all copies or substantial portions of the | ||||
|     Software. | ||||
|  | ||||
|     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
|     DEALINGS IN THE SOFTWARE. | ||||
|   </copyright> | ||||
|  | ||||
|   <description summary="Control power management modes of outputs"> | ||||
|     This protocol allows clients to control power management modes | ||||
|     of outputs that are currently part of the compositor space. The | ||||
|     intent is to allow special clients like desktop shells to power | ||||
|     down outputs when the system is idle. | ||||
|  | ||||
|     To modify outputs not currently part of the compositor space see | ||||
|     wlr-output-management. | ||||
|  | ||||
|     Warning! The protocol described in this file is experimental and | ||||
|     backward incompatible changes may be made. Backward compatible changes | ||||
|     may be added together with the corresponding interface version bump. | ||||
|     Backward incompatible changes are done by bumping the version number in | ||||
|     the protocol and interface names and resetting the interface version. | ||||
|     Once the protocol is to be declared stable, the 'z' prefix and the | ||||
|     version number in the protocol and interface names are removed and the | ||||
|     interface version number is reset. | ||||
|   </description> | ||||
|  | ||||
|   <interface name="zwlr_output_power_manager_v1" version="1"> | ||||
|     <description summary="manager to create per-output power management"> | ||||
|       This interface is a manager that allows creating per-output power | ||||
|       management mode controls. | ||||
|     </description> | ||||
|  | ||||
|     <request name="get_output_power"> | ||||
|       <description summary="get a power management for an output"> | ||||
|         Create a output power management mode control that can be used to | ||||
|         adjust the power management mode for a given output. | ||||
|       </description> | ||||
|       <arg name="id" type="new_id" interface="zwlr_output_power_v1"/> | ||||
|       <arg name="output" type="object" interface="wl_output"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy the manager"> | ||||
|         All objects created by the manager will still remain valid, until their | ||||
|         appropriate destroy request has been called. | ||||
|       </description> | ||||
|     </request> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="zwlr_output_power_v1" version="1"> | ||||
|     <description summary="adjust power management mode for an output"> | ||||
|       This object offers requests to set the power management mode of | ||||
|       an output. | ||||
|     </description> | ||||
|  | ||||
|     <enum name="mode"> | ||||
|       <entry name="off" value="0" | ||||
|              summary="Output is turned off."/> | ||||
|       <entry name="on" value="1" | ||||
|              summary="Output is turned on, no power saving"/> | ||||
|     </enum> | ||||
|  | ||||
|     <enum name="error"> | ||||
|       <entry name="invalid_mode" value="1" summary="inexistent power save mode"/> | ||||
|     </enum> | ||||
|  | ||||
|     <request name="set_mode"> | ||||
|       <description summary="Set an outputs power save mode"> | ||||
|         Set an output's power save mode to the given mode. The mode change | ||||
|         is effective immediately. If the output does not support the given | ||||
|         mode a failed event is sent. | ||||
|       </description> | ||||
|       <arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/> | ||||
|     </request> | ||||
|  | ||||
|     <event name="mode"> | ||||
|       <description summary="Report a power management mode change"> | ||||
|         Report the power management mode change of an output. | ||||
|  | ||||
|         The mode event is sent after an output changed its power | ||||
|         management mode. The reason can be a client using set_mode or the | ||||
|         compositor deciding to change an output's mode. | ||||
|         This event is also sent immediately when the object is created | ||||
|         so the client is informed about the current power management mode. | ||||
|       </description> | ||||
|       <arg name="mode" type="uint" enum="mode" | ||||
|            summary="the output's new power management mode"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="failed"> | ||||
|       <description summary="object no longer valid"> | ||||
|         This event indicates that the output power management mode control | ||||
|         is no longer valid. This can happen for a number of reasons, | ||||
|         including: | ||||
|         - The output doesn't support power management | ||||
|         - Another client already has exclusive power management mode control | ||||
|           for this output | ||||
|         - The output disappeared | ||||
|  | ||||
|         Upon receiving this event, the client should destroy this object. | ||||
|       </description> | ||||
|     </event> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy this power management"> | ||||
|         Destroys the output power management mode control object. | ||||
|       </description> | ||||
|     </request> | ||||
|   </interface> | ||||
| </protocol> | ||||
		Reference in New Issue
	
	Block a user