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 | endif | ||||||
| 
 | 
 | ||||||
| ifneq (0,${WAYLAND}) | 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 | 	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 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 | 	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 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 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 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 | endif | ||||||
| 
 | 
 | ||||||
| .PHONY: clean clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run clean-wayland-protocols | .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 | will cause notifications to be displayed above fullscreen windows, though | ||||||
| this may also occur at top depending on your compositor. | 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. | The bottom layer is below all windows and above the background. | ||||||
| 
 | 
 | ||||||
| Default: overlay | 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]) | =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 | =over 4 | ||||||
| 
 | 
 | ||||||
| @ -647,7 +645,7 @@ but also has a lot of extra functionality. So see more see dunstctl(1). | |||||||
| =head1 HISTORY | =head1 HISTORY | ||||||
| 
 | 
 | ||||||
| Dunst saves a number of notifications (specified by B<history_length>) in memory. | Dunst saves a number of notifications (specified by B<history_length>) in memory. | ||||||
| These notifications can be recalled (i.e. redisplayed) by calling  | These notifications can be recalled (i.e. redisplayed) by calling | ||||||
| B<dunstctl history> (see dunstctl(1)). Whether these notifications will time out | B<dunstctl history> (see dunstctl(1)). Whether these notifications will time out | ||||||
| like if they have been just send depends on the value of the B<sticky_history> | like if they have been just send depends on the value of the B<sticky_history> | ||||||
| setting. | setting. | ||||||
| @ -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 | is more focused on security, some things that are possible in X11 are not | ||||||
| possible in Wayland. Those differences are reflected in the configuration. | possible in Wayland. Those differences are reflected in the configuration. | ||||||
| The main things that change are that dunst on Wayland cannot use global | The main things that change are that dunst on Wayland cannot use global | ||||||
| hotkeys (they are deprecated anyways, use dunstctl) and it cannot detect | hotkeys (they are deprecated anyways, use dunstctl). | ||||||
| if an application is fullscreen. If you want to see notifications when in | 
 | ||||||
| fullscreen, set B<layer = overlay> in the global options. | 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. | Note that the same limitations exist when using xwayland. | ||||||
| If something doesn't quite work in Wayland, please file a bug report. In the | 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. | 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. | 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 | existing notifications are paused and hidden until the focus to the fullscreen | ||||||
| window is lost. | 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 | Default: show | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -25,6 +25,10 @@ void input_handle_click(unsigned int button, bool button_down, int mouse_x, int | |||||||
|                 case BTN_RIGHT: |                 case BTN_RIGHT: | ||||||
|                         acts = settings.mouse_right_click; |                         acts = settings.mouse_right_click; | ||||||
|                         break; |                         break; | ||||||
|  |                 case BTN_TOUCH: | ||||||
|  |                         // TODO Add separate action for touch
 | ||||||
|  |                         acts = settings.mouse_left_click; | ||||||
|  |                         break; | ||||||
|                 default: |                 default: | ||||||
|                         LOG_W("Unsupported mouse button: '%d'", button); |                         LOG_W("Unsupported mouse button: '%d'", button); | ||||||
|                         return; |                         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> | ||||||
							
								
								
									
										317
									
								
								src/wayland/wl.c
									
									
									
									
									
								
							
							
						
						
									
										317
									
								
								src/wayland/wl.c
									
									
									
									
									
								
							| @ -19,6 +19,8 @@ | |||||||
| #include "protocols/xdg-shell.h" | #include "protocols/xdg-shell.h" | ||||||
| #include "protocols/wlr-layer-shell-unstable-v1-client-header.h" | #include "protocols/wlr-layer-shell-unstable-v1-client-header.h" | ||||||
| #include "protocols/wlr-layer-shell-unstable-v1.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-client-header.h" | ||||||
| #include "protocols/idle.h" | #include "protocols/idle.h" | ||||||
| #include "pool-buffer.h" | #include "pool-buffer.h" | ||||||
| @ -30,6 +32,8 @@ | |||||||
| #include "../input.h" | #include "../input.h" | ||||||
| #include "libgwater-wayland.h" | #include "libgwater-wayland.h" | ||||||
| 
 | 
 | ||||||
|  | #define MAX_TOUCHPOINTS 10 | ||||||
|  | 
 | ||||||
| struct window_wl { | struct window_wl { | ||||||
|         cairo_surface_t *c_surface; |         cairo_surface_t *c_surface; | ||||||
|         cairo_t * c_ctx; |         cairo_t * c_ctx; | ||||||
| @ -54,6 +58,7 @@ struct wl_ctx { | |||||||
|         struct wl_callback *frame_callback; |         struct wl_callback *frame_callback; | ||||||
|         struct org_kde_kwin_idle *idle_handler; |         struct org_kde_kwin_idle *idle_handler; | ||||||
|         struct org_kde_kwin_idle_timeout *idle_timeout; |         struct org_kde_kwin_idle_timeout *idle_timeout; | ||||||
|  |         struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager; | ||||||
|         bool configured; |         bool configured; | ||||||
|         bool dirty; |         bool dirty; | ||||||
|         bool is_idle; |         bool is_idle; | ||||||
| @ -64,6 +69,13 @@ struct wl_ctx { | |||||||
|                 int32_t x, y; |                 int32_t x, y; | ||||||
|         } pointer; |         } pointer; | ||||||
| 
 | 
 | ||||||
|  | 	struct { | ||||||
|  | 		struct wl_touch *wl_touch; | ||||||
|  | 		struct { | ||||||
|  | 			int32_t x, y; | ||||||
|  | 		} pts[MAX_TOUCHPOINTS]; | ||||||
|  | 	} touch; | ||||||
|  | 
 | ||||||
|         struct dimensions cur_dim; |         struct dimensions cur_dim; | ||||||
| 
 | 
 | ||||||
|         int32_t width, height; |         int32_t width, height; | ||||||
| @ -79,9 +91,10 @@ struct dunst_output { | |||||||
| 
 | 
 | ||||||
|         uint32_t scale; |         uint32_t scale; | ||||||
|         uint32_t subpixel; // TODO do something with it
 |         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; | struct wl_ctx ctx; | ||||||
| 
 | 
 | ||||||
| static void noop() { | 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; |         output->wl_output = wl_output; | ||||||
|         // TODO: Fix this
 |         // TODO: Fix this
 | ||||||
|         output->scale = 1; |         output->scale = 1; | ||||||
|  |         output->fullscreen = false; | ||||||
|         wl_list_insert(&ctx.outputs, &output->link); |         wl_list_insert(&ctx.outputs, &output->link); | ||||||
| 
 | 
 | ||||||
|         wl_output_set_user_data(wl_output, output); |         wl_output_set_user_data(wl_output, output); | ||||||
| @ -144,7 +158,36 @@ static void destroy_output(struct dunst_output *output) { | |||||||
|         free(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, | 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) { |                 uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||||||
|         ctx.pointer.x = wl_fixed_to_int(surface_x); |         ctx.pointer.x = wl_fixed_to_int(surface_x); | ||||||
| @ -165,7 +208,13 @@ static const struct wl_pointer_listener pointer_listener = { | |||||||
|         .axis = noop, |         .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, | static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | ||||||
|                 uint32_t capabilities) { |                 uint32_t capabilities) { | ||||||
| @ -180,6 +229,15 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | |||||||
|                         &pointer_listener, ctx.seat); |                         &pointer_listener, ctx.seat); | ||||||
|                 LOG_I("Adding pointer"); |                 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 = { | 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) { | static void idle_start (void *data, struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) { | ||||||
|         ctx.is_idle = true; |         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) { | static void idle_stop (void *data, struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) { | ||||||
|         ctx.is_idle = false; |         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 = { | static const struct org_kde_kwin_idle_timeout_listener idle_timeout_listener = { | ||||||
| @ -273,34 +331,174 @@ static void add_seat_to_idle_handler(struct wl_seat *seat) { | |||||||
|         if (!ctx.idle_handler){ |         if (!ctx.idle_handler){ | ||||||
|                 return; |                 return; | ||||||
|         } |         } | ||||||
|         uint32_t timeout_ms = settings.idle_threshold/1000; |         if (settings.idle_threshold > 0) { | ||||||
|         ctx.idle_timeout = org_kde_kwin_idle_get_idle_timeout(ctx.idle_handler, seat, timeout_ms); |                 uint32_t timeout_ms = settings.idle_threshold/1000; | ||||||
|         org_kde_kwin_idle_timeout_add_listener(ctx.idle_timeout, &idle_timeout_listener, 0); |                 ctx.idle_timeout = org_kde_kwin_idle_get_idle_timeout(ctx.idle_handler, seat, timeout_ms); | ||||||
|         ctx.has_idle_monitor = true; |                 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, | static void handle_global(void *data, struct wl_registry *registry, | ||||||
|                 uint32_t name, const char *interface, uint32_t version) { |                 uint32_t name, const char *interface, uint32_t version) { | ||||||
|         if (strcmp(interface, wl_compositor_interface.name) == 0) { |         int *count = data; | ||||||
|                 ctx.compositor = wl_registry_bind(registry, name, |         if (*count == 0) | ||||||
|                         &wl_compositor_interface, 4); |         { | ||||||
|         } else if (strcmp(interface, wl_shm_interface.name) == 0) { |                 if (strcmp(interface, wl_compositor_interface.name) == 0) { | ||||||
|                 ctx.shm = wl_registry_bind(registry, name, |                         ctx.compositor = wl_registry_bind(registry, name, | ||||||
|                         &wl_shm_interface, 1); |                                         &wl_compositor_interface, 4); | ||||||
|         } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { |                 } else if (strcmp(interface, wl_shm_interface.name) == 0) { | ||||||
|                 ctx.layer_shell = wl_registry_bind(registry, name, |                         ctx.shm = wl_registry_bind(registry, name, | ||||||
|                         &zwlr_layer_shell_v1_interface, 1); |                                         &wl_shm_interface, 1); | ||||||
|         } else if (strcmp(interface, wl_seat_interface.name) == 0) { |                 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { | ||||||
|                 ctx.seat = wl_registry_bind(registry, name, &wl_seat_interface, 3); |                         ctx.layer_shell = wl_registry_bind(registry, name, | ||||||
|                 wl_seat_add_listener(ctx.seat, &seat_listener, ctx.seat); |                                         &zwlr_layer_shell_v1_interface, 1); | ||||||
|                 add_seat_to_idle_handler(ctx.seat); |                 } else if (strcmp(interface, wl_seat_interface.name) == 0) { | ||||||
|         } else if (strcmp(interface, wl_output_interface.name) == 0) { |                         ctx.seat = wl_registry_bind(registry, name, &wl_seat_interface, 3); | ||||||
|                 struct wl_output *output = |                         wl_seat_add_listener(ctx.seat, &seat_listener, ctx.seat); | ||||||
|                         wl_registry_bind(registry, name, &wl_output_interface, 3); |                         add_seat_to_idle_handler(ctx.seat); | ||||||
|                 create_output(output, name); |                 } else if (strcmp(interface, wl_output_interface.name) == 0) { | ||||||
|         } else if (strcmp(interface, org_kde_kwin_idle_interface.name) == 0 && |                         struct wl_output *output = | ||||||
|                         version >= ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE_SINCE_VERSION) { |                                 wl_registry_bind(registry, name, &wl_output_interface, 3); | ||||||
|                 ctx.idle_handler = wl_registry_bind(registry, name, &org_kde_kwin_idle_interface, 1); |                         create_output(output, name); | ||||||
|  |                 } else if (strcmp(interface, org_kde_kwin_idle_interface.name) == 0 && | ||||||
|  |                                 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); | ||||||
|  |                 } | ||||||
|         } |         } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -331,8 +529,15 @@ bool wl_init() { | |||||||
|                 return false; |                 return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         int count = 0; | ||||||
|         ctx.registry = wl_display_get_registry(ctx.display); |         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); |         wl_display_roundtrip(ctx.display); | ||||||
| 
 | 
 | ||||||
|         if (ctx.compositor == NULL) { |         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; |         return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -411,30 +620,6 @@ void wl_deinit() { | |||||||
|                 wl_display_disconnect(ctx.display); |                 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(); | static void schedule_frame_and_commit(); | ||||||
| 
 | 
 | ||||||
| // Draw and commit a new frame.
 | // Draw and commit a new frame.
 | ||||||
| @ -473,6 +658,9 @@ static void send_frame() { | |||||||
|         // different output), we need to create it.
 |         // different output), we need to create it.
 | ||||||
|         if (ctx.layer_surface == NULL) { |         if (ctx.layer_surface == NULL) { | ||||||
|                 struct wl_output *wl_output = NULL; |                 struct wl_output *wl_output = NULL; | ||||||
|  |                 if (output != NULL) { | ||||||
|  |                         wl_output = output->wl_output; | ||||||
|  |                 } | ||||||
|                 ctx.layer_surface_output = output; |                 ctx.layer_surface_output = output; | ||||||
|                 ctx.surface = wl_compositor_create_surface(ctx.compositor); |                 ctx.surface = wl_compositor_create_surface(ctx.compositor); | ||||||
|                 wl_surface_add_listener(ctx.surface, &surface_listener, NULL); |                 wl_surface_add_listener(ctx.surface, &surface_listener, NULL); | ||||||
| @ -675,7 +863,26 @@ bool wl_is_idle(void) { | |||||||
|                 return ctx.is_idle; |                 return ctx.is_idle; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  | 
 | ||||||
| bool wl_have_fullscreen_window(void) { | 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: */ | /* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikos Tsipinakis
						Nikos Tsipinakis