mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Added in basic floating toggling
This commit is contained in:
		
							parent
							
								
									be2635daa6
								
							
						
					
					
						commit
						05f969074e
					
				
					 6 changed files with 176 additions and 4 deletions
				
			
		| 
						 | 
					@ -40,12 +40,17 @@ struct sway_container {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool visible;
 | 
						bool visible;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_floating;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int weight;
 | 
						int weight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_t *children;
 | 
						list_t *children;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Special list for floating windows in workspaces
 | 
				
			||||||
 | 
						list_t *floating;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct sway_container *parent;
 | 
						struct sway_container *parent;
 | 
				
			||||||
	struct sway_container *focused;
 | 
						struct sway_container *focused;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								sway/children
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								sway/children
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					workspace.c:90:35:	swayc_t *current_output = active_workspace->parent;
 | 
				
			||||||
 | 
					workspace.c:93:78:		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
 | 
				
			||||||
 | 
					workspace.c:105:35:	swayc_t *current_output = active_workspace->parent;
 | 
				
			||||||
 | 
					workspace.c:108:78:		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
 | 
				
			||||||
 | 
					workspace.c:133:35:	swayc_t *current_output = active_workspace->parent;
 | 
				
			||||||
 | 
					workspace.c:136:78:		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
 | 
				
			||||||
 | 
					workspace.c:149:35:	swayc_t *current_output = active_workspace->parent;
 | 
				
			||||||
 | 
					workspace.c:152:78:		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
 | 
				
			||||||
 | 
					workspace.c:176:23:	swayc_t *ws_output = workspace->parent;
 | 
				
			||||||
 | 
					workspace.c:183:70:		sway_log(L_DEBUG, "workspace: changing from '%s' to '%s'", focused_workspace->name, workspace->name);
 | 
				
			||||||
 | 
					workspace.c:199:20:	swayc_t *output = workspace->parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					container.c:79:2:	workspace->layout = L_HORIZ; // TODO:default layout
 | 
				
			||||||
 | 
					container.c:80:2:	workspace->width = output->width;
 | 
				
			||||||
 | 
					container.c:81:2:	workspace->height = output->height;
 | 
				
			||||||
 | 
					container.c:82:2:	workspace->name = strdup(name);
 | 
				
			||||||
 | 
					container.c:83:2:	workspace->visible = true;
 | 
				
			||||||
 | 
					container.c:105:19:		cont->focused = workspace->focused;
 | 
				
			||||||
 | 
					container.c:106:3:		workspace->focused = cont;
 | 
				
			||||||
 | 
					container.c:108:24:		list_t  *tmp_list  = workspace->children;
 | 
				
			||||||
 | 
					container.c:109:3:		workspace->children = cont->children;
 | 
				
			||||||
 | 
					container.c:114:18:		cont->layout = workspace->layout;
 | 
				
			||||||
 | 
					container.c:115:3:		workspace->layout = layout;
 | 
				
			||||||
 | 
					container.c:162:6:	if (workspace->children->length == 0) {
 | 
				
			||||||
 | 
					container.c:163:61:		sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name);
 | 
				
			||||||
 | 
					container.c:164:21:		swayc_t *parent = workspace->parent;
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
#include "workspace.h"
 | 
					#include "workspace.h"
 | 
				
			||||||
#include "commands.h"
 | 
					#include "commands.h"
 | 
				
			||||||
#include "container.h"
 | 
					#include "container.h"
 | 
				
			||||||
 | 
					#include "handlers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct modifier_key {
 | 
					struct modifier_key {
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
| 
						 | 
					@ -169,6 +170,72 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
 | 
				
			||||||
 | 
						if (strcasecmp(argv[0], "toggle") == 0) {
 | 
				
			||||||
 | 
							swayc_t *view = get_focused_container(&root_container);
 | 
				
			||||||
 | 
							// Prevent running floating commands on things like workspaces
 | 
				
			||||||
 | 
							if (view->type != C_VIEW) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
							// Change from nonfloating to floating
 | 
				
			||||||
 | 
							if (!view->is_floating) {
 | 
				
			||||||
 | 
								view->is_floating = true;
 | 
				
			||||||
 | 
								for (i = 0; i < view->parent->children->length; i++) {
 | 
				
			||||||
 | 
									if (view->parent->children->items[i] == view) {
 | 
				
			||||||
 | 
										// Cut down on width/height so it's obvious that you've gone floating
 | 
				
			||||||
 | 
										// if this is the only view
 | 
				
			||||||
 | 
										view->width = view->width - 30;
 | 
				
			||||||
 | 
										view->height = view->height - 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Swap from the list of whatever container the view was in
 | 
				
			||||||
 | 
										// to the workspace->floating list
 | 
				
			||||||
 | 
										// TODO: Destroy any remaining empty containers
 | 
				
			||||||
 | 
										list_del(view->parent->children, i);
 | 
				
			||||||
 | 
										list_add(active_workspace->floating, view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Set the new position of the container and arrange windows
 | 
				
			||||||
 | 
										view->x = (active_workspace->width - view->width)/2;
 | 
				
			||||||
 | 
										view->y = (active_workspace->height - view->height)/2;
 | 
				
			||||||
 | 
										sway_log(L_INFO, "Setting container %p to floating at coordinates X:%d Y:%d, W:%d, H:%d", view, view->x, view->y, view->width, view->height);
 | 
				
			||||||
 | 
										// Change parent to active_workspace
 | 
				
			||||||
 | 
										view->parent = active_workspace;
 | 
				
			||||||
 | 
										arrange_windows(active_workspace, -1, -1);
 | 
				
			||||||
 | 
										return true;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// Delete the view from the floating list and unset its is_floating flag
 | 
				
			||||||
 | 
								// Using length-1 as the index is safe because the view must be the currently
 | 
				
			||||||
 | 
								// focused floating output
 | 
				
			||||||
 | 
								list_del(active_workspace->floating, active_workspace->floating->length - 1);
 | 
				
			||||||
 | 
								view->is_floating = false;
 | 
				
			||||||
 | 
								active_workspace->focused = NULL;
 | 
				
			||||||
 | 
								// Get the properly focused container, and add in the view there
 | 
				
			||||||
 | 
								swayc_t *focused = focus_pointer();
 | 
				
			||||||
 | 
								// If focused is null, it's because the currently focused container is a workspace
 | 
				
			||||||
 | 
								if (focused == NULL) {
 | 
				
			||||||
 | 
									focused = active_workspace;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sway_log(L_DEBUG, "Non-floating focused container is %p", focused);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//Case of focused workspace, just create as child of it
 | 
				
			||||||
 | 
								if (focused->type == C_WORKSPACE) {
 | 
				
			||||||
 | 
									add_child(focused, view);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								//Regular case, create as sibling of current container
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									add_sibling(focused, view);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								arrange_windows(active_workspace, -1, -1);
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
 | 
					static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) {
 | 
						if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -378,6 +445,7 @@ static struct cmd_handler handlers[] = {
 | 
				
			||||||
	{ "exec", cmd_exec },
 | 
						{ "exec", cmd_exec },
 | 
				
			||||||
	{ "exec_always", cmd_exec_always },
 | 
						{ "exec_always", cmd_exec_always },
 | 
				
			||||||
	{ "exit", cmd_exit },
 | 
						{ "exit", cmd_exit },
 | 
				
			||||||
 | 
						{ "floating", cmd_floating },
 | 
				
			||||||
	{ "focus", cmd_focus },
 | 
						{ "focus", cmd_focus },
 | 
				
			||||||
	{ "focus_follows_mouse", cmd_focus_follows_mouse },
 | 
						{ "focus_follows_mouse", cmd_focus_follows_mouse },
 | 
				
			||||||
	{ "fullscreen", cmd_fullscreen },
 | 
						{ "fullscreen", cmd_fullscreen },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,6 +81,7 @@ swayc_t *new_workspace(swayc_t * output, const char *name) {
 | 
				
			||||||
	workspace->height = output->height;
 | 
						workspace->height = output->height;
 | 
				
			||||||
	workspace->name = strdup(name);
 | 
						workspace->name = strdup(name);
 | 
				
			||||||
	workspace->visible = true;
 | 
						workspace->visible = true;
 | 
				
			||||||
 | 
						workspace->floating = create_list();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	add_child(output, workspace);
 | 
						add_child(output, workspace);
 | 
				
			||||||
	return workspace;
 | 
						return workspace;
 | 
				
			||||||
| 
						 | 
					@ -134,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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: properly set this
 | 
				
			||||||
 | 
						view->is_floating = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Case of focused workspace, just create as child of it
 | 
						//Case of focused workspace, just create as child of it
 | 
				
			||||||
	if (sibling->type == C_WORKSPACE) {
 | 
						if (sibling->type == C_WORKSPACE) {
 | 
				
			||||||
		add_child(sibling, view);
 | 
							add_child(sibling, view);
 | 
				
			||||||
| 
						 | 
					@ -192,23 +196,32 @@ swayc_t *destroy_view(swayc_t *view) {
 | 
				
			||||||
	if (parent->type == C_CONTAINER) {
 | 
						if (parent->type == C_CONTAINER) {
 | 
				
			||||||
		return destroy_container(parent);
 | 
							return destroy_container(parent);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return parent;
 | 
						return parent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
 | 
					swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
 | 
				
			||||||
	if (!container->children) {
 | 
						if (!container->children) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Special case for checking floating stuff
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
						if (container->type == C_WORKSPACE) {
 | 
				
			||||||
 | 
							for (i = 0; i < container->floating->length; ++i) {
 | 
				
			||||||
 | 
								swayc_t *child = container->floating->items[i];
 | 
				
			||||||
 | 
								if (test(child, data)) {
 | 
				
			||||||
 | 
									return child;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	for (i = 0; i < container->children->length; ++i) {
 | 
						for (i = 0; i < container->children->length; ++i) {
 | 
				
			||||||
		swayc_t *child = container->children->items[i];
 | 
							swayc_t *child = container->children->items[i];
 | 
				
			||||||
		if (test(child, data)) {
 | 
							if (test(child, data)) {
 | 
				
			||||||
			return child;
 | 
								return child;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			swayc_t *_ = find_container(child, test, data);
 | 
								swayc_t *res = find_container(child, test, data);
 | 
				
			||||||
			if (_) {
 | 
								if (res) {
 | 
				
			||||||
				return _;
 | 
									return res;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,15 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *remove_child(swayc_t *parent, swayc_t *child) {
 | 
					swayc_t *remove_child(swayc_t *parent, swayc_t *child) {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
						// Special case for floating views
 | 
				
			||||||
 | 
						if (child->is_floating) {
 | 
				
			||||||
 | 
							for (i = 0; i < parent->floating->length; ++i) {
 | 
				
			||||||
 | 
								if (parent->floating->items[i] == child) {
 | 
				
			||||||
 | 
									list_del(parent->floating, i);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	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);
 | 
				
			||||||
| 
						 | 
					@ -192,6 +201,33 @@ void arrange_windows(swayc_t *container, int width, int height) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Arrage floating layouts for workspaces last
 | 
				
			||||||
 | 
						if (container->type == C_WORKSPACE) {
 | 
				
			||||||
 | 
							for (i = 0; i < container->floating->length; ++i) {
 | 
				
			||||||
 | 
								swayc_t *view = ((swayc_t *)container->floating->items[i]);
 | 
				
			||||||
 | 
								// Set the geometry
 | 
				
			||||||
 | 
								struct wlc_geometry geometry = {
 | 
				
			||||||
 | 
									.origin = {
 | 
				
			||||||
 | 
										.x = view->x,
 | 
				
			||||||
 | 
										.y = view->y
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									.size = {
 | 
				
			||||||
 | 
										.w = view->width,
 | 
				
			||||||
 | 
										.h = view->height
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								wlc_view_set_geometry(view->handle, &geometry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Bring the views to the front in order of the list, the list
 | 
				
			||||||
 | 
								// will be kept up to date so that more recently focused views
 | 
				
			||||||
 | 
								// have higher indexes
 | 
				
			||||||
 | 
								// This is conditional on there not being a fullscreen view in the workspace
 | 
				
			||||||
 | 
								if (!(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) {
 | 
				
			||||||
 | 
									wlc_view_bring_to_front(view->handle);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	layout_log(&root_container, 0);
 | 
						layout_log(&root_container, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,7 +235,18 @@ swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
 | 
				
			||||||
	if (parent->children == NULL) {
 | 
						if (parent->children == NULL) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Search for floating workspaces
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
						if (parent->type == C_WORKSPACE) {
 | 
				
			||||||
 | 
							for (i = 0; i < parent->floating->length; ++i) {
 | 
				
			||||||
 | 
								swayc_t *child = parent->floating->items[i];
 | 
				
			||||||
 | 
								if (child->handle == handle) {
 | 
				
			||||||
 | 
									return child;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < parent->children->length; ++i) {
 | 
						for (i = 0; i < parent->children->length; ++i) {
 | 
				
			||||||
		swayc_t *child = parent->children->items[i];
 | 
							swayc_t *child = parent->children->items[i];
 | 
				
			||||||
		if (child->handle == handle) {
 | 
							if (child->handle == handle) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,5 +255,18 @@ void layout_log(const swayc_t *c, int depth) {
 | 
				
			||||||
		for (i = 0; i < depth; ++i) fputc(' ', stderr);
 | 
							for (i = 0; i < depth; ++i) fputc(' ', stderr);
 | 
				
			||||||
		fprintf(stderr,")\n");
 | 
							fprintf(stderr,")\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (c->type == C_WORKSPACE) {
 | 
				
			||||||
 | 
							e = c->floating?c->floating->length:0;
 | 
				
			||||||
 | 
							for (i = 0; i < depth; ++i) fputc(' ', stderr);
 | 
				
			||||||
 | 
							if (e) {
 | 
				
			||||||
 | 
								for (i = 0; i < depth; ++i) fputc(' ', stderr);
 | 
				
			||||||
 | 
								fprintf(stderr,"(\n");
 | 
				
			||||||
 | 
								for (i = 0; i < e; ++i) {
 | 
				
			||||||
 | 
									layout_log(c->floating->items[i], depth + 1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for (i = 0; i < depth; ++i) fputc(' ', stderr);
 | 
				
			||||||
 | 
								fprintf(stderr,")\n");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/* XXX:DEBUG:XXX */
 | 
					/* XXX:DEBUG:XXX */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue