diff options
Diffstat (limited to 'sway/tree/container.c')
| -rw-r--r-- | sway/tree/container.c | 174 | 
1 files changed, 123 insertions, 51 deletions
| diff --git a/sway/tree/container.c b/sway/tree/container.c index 0c0684c0..d8ad3bc0 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -92,7 +92,7 @@ void container_begin_destroy(struct sway_container *con) {  	}  	// The workspace must have the fullscreen pointer cleared so that the  	// seat code can find an appropriate new focus. -	if (con->is_fullscreen && con->workspace) { +	if (con->fullscreen_mode == FULLSCREEN_WORKSPACE && con->workspace) {  		con->workspace->fullscreen = NULL;  	}  	wl_signal_emit(&con->node.events.destroy, &con->node); @@ -106,6 +106,10 @@ void container_begin_destroy(struct sway_container *con) {  		root_scratchpad_remove_container(con);  	} +	if (con->fullscreen_mode == FULLSCREEN_GLOBAL) { +		container_fullscreen_disable(con); +	} +  	if (con->parent || con->workspace) {  		container_detach(con);  	} @@ -840,15 +844,15 @@ void container_floating_move_to_center(struct sway_container *con) {  		return;  	}  	struct sway_workspace *ws = con->workspace; -	bool full = con->is_fullscreen; -	if (full) { -		container_set_fullscreen(con, false); +	enum sway_fullscreen_mode fullscreen_mode = con->fullscreen_mode; +	if (fullscreen_mode) { +		container_fullscreen_disable(con);  	}  	double new_lx = ws->x + (ws->width - con->width) / 2;  	double new_ly = ws->y + (ws->height - con->height) / 2;  	container_floating_translate(con, new_lx - con->x, new_ly - con->y); -	if (full) { -		container_set_fullscreen(con, true); +	if (fullscreen_mode) { +		container_set_fullscreen(con, fullscreen_mode);  	}  } @@ -877,59 +881,125 @@ static void set_fullscreen_iterator(struct sway_container *con, void *data) {  	}  } -void container_set_fullscreen(struct sway_container *container, bool enable) { -	if (container->is_fullscreen == enable) { +static void container_fullscreen_workspace(struct sway_container *con) { +	if (!sway_assert(con->fullscreen_mode == FULLSCREEN_NONE, +				"Expected a non-fullscreen container")) {  		return;  	} +	bool enable = true; +	set_fullscreen_iterator(con, &enable); +	container_for_each_child(con, set_fullscreen_iterator, &enable); -	struct sway_workspace *workspace = container->workspace; -	if (enable && workspace->fullscreen) { -		container_set_fullscreen(workspace->fullscreen, false); +	con->workspace->fullscreen = con; +	con->saved_x = con->x; +	con->saved_y = con->y; +	con->saved_width = con->width; +	con->saved_height = con->height; + +	struct sway_seat *seat; +	struct sway_workspace *focus_ws; +	wl_list_for_each(seat, &server.input->seats, link) { +		focus_ws = seat_get_focused_workspace(seat); +		if (focus_ws == con->workspace) { +			seat_set_focus_container(seat, con); +		}  	} -	set_fullscreen_iterator(container, &enable); -	container_for_each_child(container, set_fullscreen_iterator, &enable); +	con->fullscreen_mode = FULLSCREEN_WORKSPACE; +	container_end_mouse_operation(con); +	ipc_event_window(con, "fullscreen_mode"); +} + +static void container_fullscreen_global(struct sway_container *con) { +	if (!sway_assert(con->fullscreen_mode == FULLSCREEN_NONE, +				"Expected a non-fullscreen container")) { +		return; +	} +	bool enable = true; +	set_fullscreen_iterator(con, &enable); +	container_for_each_child(con, set_fullscreen_iterator, &enable); -	container->is_fullscreen = enable; +	root->fullscreen_global = con; +	con->saved_x = con->x; +	con->saved_y = con->y; +	con->saved_width = con->width; +	con->saved_height = con->height; -	if (enable) { -		workspace->fullscreen = container; -		container->saved_x = container->x; -		container->saved_y = container->y; -		container->saved_width = container->width; -		container->saved_height = container->height; - -		struct sway_seat *seat; -		struct sway_workspace *focus_ws; -		wl_list_for_each(seat, &server.input->seats, link) { -			focus_ws = seat_get_focused_workspace(seat); -			if (focus_ws) { -				if (focus_ws == workspace) { -					seat_set_focus_container(seat, container); -				} -			} +	struct sway_seat *seat; +	wl_list_for_each(seat, &server.input->seats, link) { +		struct sway_container *focus = seat_get_focused_container(seat); +		if (focus && focus != con) { +			seat_set_focus_container(seat, con);  		} -	} else { -		workspace->fullscreen = NULL; -		if (container_is_floating(container)) { -			container->x = container->saved_x; -			container->y = container->saved_y; -			container->width = container->saved_width; -			container->height = container->saved_height; -			struct sway_output *output = -				container_floating_find_output(container); -			if (workspace->output != output) { -				container_floating_move_to_center(container); +	} + +	con->fullscreen_mode = FULLSCREEN_GLOBAL; +	container_end_mouse_operation(con); +	ipc_event_window(con, "fullscreen_mode"); +} + +void container_fullscreen_disable(struct sway_container *con) { +	if (!sway_assert(con->fullscreen_mode != FULLSCREEN_NONE, +				"Expected a fullscreen container")) { +		return; +	} +	bool enable = false; +	set_fullscreen_iterator(con, &enable); +	container_for_each_child(con, set_fullscreen_iterator, &enable); + +	if (container_is_floating(con)) { +		con->x = con->saved_x; +		con->y = con->saved_y; +	} +	con->width = con->saved_width; +	con->height = con->saved_height; + +	if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { +		con->workspace->fullscreen = NULL; +		if (container_is_floating(con)) { +			struct sway_output *output = container_floating_find_output(con); +			if (con->workspace->output != output) { +				container_floating_move_to_center(con);  			} -		} else { -			container->width = container->saved_width; -			container->height = container->saved_height;  		} +	} else { +		root->fullscreen_global = NULL;  	} -	container_end_mouse_operation(container); +	con->fullscreen_mode = FULLSCREEN_NONE; +	container_end_mouse_operation(con); +	ipc_event_window(con, "fullscreen_mode"); +} + +void container_set_fullscreen(struct sway_container *con, +		enum sway_fullscreen_mode mode) { +	if (con->fullscreen_mode == mode) { +		return; +	} -	ipc_event_window(container, "fullscreen_mode"); +	switch (mode) { +	case FULLSCREEN_NONE: +		container_fullscreen_disable(con); +		break; +	case FULLSCREEN_WORKSPACE: +		if (root->fullscreen_global) { +			container_fullscreen_disable(root->fullscreen_global); +		} +		if (con->workspace->fullscreen) { +			container_fullscreen_disable(con->workspace->fullscreen); +		} +		container_fullscreen_workspace(con); +		break; +	case FULLSCREEN_GLOBAL: +		if (root->fullscreen_global) { +			container_fullscreen_disable(root->fullscreen_global); +		} +		if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { +			container_fullscreen_disable(con); +		} +		container_fullscreen_global(con); +		break; +	}  }  bool container_is_floating_or_child(struct sway_container *container) { @@ -941,7 +1011,7 @@ bool container_is_floating_or_child(struct sway_container *container) {  bool container_is_fullscreen_or_child(struct sway_container *container) {  	do { -		if (container->is_fullscreen) { +		if (container->fullscreen_mode) {  			return true;  		}  		container = container->parent; @@ -1111,12 +1181,12 @@ list_t *container_get_current_siblings(struct sway_container *container) {  }  void container_handle_fullscreen_reparent(struct sway_container *con) { -	if (!con->is_fullscreen || !con->workspace || +	if (con->fullscreen_mode != FULLSCREEN_WORKSPACE || !con->workspace ||  			con->workspace->fullscreen == con) {  		return;  	}  	if (con->workspace->fullscreen) { -		container_set_fullscreen(con->workspace->fullscreen, false); +		container_fullscreen_disable(con->workspace->fullscreen);  	}  	con->workspace->fullscreen = con; @@ -1171,9 +1241,12 @@ void container_add_child(struct sway_container *parent,  }  void container_detach(struct sway_container *child) { -	if (child->is_fullscreen) { +	if (child->fullscreen_mode == FULLSCREEN_WORKSPACE) {  		child->workspace->fullscreen = NULL;  	} +	if (child->fullscreen_mode == FULLSCREEN_GLOBAL) { +		root->fullscreen_global = NULL; +	}  	struct sway_container *old_parent = child->parent;  	struct sway_workspace *old_workspace = child->workspace; @@ -1387,4 +1460,3 @@ void container_raise_floating(struct sway_container *con) {  		node_set_dirty(&floater->workspace->node);  	}  } - | 
