mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	compositor: Implement super-tab window switching
This commit is contained in:
		
							parent
							
								
									f30c67eea6
								
							
						
					
					
						commit
						c9824ddf35
					
				
					 2 changed files with 99 additions and 10 deletions
				
			
		| 
						 | 
					@ -35,6 +35,12 @@
 | 
				
			||||||
#include "wayland-server.h"
 | 
					#include "wayland-server.h"
 | 
				
			||||||
#include "compositor.h"
 | 
					#include "compositor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlsc_switcher {
 | 
				
			||||||
 | 
						struct wlsc_compositor *compositor;
 | 
				
			||||||
 | 
						struct wlsc_surface *current;
 | 
				
			||||||
 | 
						struct wl_listener listener;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The plan here is to generate a random anonymous socket name and
 | 
					/* The plan here is to generate a random anonymous socket name and
 | 
				
			||||||
 * advertise that through a service on the session dbus.
 | 
					 * advertise that through a service on the session dbus.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -416,10 +422,18 @@ wlsc_output_repaint(struct wlsc_output *output)
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			glClear(GL_COLOR_BUFFER_BIT);
 | 
								glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wl_list_for_each_reverse(es, &ec->surface_list, link)
 | 
							wl_list_for_each_reverse(es, &ec->surface_list, link) {
 | 
				
			||||||
 | 
								if (ec->switcher &&
 | 
				
			||||||
 | 
								    ec->switcher->current == es)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			wlsc_surface_draw(es, output);
 | 
								wlsc_surface_draw(es, output);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ec->switcher)
 | 
				
			||||||
 | 
							wlsc_surface_draw(ec->switcher->current, output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ec->focus)
 | 
						if (ec->focus)
 | 
				
			||||||
		wl_list_for_each(eid, &ec->input_device_list, link)
 | 
							wl_list_for_each(eid, &ec->input_device_list, link)
 | 
				
			||||||
			wlsc_surface_draw(eid->sprite, output);
 | 
								wlsc_surface_draw(eid->sprite, output);
 | 
				
			||||||
| 
						 | 
					@ -763,6 +777,20 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
 | 
				
			||||||
	wlsc_compositor_schedule_repaint(ec);
 | 
						wlsc_compositor_schedule_repaint(ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					wlsc_surface_activate(struct wlsc_surface *surface,
 | 
				
			||||||
 | 
							      struct wlsc_input_device *device, uint32_t time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						wlsc_surface_raise(surface);
 | 
				
			||||||
 | 
						if (device->selection)
 | 
				
			||||||
 | 
							wlsc_selection_set_focus(device->selection,
 | 
				
			||||||
 | 
										 &surface->surface, time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_input_device_set_keyboard_focus(&device->input_device,
 | 
				
			||||||
 | 
										   &surface->surface,
 | 
				
			||||||
 | 
										   time);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
notify_button(struct wl_input_device *device,
 | 
					notify_button(struct wl_input_device *device,
 | 
				
			||||||
	      uint32_t time, int32_t button, int32_t state)
 | 
						      uint32_t time, int32_t button, int32_t state)
 | 
				
			||||||
| 
						 | 
					@ -777,18 +805,10 @@ notify_button(struct wl_input_device *device,
 | 
				
			||||||
	int32_t x, y;
 | 
						int32_t x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (state && surface && device->grab == NULL) {
 | 
						if (state && surface && device->grab == NULL) {
 | 
				
			||||||
		wlsc_surface_raise(surface);
 | 
							wlsc_surface_activate(surface, wd, time);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (wd->selection)
 | 
					 | 
				
			||||||
			wlsc_selection_set_focus(wd->selection,
 | 
					 | 
				
			||||||
						 &surface->surface, time);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		wl_input_device_start_grab(device,
 | 
							wl_input_device_start_grab(device,
 | 
				
			||||||
					   &device->motion_grab,
 | 
										   &device->motion_grab,
 | 
				
			||||||
					   button, time);
 | 
										   button, time);
 | 
				
			||||||
		wl_input_device_set_keyboard_focus(device,
 | 
					 | 
				
			||||||
						   &surface->surface,
 | 
					 | 
				
			||||||
						   time);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (state && surface && button == BTN_LEFT &&
 | 
						if (state && surface && button == BTN_LEFT &&
 | 
				
			||||||
| 
						 | 
					@ -829,6 +849,53 @@ notify_button(struct wl_input_device *device,
 | 
				
			||||||
		wl_input_device_end_grab(device, time);
 | 
							wl_input_device_end_grab(device, time);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					wlsc_switcher_next(struct wlsc_switcher *switcher)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wl_list *l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						l = switcher->current->link.next;
 | 
				
			||||||
 | 
						if (l == &switcher->compositor->surface_list)
 | 
				
			||||||
 | 
							l = switcher->compositor->surface_list.next;
 | 
				
			||||||
 | 
						switcher->current = container_of(l, struct wlsc_surface, link);
 | 
				
			||||||
 | 
						wl_list_remove(&switcher->listener.link);
 | 
				
			||||||
 | 
						wl_list_insert(switcher->current->surface.destroy_listener_list.prev,
 | 
				
			||||||
 | 
							       &switcher->listener.link);
 | 
				
			||||||
 | 
						wlsc_compositor_schedule_repaint(switcher->compositor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					switcher_handle_surface_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
									struct wl_surface *surface, uint32_t time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wlsc_switcher *switcher =
 | 
				
			||||||
 | 
							container_of(listener, struct wlsc_switcher, listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlsc_switcher_next(switcher);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlsc_switcher *
 | 
				
			||||||
 | 
					wlsc_switcher_create(struct wlsc_compositor *compositor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wlsc_switcher *switcher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switcher = malloc(sizeof *switcher);
 | 
				
			||||||
 | 
						switcher->compositor = compositor;
 | 
				
			||||||
 | 
						switcher->current = container_of(compositor->surface_list.next,
 | 
				
			||||||
 | 
										 struct wlsc_surface, link);
 | 
				
			||||||
 | 
						switcher->listener.func = switcher_handle_surface_destroy;
 | 
				
			||||||
 | 
						wl_list_init(&switcher->listener.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return switcher;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					wlsc_switcher_destroy(struct wlsc_switcher *switcher)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						wl_list_remove(&switcher->listener.link);
 | 
				
			||||||
 | 
						free(switcher);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
notify_key(struct wl_input_device *device,
 | 
					notify_key(struct wl_input_device *device,
 | 
				
			||||||
	   uint32_t time, uint32_t key, uint32_t state)
 | 
						   uint32_t time, uint32_t key, uint32_t state)
 | 
				
			||||||
| 
						 | 
					@ -843,6 +910,27 @@ notify_key(struct wl_input_device *device,
 | 
				
			||||||
	case KEY_BACKSPACE | MODIFIER_CTRL | MODIFIER_ALT:
 | 
						case KEY_BACKSPACE | MODIFIER_CTRL | MODIFIER_ALT:
 | 
				
			||||||
		wl_display_terminate(compositor->wl_display);
 | 
							wl_display_terminate(compositor->wl_display);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case KEY_TAB | MODIFIER_SUPER:
 | 
				
			||||||
 | 
							if (!state)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							if (wl_list_empty(&compositor->surface_list))
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							if (compositor->switcher == NULL)
 | 
				
			||||||
 | 
								compositor->switcher = wlsc_switcher_create(compositor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wlsc_switcher_next(compositor->switcher);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case KEY_LEFTMETA | MODIFIER_SUPER:
 | 
				
			||||||
 | 
						case KEY_RIGHTMETA | MODIFIER_SUPER:
 | 
				
			||||||
 | 
							if (compositor->switcher && !state) {
 | 
				
			||||||
 | 
								wlsc_surface_activate(compositor->switcher->current,
 | 
				
			||||||
 | 
										      wd, time);
 | 
				
			||||||
 | 
								wlsc_switcher_destroy(compositor->switcher);
 | 
				
			||||||
 | 
								compositor->switcher = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (key) {
 | 
						switch (key) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,6 +110,7 @@ struct wlsc_compositor {
 | 
				
			||||||
	int repaint_on_timeout;
 | 
						int repaint_on_timeout;
 | 
				
			||||||
	struct timespec previous_swap;
 | 
						struct timespec previous_swap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlsc_switcher *switcher;
 | 
				
			||||||
	uint32_t focus;
 | 
						uint32_t focus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void (*destroy)(struct wlsc_compositor *ec);
 | 
						void (*destroy)(struct wlsc_compositor *ec);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue