Merge pull request #814 from fwSmit/wayland-improvements
Wayland improvements
This commit is contained in:
		
						commit
						3acffdb194
					
				
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @ -148,7 +148,8 @@ service-systemd: | ||||
| endif | ||||
| 
 | ||||
| ifneq (0,${WAYLAND}) | ||||
| wayland-protocols: src/wayland/protocols/wlr-layer-shell-unstable-v1.xml | ||||
| wayland-protocols: src/wayland/protocols/wlr-layer-shell-unstable-v1.xml src/wayland/protocols/wlr-foreign-toplevel-management-unstable-v1.xml | ||||
| 	# TODO: write this shorter | ||||
| 	mkdir -p src/wayland/protocols | ||||
| 	wayland-scanner private-code ${DATA_DIR_WAYLAND_PROTOCOLS}/stable/xdg-shell/xdg-shell.xml src/wayland/protocols/xdg-shell.h | ||||
| 	wayland-scanner client-header ${DATA_DIR_WAYLAND_PROTOCOLS}/stable/xdg-shell/xdg-shell.xml src/wayland/protocols/xdg-shell-client-header.h | ||||
| @ -158,6 +159,8 @@ wayland-protocols: src/wayland/protocols/wlr-layer-shell-unstable-v1.xml | ||||
| 	wayland-scanner private-code src/wayland/protocols/wlr-layer-shell-unstable-v1.xml src/wayland/protocols/wlr-layer-shell-unstable-v1.h | ||||
| 	wayland-scanner client-header src/wayland/protocols/idle.xml src/wayland/protocols/idle-client-header.h | ||||
| 	wayland-scanner private-code src/wayland/protocols/idle.xml src/wayland/protocols/idle.h | ||||
| 	wayland-scanner client-header src/wayland/protocols/wlr-foreign-toplevel-management-unstable-v1.xml src/wayland/protocols/wlr-foreign-toplevel-management-unstable-v1-client-header.h | ||||
| 	wayland-scanner private-code src/wayland/protocols/wlr-foreign-toplevel-management-unstable-v1.xml src/wayland/protocols/wlr-foreign-toplevel-management-unstable-v1.h | ||||
| endif | ||||
| 
 | ||||
| .PHONY: clean clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run clean-wayland-protocols | ||||
|  | ||||
| @ -249,9 +249,6 @@ Place dunst notifications on the selected layer. Using overlay | ||||
| will cause notifications to be displayed above fullscreen windows, though | ||||
| this may also occur at top depending on your compositor. | ||||
| 
 | ||||
| In Wayland, Notifications won't be delayed when in fullscreen (like when | ||||
| setting B<fullscreen> to pushback in X11). This is a Wayland limitation. | ||||
| 
 | ||||
| The bottom layer is below all windows and above the background. | ||||
| 
 | ||||
| Default: overlay | ||||
| @ -516,7 +513,8 @@ automatically lowered to half of the notification height if it exceeds it. | ||||
| 
 | ||||
| =item B<mouse_left/middle/right_click> (values: [none/do_action/close_current/close_all]) | ||||
| 
 | ||||
| Defines action of mouse click. | ||||
| Defines action of mouse click. A touch input in Wayland acts as a mouse left | ||||
| click. | ||||
| 
 | ||||
| =over 4 | ||||
| 
 | ||||
| @ -662,9 +660,15 @@ Dunst has Wayland support since version 1.6.0. Because the Wayland protocol | ||||
| is more focused on security, some things that are possible in X11 are not | ||||
| possible in Wayland. Those differences are reflected in the configuration. | ||||
| The main things that change are that dunst on Wayland cannot use global | ||||
| hotkeys (they are deprecated anyways, use dunstctl) and it cannot detect | ||||
| if an application is fullscreen. If you want to see notifications when in | ||||
| fullscreen, set B<layer = overlay> in the global options. | ||||
| hotkeys (they are deprecated anyways, use dunstctl). | ||||
| 
 | ||||
| Some dunst features on wayland might need your compositor to support a certain | ||||
| protocol. Dunst will warn you if an optional feature isn't supported and will | ||||
| disable the corresponding functionality. | ||||
| 
 | ||||
| Fullscreen detection works on wayland with some limitations (see B<fullscreen>). | ||||
| If you want notifications to appear over fullscreen windows, set | ||||
| B<layer = overlay> in the global options. | ||||
| 
 | ||||
| Note that the same limitations exist when using xwayland. | ||||
| If something doesn't quite work in Wayland, please file a bug report. In the | ||||
| @ -791,7 +795,7 @@ Equivalent to the C<format> setting. | ||||
| 
 | ||||
| The frame color color of the notification. See COLORS for possible values. | ||||
| 
 | ||||
| =item C<fullscreen> (X11 only) | ||||
| =item C<fullscreen> | ||||
| 
 | ||||
| One of show, delay, or pushback. | ||||
| 
 | ||||
| @ -806,7 +810,13 @@ Or pushback which is equivalent to delay with the difference that already | ||||
| existing notifications are paused and hidden until the focus to the fullscreen | ||||
| window is lost. | ||||
| 
 | ||||
| See B<layer> to change fullscreen behavior in Wayland | ||||
| On wayland, if B<follow> is set to mouse or keyboard, the output where the | ||||
| notification is located cannot be determined. So dunst will delay or pushback if | ||||
| any of the outputs is fullscreen. Since the fullscreen protocol is fairly new, | ||||
| you will need a recent version of a compositor that supports it. At the time of | ||||
| writing, you will need the git version of sway. | ||||
| See also B<layer> to change if notifications appear above fullscreen windows in | ||||
| Wayland. | ||||
| 
 | ||||
| Default: show | ||||
| 
 | ||||
|  | ||||
| @ -25,6 +25,10 @@ void input_handle_click(unsigned int button, bool button_down, int mouse_x, int | ||||
|                 case BTN_RIGHT: | ||||
|                         acts = settings.mouse_right_click; | ||||
|                         break; | ||||
|                 case BTN_TOUCH: | ||||
|                         // TODO Add separate action for touch
 | ||||
|                         acts = settings.mouse_left_click; | ||||
|                         break; | ||||
|                 default: | ||||
|                         LOG_W("Unsupported mouse button: '%d'", button); | ||||
|                         return; | ||||
|  | ||||
| @ -0,0 +1,611 @@ | ||||
| /* Generated by wayland-scanner 1.18.0 */ | ||||
| 
 | ||||
| #ifndef WLR_FOREIGN_TOPLEVEL_MANAGEMENT_UNSTABLE_V1_CLIENT_PROTOCOL_H | ||||
| #define WLR_FOREIGN_TOPLEVEL_MANAGEMENT_UNSTABLE_V1_CLIENT_PROTOCOL_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
| #include "wayland-client.h" | ||||
| 
 | ||||
| #ifdef  __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * @page page_wlr_foreign_toplevel_management_unstable_v1 The wlr_foreign_toplevel_management_unstable_v1 protocol | ||||
|  * @section page_ifaces_wlr_foreign_toplevel_management_unstable_v1 Interfaces | ||||
|  * - @subpage page_iface_zwlr_foreign_toplevel_manager_v1 - list and control opened apps | ||||
|  * - @subpage page_iface_zwlr_foreign_toplevel_handle_v1 - an opened toplevel | ||||
|  * @section page_copyright_wlr_foreign_toplevel_management_unstable_v1 Copyright | ||||
|  * <pre> | ||||
|  * | ||||
|  * Copyright © 2018 Ilia Bozhinov | ||||
|  * | ||||
|  * Permission to use, copy, modify, distribute, and sell this | ||||
|  * software and its documentation for any purpose is hereby granted | ||||
|  * without fee, provided that the above copyright notice appear in | ||||
|  * all copies and that both that copyright notice and this permission | ||||
|  * notice appear in supporting documentation, and that the name of | ||||
|  * the copyright holders not be used in advertising or publicity | ||||
|  * pertaining to distribution of the software without specific, | ||||
|  * written prior permission.  The copyright holders make no | ||||
|  * representations about the suitability of this software for any | ||||
|  * purpose.  It is provided "as is" without express or implied | ||||
|  * warranty. | ||||
|  * | ||||
|  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | ||||
|  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||
|  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||||
|  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||
|  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||||
|  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||||
|  * THIS SOFTWARE. | ||||
|  * </pre> | ||||
|  */ | ||||
| struct wl_output; | ||||
| struct wl_seat; | ||||
| struct wl_surface; | ||||
| struct zwlr_foreign_toplevel_handle_v1; | ||||
| struct zwlr_foreign_toplevel_manager_v1; | ||||
| 
 | ||||
| /**
 | ||||
|  * @page page_iface_zwlr_foreign_toplevel_manager_v1 zwlr_foreign_toplevel_manager_v1 | ||||
|  * @section page_iface_zwlr_foreign_toplevel_manager_v1_desc Description | ||||
|  * | ||||
|  * The purpose of this protocol is to enable the creation of taskbars | ||||
|  * and docks by providing them with a list of opened applications and | ||||
|  * letting them request certain actions on them, like maximizing, etc. | ||||
|  * | ||||
|  * After a client binds the zwlr_foreign_toplevel_manager_v1, each opened | ||||
|  * toplevel window will be sent via the toplevel event | ||||
|  * @section page_iface_zwlr_foreign_toplevel_manager_v1_api API | ||||
|  * See @ref iface_zwlr_foreign_toplevel_manager_v1. | ||||
|  */ | ||||
| /**
 | ||||
|  * @defgroup iface_zwlr_foreign_toplevel_manager_v1 The zwlr_foreign_toplevel_manager_v1 interface | ||||
|  * | ||||
|  * The purpose of this protocol is to enable the creation of taskbars | ||||
|  * and docks by providing them with a list of opened applications and | ||||
|  * letting them request certain actions on them, like maximizing, etc. | ||||
|  * | ||||
|  * After a client binds the zwlr_foreign_toplevel_manager_v1, each opened | ||||
|  * toplevel window will be sent via the toplevel event | ||||
|  */ | ||||
| extern const struct wl_interface zwlr_foreign_toplevel_manager_v1_interface; | ||||
| /**
 | ||||
|  * @page page_iface_zwlr_foreign_toplevel_handle_v1 zwlr_foreign_toplevel_handle_v1 | ||||
|  * @section page_iface_zwlr_foreign_toplevel_handle_v1_desc Description | ||||
|  * | ||||
|  * A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel | ||||
|  * window. Each app may have multiple opened toplevels. | ||||
|  * | ||||
|  * Each toplevel has a list of outputs it is visible on, conveyed to the | ||||
|  * client with the output_enter and output_leave events. | ||||
|  * @section page_iface_zwlr_foreign_toplevel_handle_v1_api API | ||||
|  * See @ref iface_zwlr_foreign_toplevel_handle_v1. | ||||
|  */ | ||||
| /**
 | ||||
|  * @defgroup iface_zwlr_foreign_toplevel_handle_v1 The zwlr_foreign_toplevel_handle_v1 interface | ||||
|  * | ||||
|  * A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel | ||||
|  * window. Each app may have multiple opened toplevels. | ||||
|  * | ||||
|  * Each toplevel has a list of outputs it is visible on, conveyed to the | ||||
|  * client with the output_enter and output_leave events. | ||||
|  */ | ||||
| extern const struct wl_interface zwlr_foreign_toplevel_handle_v1_interface; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_manager_v1 | ||||
|  * @struct zwlr_foreign_toplevel_manager_v1_listener | ||||
|  */ | ||||
| struct zwlr_foreign_toplevel_manager_v1_listener { | ||||
| 	/**
 | ||||
| 	 * a toplevel has been created | ||||
| 	 * | ||||
| 	 * This event is emitted whenever a new toplevel window is | ||||
| 	 * created. It is emitted for all toplevels, regardless of the app | ||||
| 	 * that has created them. | ||||
| 	 * | ||||
| 	 * All initial details of the toplevel(title, app_id, states, etc.) | ||||
| 	 * will be sent immediately after this event via the corresponding | ||||
| 	 * events in zwlr_foreign_toplevel_handle_v1. | ||||
| 	 */ | ||||
| 	void (*toplevel)(void *data, | ||||
| 			 struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1, | ||||
| 			 struct zwlr_foreign_toplevel_handle_v1 *toplevel); | ||||
| 	/**
 | ||||
| 	 * the compositor has finished with the toplevel manager | ||||
| 	 * | ||||
| 	 * This event indicates that the compositor is done sending | ||||
| 	 * events to the zwlr_foreign_toplevel_manager_v1. The server will | ||||
| 	 * destroy the object immediately after sending this request, so it | ||||
| 	 * will become invalid and the client should free any resources | ||||
| 	 * associated with it. | ||||
| 	 */ | ||||
| 	void (*finished)(void *data, | ||||
| 			 struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1); | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_manager_v1 | ||||
|  */ | ||||
| static inline int | ||||
| zwlr_foreign_toplevel_manager_v1_add_listener(struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1, | ||||
| 					      const struct zwlr_foreign_toplevel_manager_v1_listener *listener, void *data) | ||||
| { | ||||
| 	return wl_proxy_add_listener((struct wl_proxy *) zwlr_foreign_toplevel_manager_v1, | ||||
| 				     (void (**)(void)) listener, data); | ||||
| } | ||||
| 
 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_MANAGER_V1_STOP 0 | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_manager_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_MANAGER_V1_TOPLEVEL_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_manager_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_MANAGER_V1_FINISHED_SINCE_VERSION 1 | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_manager_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_MANAGER_V1_STOP_SINCE_VERSION 1 | ||||
| 
 | ||||
| /** @ingroup iface_zwlr_foreign_toplevel_manager_v1 */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_manager_v1_set_user_data(struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1, void *user_data) | ||||
| { | ||||
| 	wl_proxy_set_user_data((struct wl_proxy *) zwlr_foreign_toplevel_manager_v1, user_data); | ||||
| } | ||||
| 
 | ||||
| /** @ingroup iface_zwlr_foreign_toplevel_manager_v1 */ | ||||
| static inline void * | ||||
| zwlr_foreign_toplevel_manager_v1_get_user_data(struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1) | ||||
| { | ||||
| 	return wl_proxy_get_user_data((struct wl_proxy *) zwlr_foreign_toplevel_manager_v1); | ||||
| } | ||||
| 
 | ||||
| static inline uint32_t | ||||
| zwlr_foreign_toplevel_manager_v1_get_version(struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1) | ||||
| { | ||||
| 	return wl_proxy_get_version((struct wl_proxy *) zwlr_foreign_toplevel_manager_v1); | ||||
| } | ||||
| 
 | ||||
| /** @ingroup iface_zwlr_foreign_toplevel_manager_v1 */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_manager_v1_destroy(struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1) | ||||
| { | ||||
| 	wl_proxy_destroy((struct wl_proxy *) zwlr_foreign_toplevel_manager_v1); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_manager_v1 | ||||
|  * | ||||
|  * Indicates the client no longer wishes to receive events for new toplevels. | ||||
|  * However the compositor may emit further toplevel_created events, until | ||||
|  * the finished event is emitted. | ||||
|  * | ||||
|  * The client must not send any more requests after this one. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_manager_v1_stop(struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_manager_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_MANAGER_V1_STOP); | ||||
| } | ||||
| 
 | ||||
| #ifndef ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ENUM | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ENUM | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * types of states on the toplevel | ||||
|  * | ||||
|  * The different states that a toplevel can have. These have the same meaning | ||||
|  * as the states with the same names defined in xdg-toplevel | ||||
|  */ | ||||
| enum zwlr_foreign_toplevel_handle_v1_state { | ||||
| 	/**
 | ||||
| 	 * the toplevel is maximized | ||||
| 	 */ | ||||
| 	ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED = 0, | ||||
| 	/**
 | ||||
| 	 * the toplevel is minimized | ||||
| 	 */ | ||||
| 	ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED = 1, | ||||
| 	/**
 | ||||
| 	 * the toplevel is active | ||||
| 	 */ | ||||
| 	ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED = 2, | ||||
| 	/**
 | ||||
| 	 * the toplevel is fullscreen | ||||
| 	 * @since 2 | ||||
| 	 */ | ||||
| 	ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN = 3, | ||||
| }; | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN_SINCE_VERSION 2 | ||||
| #endif /* ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ENUM */ | ||||
| 
 | ||||
| #ifndef ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ERROR_ENUM | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ERROR_ENUM | ||||
| enum zwlr_foreign_toplevel_handle_v1_error { | ||||
| 	/**
 | ||||
| 	 * the provided rectangle is invalid | ||||
| 	 */ | ||||
| 	ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ERROR_INVALID_RECTANGLE = 0, | ||||
| }; | ||||
| #endif /* ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ERROR_ENUM */ | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * @struct zwlr_foreign_toplevel_handle_v1_listener | ||||
|  */ | ||||
| struct zwlr_foreign_toplevel_handle_v1_listener { | ||||
| 	/**
 | ||||
| 	 * title change | ||||
| 	 * | ||||
| 	 * This event is emitted whenever the title of the toplevel | ||||
| 	 * changes. | ||||
| 	 */ | ||||
| 	void (*title)(void *data, | ||||
| 		      struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 		      const char *title); | ||||
| 	/**
 | ||||
| 	 * app-id change | ||||
| 	 * | ||||
| 	 * This event is emitted whenever the app-id of the toplevel | ||||
| 	 * changes. | ||||
| 	 */ | ||||
| 	void (*app_id)(void *data, | ||||
| 		       struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 		       const char *app_id); | ||||
| 	/**
 | ||||
| 	 * toplevel entered an output | ||||
| 	 * | ||||
| 	 * This event is emitted whenever the toplevel becomes visible on | ||||
| 	 * the given output. A toplevel may be visible on multiple outputs. | ||||
| 	 */ | ||||
| 	void (*output_enter)(void *data, | ||||
| 			     struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 			     struct wl_output *output); | ||||
| 	/**
 | ||||
| 	 * toplevel left an output | ||||
| 	 * | ||||
| 	 * This event is emitted whenever the toplevel stops being | ||||
| 	 * visible on the given output. It is guaranteed that an | ||||
| 	 * entered-output event with the same output has been emitted | ||||
| 	 * before this event. | ||||
| 	 */ | ||||
| 	void (*output_leave)(void *data, | ||||
| 			     struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 			     struct wl_output *output); | ||||
| 	/**
 | ||||
| 	 * the toplevel state changed | ||||
| 	 * | ||||
| 	 * This event is emitted immediately after the | ||||
| 	 * zlw_foreign_toplevel_handle_v1 is created and each time the | ||||
| 	 * toplevel state changes, either because of a compositor action or | ||||
| 	 * because of a request in this protocol. | ||||
| 	 */ | ||||
| 	void (*state)(void *data, | ||||
| 		      struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 		      struct wl_array *state); | ||||
| 	/**
 | ||||
| 	 * all information about the toplevel has been sent | ||||
| 	 * | ||||
| 	 * This event is sent after all changes in the toplevel state | ||||
| 	 * have been sent. | ||||
| 	 * | ||||
| 	 * This allows changes to the zwlr_foreign_toplevel_handle_v1 | ||||
| 	 * properties to be seen as atomic, even if they happen via | ||||
| 	 * multiple events. | ||||
| 	 */ | ||||
| 	void (*done)(void *data, | ||||
| 		     struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1); | ||||
| 	/**
 | ||||
| 	 * this toplevel has been destroyed | ||||
| 	 * | ||||
| 	 * This event means the toplevel has been destroyed. It is | ||||
| 	 * guaranteed there won't be any more events for this | ||||
| 	 * zwlr_foreign_toplevel_handle_v1. The toplevel itself becomes | ||||
| 	 * inert so any requests will be ignored except the destroy | ||||
| 	 * request. | ||||
| 	 */ | ||||
| 	void (*closed)(void *data, | ||||
| 		       struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1); | ||||
| 	/**
 | ||||
| 	 * parent change | ||||
| 	 * | ||||
| 	 * This event is emitted whenever the parent of the toplevel | ||||
| 	 * changes. | ||||
| 	 * | ||||
| 	 * No event is emitted when the parent handle is destroyed by the | ||||
| 	 * client. | ||||
| 	 * @since 3 | ||||
| 	 */ | ||||
| 	void (*parent)(void *data, | ||||
| 		       struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 		       struct zwlr_foreign_toplevel_handle_v1 *parent); | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| static inline int | ||||
| zwlr_foreign_toplevel_handle_v1_add_listener(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, | ||||
| 					     const struct zwlr_foreign_toplevel_handle_v1_listener *listener, void *data) | ||||
| { | ||||
| 	return wl_proxy_add_listener((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 				     (void (**)(void)) listener, data); | ||||
| } | ||||
| 
 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_MAXIMIZED 0 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_MAXIMIZED 1 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_MINIMIZED 2 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_MINIMIZED 3 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ACTIVATE 4 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_CLOSE 5 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_RECTANGLE 6 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_DESTROY 7 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_FULLSCREEN 8 | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_FULLSCREEN 9 | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_TITLE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_APP_ID_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_OUTPUT_ENTER_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_OUTPUT_LEAVE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_DONE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_CLOSED_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_PARENT_SINCE_VERSION 3 | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_MAXIMIZED_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_MAXIMIZED_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_MINIMIZED_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_MINIMIZED_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ACTIVATE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_CLOSE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_RECTANGLE_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_DESTROY_SINCE_VERSION 1 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_FULLSCREEN_SINCE_VERSION 2 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  */ | ||||
| #define ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_FULLSCREEN_SINCE_VERSION 2 | ||||
| 
 | ||||
| /** @ingroup iface_zwlr_foreign_toplevel_handle_v1 */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_set_user_data(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, void *user_data) | ||||
| { | ||||
| 	wl_proxy_set_user_data((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, user_data); | ||||
| } | ||||
| 
 | ||||
| /** @ingroup iface_zwlr_foreign_toplevel_handle_v1 */ | ||||
| static inline void * | ||||
| zwlr_foreign_toplevel_handle_v1_get_user_data(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	return wl_proxy_get_user_data((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1); | ||||
| } | ||||
| 
 | ||||
| static inline uint32_t | ||||
| zwlr_foreign_toplevel_handle_v1_get_version(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	return wl_proxy_get_version((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Requests that the toplevel be maximized. If the maximized state actually | ||||
|  * changes, this will be indicated by the state event. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_set_maximized(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_MAXIMIZED); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Requests that the toplevel be unmaximized. If the maximized state actually | ||||
|  * changes, this will be indicated by the state event. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_unset_maximized(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_MAXIMIZED); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Requests that the toplevel be minimized. If the minimized state actually | ||||
|  * changes, this will be indicated by the state event. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_set_minimized(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_MINIMIZED); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Requests that the toplevel be unminimized. If the minimized state actually | ||||
|  * changes, this will be indicated by the state event. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_unset_minimized(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_MINIMIZED); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Request that this toplevel be activated on the given seat. | ||||
|  * There is no guarantee the toplevel will be actually activated. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_activate(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, struct wl_seat *seat) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ACTIVATE, seat); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Send a request to the toplevel to close itself. The compositor would | ||||
|  * typically use a shell-specific method to carry out this request, for | ||||
|  * example by sending the xdg_toplevel.close event. However, this gives | ||||
|  * no guarantees the toplevel will actually be destroyed. If and when | ||||
|  * this happens, the zwlr_foreign_toplevel_handle_v1.closed event will | ||||
|  * be emitted. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_close(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_CLOSE); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * The rectangle of the surface specified in this request corresponds to | ||||
|  * the place where the app using this protocol represents the given toplevel. | ||||
|  * It can be used by the compositor as a hint for some operations, e.g | ||||
|  * minimizing. The client is however not required to set this, in which | ||||
|  * case the compositor is free to decide some default value. | ||||
|  * | ||||
|  * If the client specifies more than one rectangle, only the last one is | ||||
|  * considered. | ||||
|  * | ||||
|  * The dimensions are given in surface-local coordinates. | ||||
|  * Setting width=height=0 removes the already-set rectangle. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_set_rectangle(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, struct wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_RECTANGLE, surface, x, y, width, height); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Destroys the zwlr_foreign_toplevel_handle_v1 object. | ||||
|  * | ||||
|  * This request should be called either when the client does not want to | ||||
|  * use the toplevel anymore or after the closed event to finalize the | ||||
|  * destruction of the object. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_destroy(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_DESTROY); | ||||
| 
 | ||||
| 	wl_proxy_destroy((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Requests that the toplevel be fullscreened on the given output. If the | ||||
|  * fullscreen state and/or the outputs the toplevel is visible on actually | ||||
|  * change, this will be indicated by the state and output_enter/leave | ||||
|  * events. | ||||
|  * | ||||
|  * The output parameter is only a hint to the compositor. Also, if output | ||||
|  * is NULL, the compositor should decide which output the toplevel will be | ||||
|  * fullscreened on, if at all. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_set_fullscreen(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1, struct wl_output *output) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_SET_FULLSCREEN, output); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup iface_zwlr_foreign_toplevel_handle_v1 | ||||
|  * | ||||
|  * Requests that the toplevel be unfullscreened. If the fullscreen state | ||||
|  * actually changes, this will be indicated by the state event. | ||||
|  */ | ||||
| static inline void | ||||
| zwlr_foreign_toplevel_handle_v1_unset_fullscreen(struct zwlr_foreign_toplevel_handle_v1 *zwlr_foreign_toplevel_handle_v1) | ||||
| { | ||||
| 	wl_proxy_marshal((struct wl_proxy *) zwlr_foreign_toplevel_handle_v1, | ||||
| 			 ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_UNSET_FULLSCREEN); | ||||
| } | ||||
| 
 | ||||
| #ifdef  __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,106 @@ | ||||
| /* Generated by wayland-scanner 1.18.0 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Copyright © 2018 Ilia Bozhinov | ||||
|  * | ||||
|  * Permission to use, copy, modify, distribute, and sell this | ||||
|  * software and its documentation for any purpose is hereby granted | ||||
|  * without fee, provided that the above copyright notice appear in | ||||
|  * all copies and that both that copyright notice and this permission | ||||
|  * notice appear in supporting documentation, and that the name of | ||||
|  * the copyright holders not be used in advertising or publicity | ||||
|  * pertaining to distribution of the software without specific, | ||||
|  * written prior permission.  The copyright holders make no | ||||
|  * representations about the suitability of this software for any | ||||
|  * purpose.  It is provided "as is" without express or implied | ||||
|  * warranty. | ||||
|  * | ||||
|  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | ||||
|  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||
|  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||||
|  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||
|  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||||
|  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||||
|  * THIS SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include "wayland-util.h" | ||||
| 
 | ||||
| #ifndef __has_attribute | ||||
| # define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */ | ||||
| #endif | ||||
| 
 | ||||
| #if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) | ||||
| #define WL_PRIVATE __attribute__ ((visibility("hidden"))) | ||||
| #else | ||||
| #define WL_PRIVATE | ||||
| #endif | ||||
| 
 | ||||
| extern const struct wl_interface wl_output_interface; | ||||
| extern const struct wl_interface wl_seat_interface; | ||||
| extern const struct wl_interface wl_surface_interface; | ||||
| extern const struct wl_interface zwlr_foreign_toplevel_handle_v1_interface; | ||||
| 
 | ||||
| static const struct wl_interface *wlr_foreign_toplevel_management_unstable_v1_types[] = { | ||||
| 	NULL, | ||||
| 	&zwlr_foreign_toplevel_handle_v1_interface, | ||||
| 	&wl_seat_interface, | ||||
| 	&wl_surface_interface, | ||||
| 	NULL, | ||||
| 	NULL, | ||||
| 	NULL, | ||||
| 	NULL, | ||||
| 	&wl_output_interface, | ||||
| 	&wl_output_interface, | ||||
| 	&wl_output_interface, | ||||
| 	&zwlr_foreign_toplevel_handle_v1_interface, | ||||
| }; | ||||
| 
 | ||||
| static const struct wl_message zwlr_foreign_toplevel_manager_v1_requests[] = { | ||||
| 	{ "stop", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| }; | ||||
| 
 | ||||
| static const struct wl_message zwlr_foreign_toplevel_manager_v1_events[] = { | ||||
| 	{ "toplevel", "n", wlr_foreign_toplevel_management_unstable_v1_types + 1 }, | ||||
| 	{ "finished", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| }; | ||||
| 
 | ||||
| WL_PRIVATE const struct wl_interface zwlr_foreign_toplevel_manager_v1_interface = { | ||||
| 	"zwlr_foreign_toplevel_manager_v1", 3, | ||||
| 	1, zwlr_foreign_toplevel_manager_v1_requests, | ||||
| 	2, zwlr_foreign_toplevel_manager_v1_events, | ||||
| }; | ||||
| 
 | ||||
| static const struct wl_message zwlr_foreign_toplevel_handle_v1_requests[] = { | ||||
| 	{ "set_maximized", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "unset_maximized", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "set_minimized", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "unset_minimized", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "activate", "o", wlr_foreign_toplevel_management_unstable_v1_types + 2 }, | ||||
| 	{ "close", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "set_rectangle", "oiiii", wlr_foreign_toplevel_management_unstable_v1_types + 3 }, | ||||
| 	{ "destroy", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "set_fullscreen", "2?o", wlr_foreign_toplevel_management_unstable_v1_types + 8 }, | ||||
| 	{ "unset_fullscreen", "2", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| }; | ||||
| 
 | ||||
| static const struct wl_message zwlr_foreign_toplevel_handle_v1_events[] = { | ||||
| 	{ "title", "s", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "app_id", "s", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "output_enter", "o", wlr_foreign_toplevel_management_unstable_v1_types + 9 }, | ||||
| 	{ "output_leave", "o", wlr_foreign_toplevel_management_unstable_v1_types + 10 }, | ||||
| 	{ "state", "a", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "done", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "closed", "", wlr_foreign_toplevel_management_unstable_v1_types + 0 }, | ||||
| 	{ "parent", "3?o", wlr_foreign_toplevel_management_unstable_v1_types + 11 }, | ||||
| }; | ||||
| 
 | ||||
| WL_PRIVATE const struct wl_interface zwlr_foreign_toplevel_handle_v1_interface = { | ||||
| 	"zwlr_foreign_toplevel_handle_v1", 3, | ||||
| 	10, zwlr_foreign_toplevel_handle_v1_requests, | ||||
| 	8, zwlr_foreign_toplevel_handle_v1_events, | ||||
| }; | ||||
| 
 | ||||
| @ -0,0 +1,270 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <protocol name="wlr_foreign_toplevel_management_unstable_v1"> | ||||
|   <copyright> | ||||
|     Copyright © 2018 Ilia Bozhinov | ||||
| 
 | ||||
|     Permission to use, copy, modify, distribute, and sell this | ||||
|     software and its documentation for any purpose is hereby granted | ||||
|     without fee, provided that the above copyright notice appear in | ||||
|     all copies and that both that copyright notice and this permission | ||||
|     notice appear in supporting documentation, and that the name of | ||||
|     the copyright holders not be used in advertising or publicity | ||||
|     pertaining to distribution of the software without specific, | ||||
|     written prior permission.  The copyright holders make no | ||||
|     representations about the suitability of this software for any | ||||
|     purpose.  It is provided "as is" without express or implied | ||||
|     warranty. | ||||
| 
 | ||||
|     THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | ||||
|     SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||
|     FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||||
|     SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||
|     AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||||
|     ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||||
|     THIS SOFTWARE. | ||||
|   </copyright> | ||||
| 
 | ||||
|   <interface name="zwlr_foreign_toplevel_manager_v1" version="3"> | ||||
|     <description summary="list and control opened apps"> | ||||
|       The purpose of this protocol is to enable the creation of taskbars | ||||
|       and docks by providing them with a list of opened applications and | ||||
|       letting them request certain actions on them, like maximizing, etc. | ||||
| 
 | ||||
|       After a client binds the zwlr_foreign_toplevel_manager_v1, each opened | ||||
|       toplevel window will be sent via the toplevel event | ||||
|     </description> | ||||
| 
 | ||||
|     <event name="toplevel"> | ||||
|       <description summary="a toplevel has been created"> | ||||
|         This event is emitted whenever a new toplevel window is created. It | ||||
|         is emitted for all toplevels, regardless of the app that has created | ||||
|         them. | ||||
| 
 | ||||
|         All initial details of the toplevel(title, app_id, states, etc.) will | ||||
|         be sent immediately after this event via the corresponding events in | ||||
|         zwlr_foreign_toplevel_handle_v1. | ||||
|       </description> | ||||
|       <arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/> | ||||
|     </event> | ||||
| 
 | ||||
|     <request name="stop"> | ||||
|       <description summary="stop sending events"> | ||||
|         Indicates the client no longer wishes to receive events for new toplevels. | ||||
|         However the compositor may emit further toplevel_created events, until | ||||
|         the finished event is emitted. | ||||
| 
 | ||||
|         The client must not send any more requests after this one. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <event name="finished"> | ||||
|       <description summary="the compositor has finished with the toplevel manager"> | ||||
|         This event indicates that the compositor is done sending events to the | ||||
|         zwlr_foreign_toplevel_manager_v1. The server will destroy the object | ||||
|         immediately after sending this request, so it will become invalid and | ||||
|         the client should free any resources associated with it. | ||||
|       </description> | ||||
|     </event> | ||||
|   </interface> | ||||
| 
 | ||||
|   <interface name="zwlr_foreign_toplevel_handle_v1" version="3"> | ||||
|     <description summary="an opened toplevel"> | ||||
|       A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel | ||||
|       window. Each app may have multiple opened toplevels. | ||||
| 
 | ||||
|       Each toplevel has a list of outputs it is visible on, conveyed to the | ||||
|       client with the output_enter and output_leave events. | ||||
|     </description> | ||||
| 
 | ||||
|     <event name="title"> | ||||
|       <description summary="title change"> | ||||
|         This event is emitted whenever the title of the toplevel changes. | ||||
|       </description> | ||||
|       <arg name="title" type="string"/> | ||||
|     </event> | ||||
| 
 | ||||
|     <event name="app_id"> | ||||
|       <description summary="app-id change"> | ||||
|         This event is emitted whenever the app-id of the toplevel changes. | ||||
|       </description> | ||||
|       <arg name="app_id" type="string"/> | ||||
|     </event> | ||||
| 
 | ||||
|     <event name="output_enter"> | ||||
|       <description summary="toplevel entered an output"> | ||||
|         This event is emitted whenever the toplevel becomes visible on | ||||
|         the given output. A toplevel may be visible on multiple outputs. | ||||
|       </description> | ||||
|       <arg name="output" type="object" interface="wl_output"/> | ||||
|     </event> | ||||
| 
 | ||||
|     <event name="output_leave"> | ||||
|       <description summary="toplevel left an output"> | ||||
|         This event is emitted whenever the toplevel stops being visible on | ||||
|         the given output. It is guaranteed that an entered-output event | ||||
|         with the same output has been emitted before this event. | ||||
|       </description> | ||||
|       <arg name="output" type="object" interface="wl_output"/> | ||||
|     </event> | ||||
| 
 | ||||
|     <request name="set_maximized"> | ||||
|       <description summary="requests that the toplevel be maximized"> | ||||
|         Requests that the toplevel be maximized. If the maximized state actually | ||||
|         changes, this will be indicated by the state event. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <request name="unset_maximized"> | ||||
|       <description summary="requests that the toplevel be unmaximized"> | ||||
|         Requests that the toplevel be unmaximized. If the maximized state actually | ||||
|         changes, this will be indicated by the state event. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <request name="set_minimized"> | ||||
|       <description summary="requests that the toplevel be minimized"> | ||||
|         Requests that the toplevel be minimized. If the minimized state actually | ||||
|         changes, this will be indicated by the state event. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <request name="unset_minimized"> | ||||
|       <description summary="requests that the toplevel be unminimized"> | ||||
|         Requests that the toplevel be unminimized. If the minimized state actually | ||||
|         changes, this will be indicated by the state event. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <request name="activate"> | ||||
|       <description summary="activate the toplevel"> | ||||
|         Request that this toplevel be activated on the given seat. | ||||
|         There is no guarantee the toplevel will be actually activated. | ||||
|       </description> | ||||
|       <arg name="seat" type="object" interface="wl_seat"/> | ||||
|     </request> | ||||
| 
 | ||||
|     <enum name="state"> | ||||
|       <description summary="types of states on the toplevel"> | ||||
|         The different states that a toplevel can have. These have the same meaning | ||||
|         as the states with the same names defined in xdg-toplevel | ||||
|       </description> | ||||
| 
 | ||||
|       <entry name="maximized"  value="0" summary="the toplevel is maximized"/> | ||||
|       <entry name="minimized"  value="1" summary="the toplevel is minimized"/> | ||||
|       <entry name="activated"  value="2" summary="the toplevel is active"/> | ||||
|       <entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/> | ||||
|     </enum> | ||||
| 
 | ||||
|     <event name="state"> | ||||
|       <description summary="the toplevel state changed"> | ||||
|         This event is emitted immediately after the zlw_foreign_toplevel_handle_v1 | ||||
|         is created and each time the toplevel state changes, either because of a | ||||
|         compositor action or because of a request in this protocol. | ||||
|       </description> | ||||
| 
 | ||||
|       <arg name="state" type="array"/> | ||||
|     </event> | ||||
| 
 | ||||
|     <event name="done"> | ||||
|       <description summary="all information about the toplevel has been sent"> | ||||
|         This event is sent after all changes in the toplevel state have been | ||||
|         sent. | ||||
| 
 | ||||
|         This allows changes to the zwlr_foreign_toplevel_handle_v1 properties | ||||
|         to be seen as atomic, even if they happen via multiple events. | ||||
|       </description> | ||||
|     </event> | ||||
| 
 | ||||
|     <request name="close"> | ||||
|       <description summary="request that the toplevel be closed"> | ||||
|         Send a request to the toplevel to close itself. The compositor would | ||||
|         typically use a shell-specific method to carry out this request, for | ||||
|         example by sending the xdg_toplevel.close event. However, this gives | ||||
|         no guarantees the toplevel will actually be destroyed. If and when | ||||
|         this happens, the zwlr_foreign_toplevel_handle_v1.closed event will | ||||
|         be emitted. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <request name="set_rectangle"> | ||||
|       <description summary="the rectangle which represents the toplevel"> | ||||
|         The rectangle of the surface specified in this request corresponds to | ||||
|         the place where the app using this protocol represents the given toplevel. | ||||
|         It can be used by the compositor as a hint for some operations, e.g | ||||
|         minimizing. The client is however not required to set this, in which | ||||
|         case the compositor is free to decide some default value. | ||||
| 
 | ||||
|         If the client specifies more than one rectangle, only the last one is | ||||
|         considered. | ||||
| 
 | ||||
|         The dimensions are given in surface-local coordinates. | ||||
|         Setting width=height=0 removes the already-set rectangle. | ||||
|       </description> | ||||
| 
 | ||||
|       <arg name="surface" type="object" interface="wl_surface"/> | ||||
|       <arg name="x" type="int"/> | ||||
|       <arg name="y" type="int"/> | ||||
|       <arg name="width" type="int"/> | ||||
|       <arg name="height" type="int"/> | ||||
|     </request> | ||||
| 
 | ||||
|     <enum name="error"> | ||||
|       <entry name="invalid_rectangle" value="0" | ||||
|         summary="the provided rectangle is invalid"/> | ||||
|     </enum> | ||||
| 
 | ||||
|     <event name="closed"> | ||||
|       <description summary="this toplevel has been destroyed"> | ||||
|         This event means the toplevel has been destroyed. It is guaranteed there | ||||
|         won't be any more events for this zwlr_foreign_toplevel_handle_v1. The | ||||
|         toplevel itself becomes inert so any requests will be ignored except the | ||||
|         destroy request. | ||||
|       </description> | ||||
|     </event> | ||||
| 
 | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy the zwlr_foreign_toplevel_handle_v1 object"> | ||||
|         Destroys the zwlr_foreign_toplevel_handle_v1 object. | ||||
| 
 | ||||
|         This request should be called either when the client does not want to | ||||
|         use the toplevel anymore or after the closed event to finalize the | ||||
|         destruction of the object. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <!-- Version 2 additions --> | ||||
| 
 | ||||
|     <request name="set_fullscreen" since="2"> | ||||
|       <description summary="request that the toplevel be fullscreened"> | ||||
|         Requests that the toplevel be fullscreened on the given output. If the | ||||
|         fullscreen state and/or the outputs the toplevel is visible on actually | ||||
|         change, this will be indicated by the state and output_enter/leave | ||||
|         events. | ||||
| 
 | ||||
|         The output parameter is only a hint to the compositor. Also, if output | ||||
|         is NULL, the compositor should decide which output the toplevel will be | ||||
|         fullscreened on, if at all. | ||||
|       </description> | ||||
|       <arg name="output" type="object" interface="wl_output" allow-null="true"/> | ||||
|     </request> | ||||
| 
 | ||||
|     <request name="unset_fullscreen" since="2"> | ||||
|       <description summary="request that the toplevel be unfullscreened"> | ||||
|         Requests that the toplevel be unfullscreened. If the fullscreen state | ||||
|         actually changes, this will be indicated by the state event. | ||||
|       </description> | ||||
|     </request> | ||||
| 
 | ||||
|     <!-- Version 3 additions --> | ||||
| 
 | ||||
|     <event name="parent" since="3"> | ||||
|       <description summary="parent change"> | ||||
|         This event is emitted whenever the parent of the toplevel changes. | ||||
| 
 | ||||
|         No event is emitted when the parent handle is destroyed by the client. | ||||
|       </description> | ||||
|       <arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/> | ||||
|     </event> | ||||
|   </interface> | ||||
| </protocol> | ||||
							
								
								
									
										269
									
								
								src/wayland/wl.c
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								src/wayland/wl.c
									
									
									
									
									
								
							| @ -19,6 +19,8 @@ | ||||
| #include "protocols/xdg-shell.h" | ||||
| #include "protocols/wlr-layer-shell-unstable-v1-client-header.h" | ||||
| #include "protocols/wlr-layer-shell-unstable-v1.h" | ||||
| #include "protocols/wlr-foreign-toplevel-management-unstable-v1-client-header.h" | ||||
| #include "protocols/wlr-foreign-toplevel-management-unstable-v1.h" | ||||
| #include "protocols/idle-client-header.h" | ||||
| #include "protocols/idle.h" | ||||
| #include "pool-buffer.h" | ||||
| @ -30,6 +32,8 @@ | ||||
| #include "../input.h" | ||||
| #include "libgwater-wayland.h" | ||||
| 
 | ||||
| #define MAX_TOUCHPOINTS 10 | ||||
| 
 | ||||
| struct window_wl { | ||||
|         cairo_surface_t *c_surface; | ||||
|         cairo_t * c_ctx; | ||||
| @ -54,6 +58,7 @@ struct wl_ctx { | ||||
|         struct wl_callback *frame_callback; | ||||
|         struct org_kde_kwin_idle *idle_handler; | ||||
|         struct org_kde_kwin_idle_timeout *idle_timeout; | ||||
|         struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager; | ||||
|         bool configured; | ||||
|         bool dirty; | ||||
|         bool is_idle; | ||||
| @ -64,6 +69,13 @@ struct wl_ctx { | ||||
|                 int32_t x, y; | ||||
|         } pointer; | ||||
| 
 | ||||
| 	struct { | ||||
| 		struct wl_touch *wl_touch; | ||||
| 		struct { | ||||
| 			int32_t x, y; | ||||
| 		} pts[MAX_TOUCHPOINTS]; | ||||
| 	} touch; | ||||
| 
 | ||||
|         struct dimensions cur_dim; | ||||
| 
 | ||||
|         int32_t width, height; | ||||
| @ -79,9 +91,10 @@ struct dunst_output { | ||||
| 
 | ||||
|         uint32_t scale; | ||||
|         uint32_t subpixel; // TODO do something with it
 | ||||
|         bool fullscreen; | ||||
|         struct zwlr_foreign_toplevel_handle_v1 *fullscreen_toplevel; // the toplevel that is fullscreened on this output
 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| struct wl_ctx ctx; | ||||
| 
 | ||||
| static void noop() { | ||||
| @ -124,6 +137,7 @@ static void create_output( struct wl_output *wl_output, uint32_t global_name) { | ||||
|         output->wl_output = wl_output; | ||||
|         // TODO: Fix this
 | ||||
|         output->scale = 1; | ||||
|         output->fullscreen = false; | ||||
|         wl_list_insert(&ctx.outputs, &output->link); | ||||
| 
 | ||||
|         wl_output_set_user_data(wl_output, output); | ||||
| @ -144,7 +158,36 @@ static void destroy_output(struct dunst_output *output) { | ||||
|         free(output); | ||||
| } | ||||
| 
 | ||||
| // FIXME: Snipped touch handling
 | ||||
| static void touch_handle_motion(void *data, struct wl_touch *wl_touch, | ||||
|                 uint32_t time, int32_t id, | ||||
|                 wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||||
|         if (id >= MAX_TOUCHPOINTS) { | ||||
|                 return; | ||||
|         } | ||||
|         ctx.touch.pts[id].x = wl_fixed_to_int(surface_x); | ||||
|         ctx.touch.pts[id].y = wl_fixed_to_int(surface_y); | ||||
| } | ||||
| 
 | ||||
| static void touch_handle_down(void *data, struct wl_touch *wl_touch, | ||||
|                 uint32_t serial, uint32_t time, struct wl_surface *sfc, int32_t id, | ||||
|                 wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||||
|         if (id >= MAX_TOUCHPOINTS) { | ||||
|                 return; | ||||
|         } | ||||
|         ctx.touch.pts[id].x = wl_fixed_to_int(surface_x); | ||||
|         ctx.touch.pts[id].y = wl_fixed_to_int(surface_y); | ||||
| } | ||||
| 
 | ||||
| static void touch_handle_up(void *data, struct wl_touch *wl_touch, | ||||
|                 uint32_t serial, uint32_t time, int32_t id) { | ||||
|         if (id >= MAX_TOUCHPOINTS) { | ||||
|                 return; | ||||
|         } | ||||
|         input_handle_click(BTN_TOUCH, false, | ||||
|                         ctx.touch.pts[id].x, ctx.touch.pts[id].y); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, | ||||
|                 uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||||
|         ctx.pointer.x = wl_fixed_to_int(surface_x); | ||||
| @ -165,7 +208,13 @@ static const struct wl_pointer_listener pointer_listener = { | ||||
|         .axis = noop, | ||||
| }; | ||||
| 
 | ||||
| // FIXME snipped touch listener
 | ||||
| static const struct wl_touch_listener touch_listener = { | ||||
|         .down = touch_handle_down, | ||||
|         .up = touch_handle_up, | ||||
|         .motion = touch_handle_motion, | ||||
|         .frame = noop, | ||||
|         .cancel = noop, | ||||
| }; | ||||
| 
 | ||||
| static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | ||||
|                 uint32_t capabilities) { | ||||
| @ -180,6 +229,15 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | ||||
|                         &pointer_listener, ctx.seat); | ||||
|                 LOG_I("Adding pointer"); | ||||
|         } | ||||
|         if (ctx.touch.wl_touch != NULL) { | ||||
|                 wl_touch_release(ctx.touch.wl_touch); | ||||
|                 ctx.touch.wl_touch = NULL; | ||||
|         } | ||||
|         if (capabilities & WL_SEAT_CAPABILITY_TOUCH) { | ||||
|                 ctx.touch.wl_touch = wl_seat_get_touch(wl_seat); | ||||
|                 wl_touch_add_listener(ctx.touch.wl_touch, | ||||
|                         &touch_listener, ctx.seat); | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| static const struct wl_seat_listener seat_listener = { | ||||
| @ -257,11 +315,11 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { | ||||
| 
 | ||||
| static void idle_start (void *data, struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) { | ||||
|         ctx.is_idle = true; | ||||
|         LOG_I("User went idle"); | ||||
|         LOG_D("User went idle"); | ||||
| } | ||||
| static void idle_stop (void *data, struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) { | ||||
|         ctx.is_idle = false; | ||||
|         LOG_I("User isn't idle anymore"); | ||||
|         LOG_D("User isn't idle anymore"); | ||||
| } | ||||
| 
 | ||||
| static const struct org_kde_kwin_idle_timeout_listener idle_timeout_listener = { | ||||
| @ -273,14 +331,145 @@ static void add_seat_to_idle_handler(struct wl_seat *seat) { | ||||
|         if (!ctx.idle_handler){ | ||||
|                 return; | ||||
|         } | ||||
|         if (settings.idle_threshold > 0) { | ||||
|                 uint32_t timeout_ms = settings.idle_threshold/1000; | ||||
|                 ctx.idle_timeout = org_kde_kwin_idle_get_idle_timeout(ctx.idle_handler, seat, timeout_ms); | ||||
|                 org_kde_kwin_idle_timeout_add_listener(ctx.idle_timeout, &idle_timeout_listener, 0); | ||||
|                 ctx.has_idle_monitor = true; | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| // Warning, can return NULL
 | ||||
| static struct dunst_output *get_configured_output() { | ||||
| 
 | ||||
|         switch (settings.f_mode){ | ||||
|                 case FOLLOW_NONE: ; // this semicolon is neccesary
 | ||||
|                         int n = 0; | ||||
|                         int target_monitor = settings.monitor; | ||||
| 
 | ||||
|                         struct dunst_output *output; | ||||
|                         wl_list_for_each(output, &ctx.outputs, link) { | ||||
|                                 if (n == target_monitor) | ||||
|                                         return output; | ||||
|                                 n++; | ||||
|                         } | ||||
|                         LOG_W("Monitor %i doesn't exist, using focused monitor", settings.monitor); | ||||
|                         return NULL; | ||||
|                 case FOLLOW_MOUSE: | ||||
|                         // fallthrough
 | ||||
|                 case FOLLOW_KEYBOARD: | ||||
|                         // fallthrough
 | ||||
|                 default: | ||||
|                         return NULL; | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| // does not do null checking
 | ||||
| static void dunst_output_set_fullscreen(struct dunst_output *output, | ||||
|                 struct zwlr_foreign_toplevel_handle_v1 *toplevel, | ||||
|                 bool fullscreen) { | ||||
|         output->fullscreen = fullscreen; | ||||
|         if (fullscreen) | ||||
|                 output->fullscreen_toplevel = toplevel; | ||||
|         else | ||||
|                 output->fullscreen_toplevel = NULL; | ||||
| 
 | ||||
|         LOG_D("Set output %i fullscreen state %i", output->global_name, fullscreen); | ||||
|         wake_up(); | ||||
| } | ||||
| 
 | ||||
| static void toplevel_output_leave(void *data, | ||||
|                 struct zwlr_foreign_toplevel_handle_v1 *toplevel, | ||||
|                 struct wl_output *output) { | ||||
|         zwlr_foreign_toplevel_handle_v1_set_user_data(toplevel, NULL); | ||||
| } | ||||
| 
 | ||||
| static void toplevel_output_enter(void *data, | ||||
|                 struct zwlr_foreign_toplevel_handle_v1 *toplevel, | ||||
|                 struct wl_output *output) { | ||||
|         // FIXME toplevel can be on multiple outputs, so a list of outputs should be kept
 | ||||
|         zwlr_foreign_toplevel_handle_v1_set_user_data(toplevel, output); | ||||
| } | ||||
| 
 | ||||
| static void toplevel_closed(void *data, | ||||
|                 struct zwlr_foreign_toplevel_handle_v1 *toplevel) { | ||||
|         struct wl_output *output_wl = (struct wl_output*) data; | ||||
| 
 | ||||
|         if (output_wl == NULL) { | ||||
|                 return; | ||||
|         } | ||||
|         struct dunst_output *output = (struct dunst_output*) wl_output_get_user_data(output_wl); | ||||
| 
 | ||||
|         if (output == NULL) { | ||||
|                 return; | ||||
|         } | ||||
|         dunst_output_set_fullscreen(output, toplevel, false); | ||||
| } | ||||
| 
 | ||||
| static void toplevel_state(void *data, | ||||
|                 struct zwlr_foreign_toplevel_handle_v1 *toplevel, | ||||
|                 struct wl_array *state) { | ||||
|         struct wl_output *output_wl = (struct wl_output*) data; | ||||
|         if (output_wl == NULL) { | ||||
|                 return; | ||||
|         } | ||||
|         struct dunst_output *output = (struct dunst_output*) wl_output_get_user_data(output_wl); | ||||
|         if (output == NULL) { | ||||
|                 return; | ||||
|         } | ||||
| 
 | ||||
|         bool fullscreen = false; | ||||
|         bool activated = false; | ||||
|         enum zwlr_foreign_toplevel_handle_v1_state* element; | ||||
|         wl_array_for_each(element, state){ | ||||
|                 if (*element == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN) { | ||||
|                         fullscreen = true; | ||||
|                 } | ||||
|                 if (*element == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED) { | ||||
|                         activated = true; | ||||
|                 } | ||||
|         } | ||||
|         if (fullscreen && activated) { | ||||
|                 dunst_output_set_fullscreen(output, toplevel, true); | ||||
| 
 | ||||
|         } else { | ||||
|                 if (output->fullscreen_toplevel == toplevel) { | ||||
|                         // this toplevel was fullscreen, but isn't anymore
 | ||||
|                         dunst_output_set_fullscreen(output, toplevel, false); | ||||
|                 } | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| static const struct zwlr_foreign_toplevel_handle_v1_listener foreign_toplevel_handle_listener = { | ||||
|         .title = noop, | ||||
|         .app_id = noop, | ||||
|         .output_enter = toplevel_output_enter, | ||||
|         .output_leave = toplevel_output_leave, | ||||
|         .state = toplevel_state, | ||||
|         .done = noop, | ||||
|         .closed = toplevel_closed, | ||||
| }; | ||||
| 
 | ||||
| static void toplevel_created(void *data, | ||||
|                 struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1, | ||||
|                 struct zwlr_foreign_toplevel_handle_v1 *toplevel){ | ||||
|         zwlr_foreign_toplevel_handle_v1_add_listener(toplevel, &foreign_toplevel_handle_listener, NULL); | ||||
| } | ||||
| 
 | ||||
| static void toplevel_finished(void *data, | ||||
|                 struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1){ | ||||
| } | ||||
| 
 | ||||
| static const struct zwlr_foreign_toplevel_manager_v1_listener foreign_toplevel_manager_listener = { | ||||
|         .toplevel = toplevel_created, | ||||
|         .finished = toplevel_finished, | ||||
| }; | ||||
| 
 | ||||
| static void handle_global(void *data, struct wl_registry *registry, | ||||
|                 uint32_t name, const char *interface, uint32_t version) { | ||||
|         int *count = data; | ||||
|         if (*count == 0) | ||||
|         { | ||||
|                 if (strcmp(interface, wl_compositor_interface.name) == 0) { | ||||
|                         ctx.compositor = wl_registry_bind(registry, name, | ||||
|                                         &wl_compositor_interface, 4); | ||||
| @ -302,6 +491,15 @@ static void handle_global(void *data, struct wl_registry *registry, | ||||
|                                 version >= ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE_SINCE_VERSION) { | ||||
|                         ctx.idle_handler = wl_registry_bind(registry, name, &org_kde_kwin_idle_interface, 1); | ||||
|                 } | ||||
|         } else { | ||||
|                 if (strcmp(interface, zwlr_foreign_toplevel_manager_v1_interface.name) == 0 && | ||||
|                                 version >= ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN_SINCE_VERSION) { | ||||
|                         // Only bind after the second pass to bind after binding to all the outputs.
 | ||||
|                         // This is because otherwise toplevel_enter evens won't be sent.
 | ||||
|                         ctx.toplevel_manager = wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, 2); | ||||
|                         zwlr_foreign_toplevel_manager_v1_add_listener(ctx.toplevel_manager, &foreign_toplevel_manager_listener, NULL); | ||||
|                 } | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| static void handle_global_remove(void *data, struct wl_registry *registry, | ||||
| @ -331,8 +529,15 @@ bool wl_init() { | ||||
|                 return false; | ||||
|         } | ||||
| 
 | ||||
|         int count = 0; | ||||
|         ctx.registry = wl_display_get_registry(ctx.display); | ||||
|         wl_registry_add_listener(ctx.registry, ®istry_listener, NULL); | ||||
|         wl_registry_add_listener(ctx.registry, ®istry_listener, &count); | ||||
|         wl_display_roundtrip(ctx.display); | ||||
| 
 | ||||
|         count = 1; | ||||
|         // we need a second pass to let for foreign_toplevel (look there for more info)
 | ||||
|         ctx.registry = wl_display_get_registry(ctx.display); | ||||
|         wl_registry_add_listener(ctx.registry, ®istry_listener, &count); | ||||
|         wl_display_roundtrip(ctx.display); | ||||
| 
 | ||||
|         if (ctx.compositor == NULL) { | ||||
| @ -359,6 +564,10 @@ bool wl_init() { | ||||
|                 } | ||||
|         } | ||||
| 
 | ||||
|         if (ctx.toplevel_manager == NULL) { | ||||
|                 LOG_W("compositor doesn't support zwlr_foreign_toplevel_v1. Fullscreen detection won't work"); | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
| } | ||||
| 
 | ||||
| @ -411,30 +620,6 @@ void wl_deinit() { | ||||
|                 wl_display_disconnect(ctx.display); | ||||
| } | ||||
| 
 | ||||
| static struct dunst_output *get_configured_output() { | ||||
|         struct dunst_output *output; | ||||
| 
 | ||||
|         switch (settings.f_mode){ | ||||
|                 case FOLLOW_NONE: ; // this semicolon is neccesary
 | ||||
|                         int n = 0; | ||||
|                         int target_monitor = settings.monitor; | ||||
| 
 | ||||
|                         wl_list_for_each(output, &ctx.outputs, link) { | ||||
|                                 if (n == target_monitor) | ||||
|                                         return output; | ||||
|                                 n++; | ||||
|                         } | ||||
|                         LOG_W("Monitor %i doesn't exist, using focused monitor", settings.monitor); | ||||
|                         return NULL; | ||||
|                 case FOLLOW_MOUSE: | ||||
|                         // fallthrough
 | ||||
|                 case FOLLOW_KEYBOARD: | ||||
|                         // fallthrough
 | ||||
|                 default: | ||||
|                         return NULL; | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| static void schedule_frame_and_commit(); | ||||
| 
 | ||||
| // Draw and commit a new frame.
 | ||||
| @ -473,6 +658,9 @@ static void send_frame() { | ||||
|         // different output), we need to create it.
 | ||||
|         if (ctx.layer_surface == NULL) { | ||||
|                 struct wl_output *wl_output = NULL; | ||||
|                 if (output != NULL) { | ||||
|                         wl_output = output->wl_output; | ||||
|                 } | ||||
|                 ctx.layer_surface_output = output; | ||||
|                 ctx.surface = wl_compositor_create_surface(ctx.compositor); | ||||
|                 wl_surface_add_listener(ctx.surface, &surface_listener, NULL); | ||||
| @ -675,7 +863,26 @@ bool wl_is_idle(void) { | ||||
|                 return ctx.is_idle; | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| bool wl_have_fullscreen_window(void) { | ||||
|         return false; | ||||
|         bool have_fullscreen = false; | ||||
| 
 | ||||
|         struct dunst_output *current_output = get_configured_output(); | ||||
| 
 | ||||
|         if (!current_output) { | ||||
|                 // Cannot detect focused output, so return true if any of the
 | ||||
|                 // outputs is fullscreen. This will work even when unfocused
 | ||||
|                 // outputs have fullscreen toplevels, since a toplevel has to
 | ||||
|                 // be fullscreen and activate to consider an output fullscreen.
 | ||||
|                 struct dunst_output *output; | ||||
|                 wl_list_for_each(output, &ctx.outputs, link) { | ||||
|                         have_fullscreen |= output->fullscreen; | ||||
|                 } | ||||
|         } else { | ||||
|                 have_fullscreen = current_output->fullscreen; | ||||
|         } | ||||
| 
 | ||||
|         LOG_D("Fullscreen queried: %i", have_fullscreen); | ||||
|         return have_fullscreen; | ||||
| } | ||||
| /* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikos Tsipinakis
						Nikos Tsipinakis