diff options
| -rw-r--r-- | include/container.h | 5 | ||||
| -rw-r--r-- | sway/commands.c | 13 | ||||
| -rw-r--r-- | sway/container.c | 35 | ||||
| -rw-r--r-- | sway/handlers.c | 49 | ||||
| -rw-r--r-- | sway/layout.c | 11 | 
5 files changed, 99 insertions, 14 deletions
diff --git a/include/container.h b/include/container.h index 7560ddb8..3136e565 100644 --- a/include/container.h +++ b/include/container.h @@ -36,6 +36,9 @@ struct sway_container {  	// Not including borders or margins  	int width, height; +    // Used for setting floating geometry +    int desired_width, desired_height; +  	int x, y;  	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);  //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); +//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); diff --git a/sway/commands.c b/sway/commands.c index 91dfa2b2..8a81cd76 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -183,16 +183,19 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {  			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; +					// Try to use desired geometry to set w/h +					if (view->desired_width != -1) { +						view->width = view->desired_width; +					} +					if (view->desired_height != -1) { +						view->height = view->desired_height; +					}  					// 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); +					destroy_container(view->parent);  					// Set the new position of the container and arrange windows  					view->x = (active_workspace->width - view->width)/2; diff --git a/sway/container.c b/sway/container.c index 87e48e91..1f93d4dc 100644 --- a/sway/container.c +++ b/sway/container.c @@ -135,6 +135,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {  	view->name = strdup(title);  	view->visible = true; +	view->desired_width = -1; +	view->desired_height = -1; +  	// TODO: properly set this  	view->is_floating = false; @@ -149,6 +152,38 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {  	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) {  	if (output->children->length == 0) { diff --git a/sway/handlers.c b/sway/handlers.c index 3e83b850..85df09f7 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -10,6 +10,7 @@  #include "handlers.h"  #include "stringop.h"  #include "workspace.h" +#include "container.h"  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) {  	swayc_t *focused = get_focused_container(&root_container);  	uint32_t type = wlc_view_get_type(handle); -	//If override_redirect/unmanaged/popup/modal/splach +	// If override_redirect/unmanaged/popup/modal/splach  	if (type) {  		sway_log(L_DEBUG,"Unmanaged window of type %x left alone", type);  		wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);  		if (type & WLC_BIT_UNMANAGED) {  			return true;  		} -		//for things like Dmenu +		// For things like Dmenu  		if (type & WLC_BIT_OVERRIDE_REDIRECT) {  			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 {  		swayc_t *view = new_view(focused, handle);  		//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) {  	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 *parent;  	swayc_t *focused = get_focused_container(&root_container); @@ -135,8 +161,23 @@ static void handle_view_focus(wlc_handle view, bool focus) {  	return;  } -static void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry) { -	// deny that shit +static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry* geometry) { +	// 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) { diff --git a/sway/layout.c b/sway/layout.c index c53b9dad..1bc65050 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -73,11 +73,12 @@ swayc_t *remove_child(swayc_t *parent, swayc_t *child) {  				break;  			}  		} -	} -	for (i = 0; i < parent->children->length; ++i) { -		if (parent->children->items[i] == child) { -			list_del(parent->children, i); -			break; +	} else { +		for (i = 0; i < parent->children->length; ++i) { +			if (parent->children->items[i] == child) { +				list_del(parent->children, i); +				break; +			}  		}  	}  	if (parent->focused == child) {  | 
