Exemplo n.º 1
0
static swayc_t *fetch_view_from_scratchpad() {
	if (sp_index >= scratchpad->length) {
		sp_index = 0;
	}
	swayc_t *view = scratchpad->items[sp_index++];

	if (wlc_view_get_output(view->handle) != swayc_active_output()->handle) {
		wlc_view_set_output(view->handle, swayc_active_output()->handle);
	}
	if (!view->is_floating) {
		view->width = swayc_active_workspace()->width/2;
		view->height = swayc_active_workspace()->height/2;
		view->x = (swayc_active_workspace()->width - view->width)/2;
		view->y = (swayc_active_workspace()->height - view->height)/2;
	}
	if (swayc_active_workspace()->width < view->x + 20 || view->x + view->width < 20) {
		view->x = (swayc_active_workspace()->width - view->width)/2;
	}
	if (swayc_active_workspace()->height < view->y + 20 || view->y + view->height < 20) {
		view->y = (swayc_active_workspace()->height - view->height)/2;
	}

	add_floating(swayc_active_workspace(), view);
	wlc_view_set_mask(view->handle, VISIBLE);
	view->visible = true;
	arrange_windows(swayc_active_workspace(), -1, -1);
	set_focused_container(view);
	return view;
}
Exemplo n.º 2
0
struct cmd_results *cmd_scratchpad(int argc, char **argv) {
	struct cmd_results *error = NULL;
	if (config->reading) return cmd_results_new(CMD_FAILURE, "scratchpad", "Can't be used in config file.");
	if (!config->active) return cmd_results_new(CMD_FAILURE, "scratchpad", "Can only be used when sway is running.");
	if ((error = checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1))) {
		return error;
	}

	if (strcasecmp(argv[0], "show") == 0 && scratchpad->length > 0) {
		if (!sp_view) {
			sp_view = fetch_view_from_scratchpad();
		} else {
			if (swayc_active_workspace() != sp_view->parent) {
				hide_view_in_scratchpad(sp_view);
				if (sp_index == 0) {
					sp_index = scratchpad->length;
				}
				sp_index--;
				sp_view = fetch_view_from_scratchpad();
			} else {
				hide_view_in_scratchpad(sp_view);
				sp_view = NULL;
			}
		}
		return cmd_results_new(CMD_SUCCESS, NULL, NULL);
	}
	return cmd_results_new(CMD_FAILURE, "scratchpad", "Expected 'scratchpad show' when scratchpad is not empty.");
}
Exemplo n.º 3
0
static bool resize(int dimension, bool use_width, enum resize_dim_types dim_type) {
	swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace());

	// translate "10 ppt" (10%) to appropriate # of pixels in case we need it
	float ppt_dim = (float)dimension / 100;

	if (use_width) {
		ppt_dim = focused->width * ppt_dim;
	} else {
		ppt_dim = focused->height * ppt_dim;
	}

	if (focused) {
		if (focused->is_floating) {
			// floating view resize dimensions should default to px, so only
			// use ppt if specified
			if (dim_type == RESIZE_DIM_PPT) {
				dimension = (int)ppt_dim;
			}

			return resize_floating(dimension, use_width);
		} else {
			// tiled view resize dimensions should default to ppt, so only use
			// px if specified
			if (dim_type != RESIZE_DIM_PX) {
				dimension = (int)ppt_dim;
			}

			return resize_tiled(dimension, use_width);
		}
	}

	return false;
}
Exemplo n.º 4
0
Arquivo: log.c Projeto: zetok/sway
/* XXX:DEBUG:XXX */
static void container_log(const swayc_t *c) {
	fprintf(stderr, "focus:%c|",
			c == get_focused_view(&root_container) ? 'K':
			c == get_focused_container(&root_container) ? 'F' : // Focused
			c == swayc_active_workspace() ? 'W' : // active workspace
			c == &root_container  ? 'R' : // root
			'X');// not any others
	fprintf(stderr,"(%p)",c);
	fprintf(stderr,"(p:%p)",c->parent);
	fprintf(stderr,"(f:%p)",c->focused);
	fprintf(stderr,"(h:%ld)",c->handle);
	fprintf(stderr,"Type:");
	fprintf(stderr,
			c->type == C_ROOT   ? "Root|" :
			c->type == C_OUTPUT ? "Output|" :
			c->type == C_WORKSPACE ? "Workspace|" :
			c->type == C_CONTAINER ? "Container|" :
			c->type == C_VIEW   ? "View|" : "Unknown|");
	fprintf(stderr,"layout:");
	fprintf(stderr,
			c->layout == L_NONE ? "NONE|" :
			c->layout == L_HORIZ ? "Horiz|":
			c->layout == L_VERT ? "Vert|":
			c->layout == L_STACKED  ? "Stacked|":
			c->layout == L_FLOATING ? "Floating|":
			"Unknown|");
	fprintf(stderr, "w:%.f|h:%.f|", c->width, c->height);
	fprintf(stderr, "x:%.f|y:%.f|", c->x, c->y);
	fprintf(stderr, "g:%d|",c->gaps);
	fprintf(stderr, "vis:%c|", c->visible?'t':'f');
	fprintf(stderr, "name:%.16s|", c->name);
	fprintf(stderr, "children:%d\n",c->children?c->children->length:0);
}
Exemplo n.º 5
0
static bool set_size_floating(int new_dimension, bool use_width) {
	swayc_t *view = get_focused_float(swayc_active_workspace());
	if (view) {
		if (use_width) {
			int current_width = view->width;
			view->desired_width = new_dimension;
			floating_view_sane_size(view);

			int new_x = view->x + (int)(((view->desired_width - current_width) / 2) * -1);
			view->width = view->desired_width;
			view->x = new_x;

			update_geometry(view);
		} else {
			int current_height = view->height;
			view->desired_height = new_dimension;
			floating_view_sane_size(view);

			int new_y = view->y + (int)(((view->desired_height - current_height) / 2) * -1);
			view->height = view->desired_height;
			view->y = new_y;

			update_geometry(view);
		}

		return true;
	}

	return false;
}
Exemplo n.º 6
0
swayc_t *get_focused_float(swayc_t *ws) {
	if(!sway_assert(ws->type == C_WORKSPACE, "must be of workspace type")) {
		ws = swayc_active_workspace();
	}
	if (ws->floating->length) {
		return ws->floating->items[ws->floating->length - 1];
	}
	return NULL;
}
Exemplo n.º 7
0
swayc_t *get_focused_container(swayc_t *parent) {
	if (!parent) {
		return swayc_active_workspace();
	}
	// get focusde container
	while (!parent->is_focused && parent->focused) {
		parent = parent->focused;
	}
	return parent;
}
Exemplo n.º 8
0
static bool set_size_tiled(int amount, bool use_width) {
	int desired;
	swayc_t *focused = get_focused_view(swayc_active_workspace());

	if (use_width) {
		desired = amount - focused->width;
	} else {
		desired = amount - focused->height;
	}

	return resize_tiled(desired, use_width);
}
Exemplo n.º 9
0
static bool set_size(int dimension, bool use_width) {
	swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace());

	if (focused) {
		if (focused->is_floating) {
			return set_size_floating(dimension, use_width);
		} else {
			return set_size_tiled(dimension, use_width);
		}
	}

	return false;
}
Exemplo n.º 10
0
static bool resize_floating(int amount, bool use_width) {
	swayc_t *view = get_focused_float(swayc_active_workspace());

	if (view) {
		if (use_width) {
			return set_size_floating(view->width + amount, true);
		} else {
			return set_size_floating(view->height + amount, false);
		}
	}

	return false;
}
Exemplo n.º 11
0
bool workspace_switch(swayc_t *workspace) {
	if (!workspace) {
		return false;
	}
	swayc_t *active_ws = swayc_active_workspace();
	if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) {
		swayc_t *new_ws = workspace_by_name(prev_workspace_name);
		workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
	}

	if (!prev_workspace_name
			|| (strcmp(prev_workspace_name, active_ws->name)
				&& active_ws != workspace)) {
		free(prev_workspace_name);
		prev_workspace_name = malloc(strlen(active_ws->name)+1);
		strcpy(prev_workspace_name, active_ws->name);
	}

	// move sticky containers
	if (swayc_parent_by_type(active_ws, C_OUTPUT) == swayc_parent_by_type(workspace, C_OUTPUT)) {
		// don't change list while traversing it, use intermediate list instead
		list_t *stickies = create_list();
		for (int i = 0; i < active_ws->floating->length; i++) {
			swayc_t *cont = active_ws->floating->items[i];
			if (cont->sticky) {
				list_add(stickies, cont);
			}
		}
		for (int i = 0; i < stickies->length; i++) {
			swayc_t *cont = stickies->items[i];
			sway_log(L_DEBUG, "Moving sticky container %p to %p:%s",
					cont, workspace, workspace->name);
			swayc_t *parent = remove_child(cont);
			add_floating(workspace, cont);
			// Destroy old container if we need to
			destroy_container(parent);
		}
		list_free(stickies);
	}
	sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
	if (!set_focused_container(get_focused_view(workspace))) {
		return false;
	}
	swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
	arrange_backgrounds();
	arrange_windows(output, -1, -1);
	return true;
}
Exemplo n.º 12
0
static bool handle_output_created(wlc_handle output) {
	swayc_t *op = new_output(output);

	// Visibility mask to be able to make view invisible
	wlc_output_set_mask(output, VISIBLE);

	if (!op) {
		return false;
	}

	// Switch to workspace if we need to
	if (swayc_active_workspace() == NULL) {
		swayc_t *ws = op->children->items[0];
		workspace_switch(ws);
	}
	return true;
}
Exemplo n.º 13
0
void workspace_switch(swayc_t *workspace) {
	if (!workspace) {
		return;
	}
	if (strcmp(prev_workspace_name, swayc_active_workspace()->name) != 0 && swayc_active_workspace() != workspace) {
		prev_workspace_name = malloc(strlen(swayc_active_workspace()->name) + 1);
		strcpy(prev_workspace_name, swayc_active_workspace()->name);
	} else if (config->auto_back_and_forth && swayc_active_workspace() == workspace && strlen(prev_workspace_name) != 0) {
		workspace = workspace_by_name(prev_workspace_name) ? workspace_by_name(prev_workspace_name) : workspace_create(prev_workspace_name);
		prev_workspace_name = malloc(strlen(swayc_active_workspace()->name) + 1);
		strcpy(prev_workspace_name, swayc_active_workspace()->name);
	}

	sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
	set_focused_container(get_focused_view(workspace));
	arrange_windows(workspace, -1, -1);
}
Exemplo n.º 14
0
swayc_t *workspace_by_name(const char* name) {
	if (strcmp(name, "prev") == 0) {
		return workspace_prev();
	}
	else if (strcmp(name, "prev_on_output") == 0) {
		return workspace_output_prev();
	}
	else if (strcmp(name, "next") == 0) {
		return workspace_next();
	}
	else if (strcmp(name, "next_on_output") == 0) {
		return workspace_output_next();
	}
	else if (strcmp(name, "current") == 0) {
		return swayc_active_workspace();
	}
	else {
		return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
	}
}
Exemplo n.º 15
0
void workspace_switch(swayc_t *workspace) {
	if (!workspace) {
		return;
	}
	swayc_t *active_ws = swayc_active_workspace();
	if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) {
		swayc_t *new_ws = workspace_by_name(prev_workspace_name);
		workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
	}

	if (!prev_workspace_name
			|| (strcmp(prev_workspace_name, active_ws->name)
				&& active_ws != workspace)) {
		free(prev_workspace_name);
		prev_workspace_name = malloc(strlen(active_ws->name)+1);
		strcpy(prev_workspace_name, active_ws->name);
	}

	sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
	set_focused_container(get_focused_view(workspace));
	arrange_windows(workspace, -1, -1);
}
Exemplo n.º 16
0
static bool handle_output_created(wlc_handle output) {
	swayc_t *op = new_output(output);

	// Visibility mask to be able to make view invisible
	wlc_output_set_mask(output, VISIBLE);

	if (!op) {
		return false;
	}

	// Switch to workspace if we need to
	if (swayc_active_workspace() == NULL) {
		swayc_t *ws = op->children->items[0];
		workspace_switch(ws);
	}

	// Fixes issues with backgrounds and wlc
	wlc_handle prev = wlc_get_focused_output();
	wlc_output_focus(output);
	wlc_output_focus(prev);
	return true;
}
Exemplo n.º 17
0
/* XXX:DEBUG:XXX */
static void container_log(const swayc_t *c, int depth) {
	fprintf(stderr, "focus:%c",
			c == get_focused_view(&root_container) ? 'K':
			c == get_focused_container(&root_container) ? 'F' : // Focused
			c == swayc_active_workspace() ? 'W' : // active workspace
			c == &root_container  ? 'R' : // root
			'X');// not any others
	for (int i = 6; i > depth; i--) { fprintf(stderr, " "); }
	fprintf(stderr,"|(%p)",c);
	fprintf(stderr,"(p:%-8p)",c->parent);
	fprintf(stderr,"(f:%-8p)",c->focused);
	fprintf(stderr,"(h:%2" PRIuPTR ")",c->handle);
	fprintf(stderr,"Type:%-4s|",
			c->type == C_ROOT   ? "root" :
			c->type == C_OUTPUT ? "op" :
			c->type == C_WORKSPACE ? "ws" :
			c->type == C_CONTAINER ? "cont" :
			c->type == C_VIEW   ? "view" : "?");
	fprintf(stderr,"layout:%-5s|",
			c->layout == L_NONE ? "-" :
			c->layout == L_HORIZ ? "Horiz":
			c->layout == L_VERT ? "Vert":
			c->layout == L_STACKED  ? "Stack":
			c->layout == L_TABBED  ? "Tab":
			c->layout == L_FLOATING ? "Float":
			c->layout == L_AUTO_LEFT ? "A_lft":
			c->layout == L_AUTO_RIGHT ? "A_rgt":
			c->layout == L_AUTO_TOP ? "A_top":
			c->layout == L_AUTO_BOTTOM ? "A_bot":
			"Unknown");
	fprintf(stderr, "w:%4.f|h:%4.f|", c->width, c->height);
	fprintf(stderr, "x:%4.f|y:%4.f|", c->x, c->y);
	fprintf(stderr, "g:%3d|",c->gaps);
	fprintf(stderr, "vis:%c|", c->visible?'t':'f');
	fprintf(stderr, "children:%2d|",c->children?c->children->length:0);
	fprintf(stderr, "name:%.16s\n", c->name);
}
Exemplo n.º 18
0
swayc_t *workspace_next() {
	return workspace_prev_next_impl(swayc_active_workspace(), true);
}
Exemplo n.º 19
0
static bool resize_tiled(int amount, bool use_width) {
	swayc_t *parent = get_focused_view(swayc_active_workspace());
	swayc_t *focused = parent;
	swayc_t *sibling;
	if (!parent) {
		return true;
	}
	// Find the closest parent container which has siblings of the proper layout.
	// Then apply the resize to all of them.
	int i;
	if (use_width) {
		int lnumber = 0;
		int rnumber = 0;
		while (parent->parent) {
			if (parent->parent->layout == L_HORIZ && parent->parent->children) {
				for (i = 0; i < parent->parent->children->length; i++) {
					sibling = parent->parent->children->items[i];
					if (sibling->x != focused->x) {
						if (sibling->x < parent->x) {
							lnumber++;
						} else if (sibling->x > parent->x) {
							rnumber++;
						}
					}
				}
				if (rnumber || lnumber) {
					break;
				}
			}
			parent = parent->parent;
		}
		if (parent == &root_container) {
			return true;
		}
		sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber);
		//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
		bool valid = true;
		for (i = 0; i < parent->parent->children->length; i++) {
			sibling = parent->parent->children->items[i];
			if (sibling->x != focused->x) {
				if (sibling->x < parent->x) {
					double pixels = -1 * amount;
					pixels /= lnumber;
					if (rnumber) {
						if ((sibling->width + pixels/2) < min_sane_w) {
							valid = false;
							break;
						}
					} else {
						if ((sibling->width + pixels) < min_sane_w) {
							valid = false;
							break;
						}
					}
				} else if (sibling->x > parent->x) {
					double pixels = -1 * amount;
					pixels /= rnumber;
					if (lnumber) {
						if ((sibling->width + pixels/2) < min_sane_w) {
							valid = false;
							break;
						}
					} else {
						if ((sibling->width + pixels) < min_sane_w) {
							valid = false;
							break;
						}
					}
				}
			} else {
				double pixels = amount;
				if (parent->width + pixels < min_sane_w) {
					valid = false;
					break;
				}
			}
		}
		if (valid) {
			for (i = 0; i < parent->parent->children->length; i++) {
				sibling = parent->parent->children->items[i];
				if (sibling->x != focused->x) {
					if (sibling->x < parent->x) {
						double pixels = -1 * amount;
						pixels /= lnumber;
						if (rnumber) {
							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT);
						} else {
							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT);
						}
					} else if (sibling->x > parent->x) {
						double pixels = -1 * amount;
						pixels /= rnumber;
						if (lnumber) {
							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT);
						} else {
							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT);
						}
					}
				} else {
					if (rnumber != 0 && lnumber != 0) {
						double pixels = amount;
						pixels /= 2;
						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT);
						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT);
					} else if (rnumber) {
						recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT);
					} else if (lnumber) {
						recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT);
					}
				}
			}
			// Recursive resize does not handle positions, let arrange_windows
			// take care of that.
			arrange_windows(swayc_active_workspace(), -1, -1);
		}
		return true;
	} else {
		int tnumber = 0;
		int bnumber = 0;
		while (parent->parent) {
			if (parent->parent->layout == L_VERT) {
				for (i = 0; i < parent->parent->children->length; i++) {
					sibling = parent->parent->children->items[i];
					if (sibling->y != focused->y) {
						if (sibling->y < parent->y) {
							bnumber++;
						} else if (sibling->y > parent->y) {
							tnumber++;
						}
					}
				}
				if (bnumber || tnumber) {
					break;
				}
			}
			parent = parent->parent;
		}
		if (parent->parent == NULL || parent->parent->children == NULL) {
			return true;
		}
		sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber);
		//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
		bool valid = true;
		for (i = 0; i < parent->parent->children->length; i++) {
			sibling = parent->parent->children->items[i];
			if (sibling->y != focused->y) {
				if (sibling->y < parent->y) {
					double pixels = -1 * amount;
					pixels /= bnumber;
					if (tnumber) {
						if ((sibling->height + pixels/2) < min_sane_h) {
							valid = false;
							break;
						}
					} else {
						if ((sibling->height + pixels) < min_sane_h) {
							valid = false;
							break;
						}
					}
				} else if (sibling->y > parent->y) {
					double pixels = -1 * amount;
					pixels /= tnumber;
					if (bnumber) {
						if ((sibling->height + pixels/2) < min_sane_h) {
							valid = false;
							break;
						}
					} else {
						if ((sibling->height + pixels) < min_sane_h) {
							valid = false;
							break;
						}
					}
				}
			} else {
				double pixels = amount;
				if (parent->height + pixels < min_sane_h) {
					valid = false;
					break;
				}
			}
		}
		if (valid) {
			for (i = 0; i < parent->parent->children->length; i++) {
				sibling = parent->parent->children->items[i];
				if (sibling->y != focused->y) {
					if (sibling->y < parent->y) {
						double pixels = -1 * amount;
						pixels /= bnumber;
						if (tnumber) {
							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM);
						} else {
							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM);
						}
					} else if (sibling->x > parent->x) {
						double pixels = -1 * amount;
						pixels /= tnumber;
						if (bnumber) {
							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP);
						} else {
							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP);
						}
					}
				} else {
					if (bnumber != 0 && tnumber != 0) {
						double pixels = amount/2;
						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP);
						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM);
					} else if (tnumber) {
						recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP);
					} else if (bnumber) {
						recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM);
					}
				}
			}
			arrange_windows(swayc_active_workspace(), -1, -1);
		}
		return true;
	}
	return true;
}
Exemplo n.º 20
0
bool set_focused_container(swayc_t *c) {
	if (locked_container_focus || !c || !c->parent) {
		return false;
	}
	swayc_t *active_ws = swayc_active_workspace();
	int active_ws_child_count = 0;
	if (active_ws) {
		active_ws_child_count = active_ws->children->length + active_ws->floating->length;
	}

	swayc_log(L_DEBUG, c, "Setting focus to %p:%" PRIuPTR, c, c->handle);

	// Get workspace for c, get that workspaces current focused container.
	swayc_t *workspace = swayc_active_workspace_for(c);
	swayc_t *focused = get_focused_view(workspace);

	if (swayc_is_fullscreen(focused) && focused != c) {
		// if switching to a workspace with a fullscreen view,
		// focus on the fullscreen view
		c = focused;
	}

	if (c->type == C_VIEW) {
		// dispatch a window event
		ipc_event_window(c, "focus");
	}
	// update container focus from here to root, making necessary changes along
	// the way
	swayc_t *p = c;
	if (p->type != C_OUTPUT && p->type != C_ROOT) {
		p->is_focused = true;
	}
	while (p != &root_container) {
		update_focus(p);
		p = p->parent;
		p->is_focused = false;
	}

	// get new focused view and set focus to it.
	p = get_focused_view(c);
	if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) {
		// unactivate previous focus
		if (focused->type == C_VIEW) {
			wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false);
			update_view_border(focused);
		}
		// activate current focus
		if (p->type == C_VIEW) {
			wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true);
			// set focus if view_focus is unlocked
			if (!locked_view_focus) {
				wlc_view_focus(p->handle);
				if (p->parent->layout != L_TABBED
					&& p->parent->layout != L_STACKED) {
					update_view_border(p);
				}
			}
		}

		// rearrange if parent container is tabbed/stacked
		swayc_t *parent = swayc_tabbed_stacked_ancestor(p);
		if (parent != NULL) {
			arrange_backgrounds();
			arrange_windows(parent, -1, -1);
		}
	} else if (p->type == C_WORKSPACE) {
		// remove previous focus if view_focus is unlocked
		if (!locked_view_focus) {
			wlc_view_focus(0);
		}
	}

	if (active_ws != workspace) {
		// active_ws might have been destroyed by now
		// (focus swap away from empty ws = destroy ws)
		if (active_ws_child_count == 0) {
			active_ws = NULL;
		}

		ipc_event_workspace(active_ws, workspace, "focus");
	}
	return true;
}
Exemplo n.º 21
0
struct cmd_results *cmd_floating(int argc, char **argv) {
	struct cmd_results *error = NULL;
	if (config->reading) return cmd_results_new(CMD_FAILURE, "floating", "Can't be used in config file.");
	if ((error = checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1))) {
		return error;
	}
	swayc_t *view = current_container;
	bool wants_floating;
	if (strcasecmp(argv[0], "enable") == 0) {
		wants_floating = true;
	} else if (strcasecmp(argv[0], "disable") == 0) {
		wants_floating = false;
	} else if (strcasecmp(argv[0], "toggle") == 0) {
		wants_floating = !view->is_floating;
	} else {
		return cmd_results_new(CMD_FAILURE, "floating",
			"Expected 'floating <enable|disable|toggle>");
	}

	// Prevent running floating commands on things like workspaces
	if (view->type != C_VIEW) {
		return cmd_results_new(CMD_SUCCESS, NULL, NULL);
	}

	// Change from nonfloating to floating
	if (!view->is_floating && wants_floating) {
		// Remove view from its current location
		destroy_container(remove_child(view));

		// and move it into workspace floating
		add_floating(swayc_active_workspace(), view);
		view->x = (swayc_active_workspace()->width - view->width)/2;
		view->y = (swayc_active_workspace()->height - view->height)/2;
		if (view->desired_width != -1) {
			view->width = view->desired_width;
		}
		if (view->desired_height != -1) {
			view->height = view->desired_height;
		}
		arrange_windows(swayc_active_workspace(), -1, -1);

	} else if (view->is_floating && !wants_floating) {
		// Delete the view from the floating list and unset its is_floating flag
		remove_child(view);
		view->is_floating = false;
		// Get the properly focused container, and add in the view there
		swayc_t *focused = container_under_pointer();
		// If focused is null, it's because the currently focused container is a workspace
		if (focused == NULL || focused->is_floating) {
			focused = swayc_active_workspace();
		}
		set_focused_container(focused);

		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);
		}
		// Refocus on the view once its been put back into the layout
		view->width = view->height = 0;
		arrange_windows(swayc_active_workspace(), -1, -1);
		remove_view_from_scratchpad(view);
		ipc_event_window(view, "floating");
	}
	set_focused_container(view);
	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
Exemplo n.º 22
0
swayc_t *workspace_prev() {
	return workspace_prev_next_impl(swayc_active_workspace(), false);
}
Exemplo n.º 23
0
Arquivo: gaps.c Projeto: SirCmpwn/sway
struct cmd_results *cmd_gaps(int argc, char **argv) {
	struct cmd_results *error = NULL;
	if ((error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1))) {
		return error;
	}
	const char *expected_syntax =
		"Expected 'gaps edge_gaps <on|off|toggle>' or "
		"'gaps <inner|outer> <current|all|workspace> <set|plus|minus n>'";
	const char *amount_str = argv[0];
	// gaps amount
	if (argc >= 1 && isdigit(*amount_str)) {
		int amount = (int)strtol(amount_str, NULL, 10);
		if (errno == ERANGE) {
			errno = 0;
			return cmd_results_new(CMD_INVALID, "gaps", "Number is out out of range.");
		}
		config->gaps_inner = config->gaps_outer = amount;
		arrange_windows(&root_container, -1, -1);
		return cmd_results_new(CMD_SUCCESS, NULL, NULL);
	}
	// gaps inner|outer n
	else if (argc >= 2 && isdigit((amount_str = argv[1])[0])) {
		int amount = (int)strtol(amount_str, NULL, 10);
		if (errno == ERANGE) {
			errno = 0;
			return cmd_results_new(CMD_INVALID, "gaps", "Number is out out of range.");
		}
		const char *target_str = argv[0];
		if (strcasecmp(target_str, "inner") == 0) {
			config->gaps_inner = amount;
		} else if (strcasecmp(target_str, "outer") == 0) {
			config->gaps_outer = amount;
		}
		arrange_windows(&root_container, -1, -1);
		return cmd_results_new(CMD_SUCCESS, NULL, NULL);
	} else if (argc == 2 && strcasecmp(argv[0], "edge_gaps") == 0) {
		// gaps edge_gaps <on|off|toggle>
		if (strcasecmp(argv[1], "toggle") == 0) {
			if (config->reading) {
				return cmd_results_new(CMD_FAILURE, "gaps edge_gaps toggle",
					"Can't be used in config file.");
			}
			config->edge_gaps = !config->edge_gaps;
		} else {
			config->edge_gaps =
				(strcasecmp(argv[1], "yes") == 0 || strcasecmp(argv[1], "on") == 0);
		}
		arrange_windows(&root_container, -1, -1);
		return cmd_results_new(CMD_SUCCESS, NULL, NULL);
	}
	// gaps inner|outer current|all set|plus|minus n
	if (argc < 4 || config->reading) {
		return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
	}
	// gaps inner|outer ...
	const char *inout_str = argv[0];
	enum {INNER, OUTER} inout;
	if (strcasecmp(inout_str, "inner") == 0) {
		inout = INNER;
	} else if (strcasecmp(inout_str, "outer") == 0) {
		inout = OUTER;
	} else {
		return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
	}

	// gaps ... current|all ...
	const char *target_str = argv[1];
	enum {CURRENT, WORKSPACE, ALL} target;
	if (strcasecmp(target_str, "current") == 0) {
		target = CURRENT;
	} else if (strcasecmp(target_str, "all") == 0) {
		target = ALL;
	} else if (strcasecmp(target_str, "workspace") == 0) {
		if (inout == OUTER) {
			target = CURRENT;
		} else {
			// Set gap for views in workspace
			target = WORKSPACE;
		}
	} else {
		return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
	}

	// gaps ... n
	amount_str = argv[3];
	int amount = (int)strtol(amount_str, NULL, 10);
	if (errno == ERANGE) {
		errno = 0;
		return cmd_results_new(CMD_INVALID, "gaps", "Number is out out of range.");
	}

	// gaps ... set|plus|minus ...
	const char *method_str = argv[2];
	enum {SET, ADD} method;
	if (strcasecmp(method_str, "set") == 0) {
		method = SET;
	} else if (strcasecmp(method_str, "plus") == 0) {
		method = ADD;
	} else if (strcasecmp(method_str, "minus") == 0) {
		method = ADD;
		amount *= -1;
	} else {
		return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
	}

	if (target == CURRENT) {
		swayc_t *cont;
		if (inout == OUTER) {
			if ((cont = swayc_active_workspace()) == NULL) {
				return cmd_results_new(CMD_FAILURE, "gaps", "There's no active workspace.");
			}
		} else {
			if ((cont = get_focused_view(&root_container))->type != C_VIEW) {
				return cmd_results_new(CMD_FAILURE, "gaps", "Currently focused item is not a view.");
			}
		}
		cont->gaps = swayc_gap(cont);
		if (method == SET) {
			cont->gaps = amount;
		} else if ((cont->gaps += amount) < 0) {
			cont->gaps = 0;
		}
		arrange_windows(cont->parent, -1, -1);
	} else if (inout == OUTER) {
		//resize all workspace.
		int i,j;
		for (i = 0; i < root_container.children->length; ++i) {
			swayc_t *op = root_container.children->items[i];
			for (j = 0; j < op->children->length; ++j) {
				swayc_t *ws = op->children->items[j];
				if (method == SET) {
					ws->gaps = amount;
				} else if ((ws->gaps += amount) < 0) {
					ws->gaps = 0;
				}
			}
		}
		arrange_windows(&root_container, -1, -1);
	} else {
		// Resize gaps for all views in workspace
		swayc_t *top;
		if (target == WORKSPACE) {
			if ((top = swayc_active_workspace()) == NULL) {
				return cmd_results_new(CMD_FAILURE, "gaps", "There's currently no active workspace.");
			}
		} else {
			top = &root_container;
		}
		int top_gap = top->gaps;
		container_map(top, method == SET ? set_gaps : add_gaps, &amount);
		top->gaps = top_gap;
		arrange_windows(top, -1, -1);
	}

	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}