mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Fixes to floating and umanaged views
This commit is contained in:
		
							parent
							
								
									da77dc45a9
								
							
						
					
					
						commit
						47ec999e71
					
				
					 5 changed files with 99 additions and 14 deletions
				
			
		| 
						 | 
					@ -36,6 +36,9 @@ struct sway_container {
 | 
				
			||||||
	// Not including borders or margins
 | 
						// Not including borders or margins
 | 
				
			||||||
	int width, height;
 | 
						int width, height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Used for setting floating geometry
 | 
				
			||||||
 | 
					    int desired_width, desired_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int x, y;
 | 
						int x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool visible;
 | 
						bool visible;
 | 
				
			||||||
| 
						 | 
					@ -62,6 +65,8 @@ swayc_t *new_workspace(swayc_t * output, const char *name);
 | 
				
			||||||
swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
 | 
					swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
 | 
				
			||||||
//Creates view as a sibling of current focused container, or as child of a workspace
 | 
					//Creates view as a sibling of current focused container, or as child of a workspace
 | 
				
			||||||
swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
 | 
					swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
 | 
				
			||||||
 | 
					//Creates view as a new floating view which is in the active workspace
 | 
				
			||||||
 | 
					swayc_t *new_floating_view(wlc_handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *destroy_output(swayc_t *output);
 | 
					swayc_t *destroy_output(swayc_t *output);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,16 +183,19 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
 | 
				
			||||||
			view->is_floating = true;
 | 
								view->is_floating = true;
 | 
				
			||||||
			for (i = 0; i < view->parent->children->length; i++) {
 | 
								for (i = 0; i < view->parent->children->length; i++) {
 | 
				
			||||||
				if (view->parent->children->items[i] == view) {
 | 
									if (view->parent->children->items[i] == view) {
 | 
				
			||||||
					// Cut down on width/height so it's obvious that you've gone floating
 | 
										// Try to use desired geometry to set w/h
 | 
				
			||||||
					// if this is the only view
 | 
										if (view->desired_width != -1) {
 | 
				
			||||||
					view->width = view->width - 30;
 | 
											view->width = view->desired_width;
 | 
				
			||||||
					view->height = view->height - 30;
 | 
										}
 | 
				
			||||||
 | 
										if (view->desired_height != -1) {
 | 
				
			||||||
 | 
											view->height = view->desired_height;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// Swap from the list of whatever container the view was in
 | 
										// Swap from the list of whatever container the view was in
 | 
				
			||||||
					// to the workspace->floating list
 | 
										// to the workspace->floating list
 | 
				
			||||||
					// TODO: Destroy any remaining empty containers
 | 
					 | 
				
			||||||
					list_del(view->parent->children, i);
 | 
										list_del(view->parent->children, i);
 | 
				
			||||||
					list_add(active_workspace->floating, view);
 | 
										list_add(active_workspace->floating, view);
 | 
				
			||||||
 | 
										destroy_container(view->parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// Set the new position of the container and arrange windows
 | 
										// Set the new position of the container and arrange windows
 | 
				
			||||||
					view->x = (active_workspace->width - view->width)/2;
 | 
										view->x = (active_workspace->width - view->width)/2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,6 +135,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
 | 
				
			||||||
	view->name = strdup(title);
 | 
						view->name = strdup(title);
 | 
				
			||||||
	view->visible = true;
 | 
						view->visible = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						view->desired_width = -1;
 | 
				
			||||||
 | 
						view->desired_height = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: properly set this
 | 
						// TODO: properly set this
 | 
				
			||||||
	view->is_floating = false;
 | 
						view->is_floating = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,6 +152,38 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
 | 
				
			||||||
	return view;
 | 
						return view;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					swayc_t *new_floating_view(wlc_handle handle) {
 | 
				
			||||||
 | 
						const char   *title = wlc_view_get_title(handle);
 | 
				
			||||||
 | 
						swayc_t *view = new_swayc(C_VIEW);
 | 
				
			||||||
 | 
						sway_log(L_DEBUG, "Adding new view %u:%s as a floating view",
 | 
				
			||||||
 | 
							(unsigned int)handle, title);
 | 
				
			||||||
 | 
						//Setup values
 | 
				
			||||||
 | 
						view->handle = handle;
 | 
				
			||||||
 | 
						view->name = strdup(title);
 | 
				
			||||||
 | 
						view->visible = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set the geometry of the floating view
 | 
				
			||||||
 | 
						const struct wlc_geometry* geometry = wlc_view_get_geometry(handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						view->x = geometry->origin.x;
 | 
				
			||||||
 | 
						view->y = geometry->origin.y;
 | 
				
			||||||
 | 
						view->width = geometry->size.w;
 | 
				
			||||||
 | 
						view->height = geometry->size.h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						view->desired_width = -1;
 | 
				
			||||||
 | 
						view->desired_height = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						view->is_floating = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//Case of focused workspace, just create as child of it
 | 
				
			||||||
 | 
						list_add(active_workspace->floating, view);
 | 
				
			||||||
 | 
						view->parent = active_workspace;
 | 
				
			||||||
 | 
						if (active_workspace->focused == NULL) {
 | 
				
			||||||
 | 
							active_workspace->focused = view;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return view;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *destroy_output(swayc_t *output) {
 | 
					swayc_t *destroy_output(swayc_t *output) {
 | 
				
			||||||
	if (output->children->length == 0) {
 | 
						if (output->children->length == 0) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@
 | 
				
			||||||
#include "handlers.h"
 | 
					#include "handlers.h"
 | 
				
			||||||
#include "stringop.h"
 | 
					#include "stringop.h"
 | 
				
			||||||
#include "workspace.h"
 | 
					#include "workspace.h"
 | 
				
			||||||
 | 
					#include "container.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlc_origin mouse_origin;
 | 
					static struct wlc_origin mouse_origin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,17 +89,24 @@ static void handle_output_focused(wlc_handle output, bool focus) {
 | 
				
			||||||
static bool handle_view_created(wlc_handle handle) {
 | 
					static bool handle_view_created(wlc_handle handle) {
 | 
				
			||||||
	swayc_t *focused = get_focused_container(&root_container);
 | 
						swayc_t *focused = get_focused_container(&root_container);
 | 
				
			||||||
	uint32_t type = wlc_view_get_type(handle);
 | 
						uint32_t type = wlc_view_get_type(handle);
 | 
				
			||||||
	//If override_redirect/unmanaged/popup/modal/splach
 | 
						// If override_redirect/unmanaged/popup/modal/splach
 | 
				
			||||||
	if (type) {
 | 
						if (type) {
 | 
				
			||||||
		sway_log(L_DEBUG,"Unmanaged window of type %x left alone", type);
 | 
							sway_log(L_DEBUG,"Unmanaged window of type %x left alone", type);
 | 
				
			||||||
		wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
 | 
							wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
 | 
				
			||||||
		if (type & WLC_BIT_UNMANAGED) {
 | 
							if (type & WLC_BIT_UNMANAGED) {
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		//for things like Dmenu
 | 
							// For things like Dmenu
 | 
				
			||||||
		if (type & WLC_BIT_OVERRIDE_REDIRECT) {
 | 
							if (type & WLC_BIT_OVERRIDE_REDIRECT) {
 | 
				
			||||||
			wlc_view_focus(handle);
 | 
								wlc_view_focus(handle);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Float popups
 | 
				
			||||||
 | 
							if (type & WLC_BIT_POPUP) {
 | 
				
			||||||
 | 
								swayc_t *view = new_floating_view(handle);
 | 
				
			||||||
 | 
								focus_view(view);
 | 
				
			||||||
 | 
								arrange_windows(active_workspace, -1, -1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		swayc_t *view = new_view(focused, handle);
 | 
							swayc_t *view = new_view(focused, handle);
 | 
				
			||||||
		//Set maximize flag for windows.
 | 
							//Set maximize flag for windows.
 | 
				
			||||||
| 
						 | 
					@ -118,6 +126,24 @@ static bool handle_view_created(wlc_handle handle) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_view_destroyed(wlc_handle handle) {
 | 
					static void handle_view_destroyed(wlc_handle handle) {
 | 
				
			||||||
	sway_log(L_DEBUG, "Destroying window %u", (unsigned int)handle);
 | 
						sway_log(L_DEBUG, "Destroying window %u", (unsigned int)handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Properly handle unmanaged views
 | 
				
			||||||
 | 
						uint32_t type = wlc_view_get_type(handle);
 | 
				
			||||||
 | 
						if (type) {
 | 
				
			||||||
 | 
							wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
 | 
				
			||||||
 | 
							sway_log(L_DEBUG,"Unmanaged window of type %x was destroyed", type);
 | 
				
			||||||
 | 
							if (type & WLC_BIT_UNMANAGED) {
 | 
				
			||||||
 | 
								focus_view(focus_pointer());
 | 
				
			||||||
 | 
								arrange_windows(active_workspace, -1, -1);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (type & WLC_BIT_OVERRIDE_REDIRECT) {
 | 
				
			||||||
 | 
								focus_view(focus_pointer());
 | 
				
			||||||
 | 
								arrange_windows(active_workspace, -1, -1);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	swayc_t *view = get_swayc_for_handle(handle, &root_container);
 | 
						swayc_t *view = get_swayc_for_handle(handle, &root_container);
 | 
				
			||||||
	swayc_t *parent;
 | 
						swayc_t *parent;
 | 
				
			||||||
	swayc_t *focused = get_focused_container(&root_container);
 | 
						swayc_t *focused = get_focused_container(&root_container);
 | 
				
			||||||
| 
						 | 
					@ -135,8 +161,23 @@ static void handle_view_focus(wlc_handle view, bool focus) {
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry) {
 | 
					static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry* geometry) {
 | 
				
			||||||
	// deny that shit
 | 
						// If the view is floating, then apply the geometry.
 | 
				
			||||||
 | 
						// Otherwise save the desired width/height for the view.
 | 
				
			||||||
 | 
						// This will not do anything for the time being as WLC improperly sends geometry requests
 | 
				
			||||||
 | 
						swayc_t *view = get_swayc_for_handle(handle, &root_container);
 | 
				
			||||||
 | 
						if (view) {
 | 
				
			||||||
 | 
							if (view->is_floating) {
 | 
				
			||||||
 | 
								view->width = geometry->size.w;
 | 
				
			||||||
 | 
								view->height = geometry->size.h;
 | 
				
			||||||
 | 
								view->x = geometry->origin.x;
 | 
				
			||||||
 | 
								view->y = geometry->origin.y;
 | 
				
			||||||
 | 
								arrange_windows(view->parent, -1, -1);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								view->desired_width = geometry->size.w;
 | 
				
			||||||
 | 
								view->desired_height = geometry->size.h;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
 | 
					static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,13 +73,14 @@ swayc_t *remove_child(swayc_t *parent, swayc_t *child) {
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						} else {
 | 
				
			||||||
		for (i = 0; i < parent->children->length; ++i) {
 | 
							for (i = 0; i < parent->children->length; ++i) {
 | 
				
			||||||
			if (parent->children->items[i] == child) {
 | 
								if (parent->children->items[i] == child) {
 | 
				
			||||||
				list_del(parent->children, i);
 | 
									list_del(parent->children, i);
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (parent->focused == child) {
 | 
						if (parent->focused == child) {
 | 
				
			||||||
		parent->focused = NULL;
 | 
							parent->focused = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue