parent
							
								
									1efd5f819f
								
							
						
					
					
						commit
						0c8491f7d0
					
				| @ -0,0 +1,56 @@ | ||||
| #ifndef _SWAY_VIEW_H | ||||
| #define _SWAY_VIEW_H | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/types/wlr_xdg_shell_v6.h> | ||||
| 
 | ||||
| struct sway_container; | ||||
| struct sway_view; | ||||
| 
 | ||||
| struct sway_xdg_surface_v6 { | ||||
| 	struct sway_view *view; | ||||
| 
 | ||||
| 	struct wl_listener commit; | ||||
| 	struct wl_listener request_move; | ||||
| 	struct wl_listener request_resize; | ||||
| 	struct wl_listener request_maximize; | ||||
| }; | ||||
| 
 | ||||
| enum sway_view_type { | ||||
| 	SWAY_WL_SHELL_VIEW, | ||||
| 	SWAY_XDG_SHELL_V6_VIEW, | ||||
| 	SWAY_XWAYLAND_VIEW, | ||||
| 	// Keep last
 | ||||
| 	SWAY_VIEW_TYPES, | ||||
| }; | ||||
| 
 | ||||
| enum sway_view_prop { | ||||
| 	VIEW_PROP_TITLE, | ||||
| 	VIEW_PROP_CLASS, | ||||
| 	VIEW_PROP_INSTANCE, | ||||
| 	VIEW_PROP_APP_ID, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * sway_view is a state container for surfaces that are arranged in the sway | ||||
|  * tree (shell surfaces). | ||||
|  */ | ||||
| struct sway_view { | ||||
| 	struct wl_listener destroy; | ||||
| 	enum sway_view_type type; | ||||
| 	struct sway_container *swayc; | ||||
| 
 | ||||
| 	union { | ||||
| 		struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; | ||||
| 	}; | ||||
| 
 | ||||
| 	union { | ||||
| 		struct sway_xdg_surface_v6 *sway_xdg_surface_v6; | ||||
| 	}; | ||||
| 
 | ||||
| 	struct { | ||||
| 		const char *(*get_prop)(struct sway_view *view, | ||||
| 				enum sway_view_prop prop); | ||||
| 	} iface; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,117 @@ | ||||
| #include <stdlib.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/types/wlr_xdg_shell_v6.h> | ||||
| #include "sway/commands.h" | ||||
| #include "sway/container.h" | ||||
| #include "sway/focus.h" | ||||
| #include "sway/ipc-server.h" | ||||
| #include "sway/server.h" | ||||
| #include "sway/view.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| // TODO: move elsewhere
 | ||||
| static void temp_ws_cleanup() { | ||||
| 	swayc_t *op, *ws; | ||||
| 	int i = 0, j; | ||||
| 	if (!root_container.children) | ||||
| 		return; | ||||
| 	while (i < root_container.children->length) { | ||||
| 		op = root_container.children->items[i++]; | ||||
| 		if (!op->children) | ||||
| 			continue; | ||||
| 		j = 0; | ||||
| 		while (j < op->children->length) { | ||||
| 			ws = op->children->items[j++]; | ||||
| 			if (ws->children->length == 0 && ws->floating->length == 0 && ws != op->focused) { | ||||
| 				if (destroy_workspace(ws)) { | ||||
| 					j--; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TODO: move elsewhere
 | ||||
| static swayc_t *move_focus_to_tiling(swayc_t *focused) { | ||||
| 	if (focused->is_floating) { | ||||
| 		if (focused->parent->children->length == 0) { | ||||
| 			return focused->parent; | ||||
| 		} | ||||
| 		// TODO find a better way of doing this
 | ||||
| 		// Or to focused container
 | ||||
| 		return get_focused_container(focused->parent->children->items[0]); | ||||
| 	} | ||||
| 	return focused; | ||||
| } | ||||
| 
 | ||||
| static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { | ||||
| 	if (!sway_assert(view->type == SWAY_XDG_SHELL_V6_VIEW, | ||||
| 				"xdg get_prop for non-xdg view!")) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	switch (prop) { | ||||
| 	case VIEW_PROP_TITLE: | ||||
| 		return view->wlr_xdg_surface_v6->title; | ||||
| 	case VIEW_PROP_APP_ID: | ||||
| 		return view->wlr_xdg_surface_v6->app_id; | ||||
| 	default: | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | ||||
| 	struct sway_server *server = wl_container_of( | ||||
| 			listener, server, xdg_shell_v6_surface); | ||||
| 	struct wlr_xdg_surface_v6 *xdg_surface = data; | ||||
| 
 | ||||
| 	if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | ||||
| 		// TODO: popups
 | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	sway_log(L_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", | ||||
| 			xdg_surface->title, xdg_surface->app_id); | ||||
| 	wlr_xdg_surface_v6_ping(xdg_surface); | ||||
| 
 | ||||
| 	struct sway_xdg_surface_v6 *sway_surface = | ||||
| 		calloc(1, sizeof(struct sway_xdg_surface_v6)); | ||||
| 	if (!sway_assert(sway_surface, "Failed to allocate surface!")) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct sway_view *sway_view = calloc(1, sizeof(struct sway_view)); | ||||
| 	if (!sway_assert(sway_view, "Failed to allocate view!")) { | ||||
| 		return; | ||||
| 	} | ||||
| 	sway_view->type = SWAY_XDG_SHELL_V6_VIEW; | ||||
| 	sway_view->iface.get_prop = get_prop; | ||||
| 	sway_surface->view = sway_view; | ||||
| 	 | ||||
| 	// TODO:
 | ||||
| 	// - Consolodate common logic between shells
 | ||||
| 	// - Wire up listeners
 | ||||
| 	// - Handle popups
 | ||||
| 	// - Look up pid and open on appropriate workspace
 | ||||
| 	// - Set new view to maximized so it behaves nicely
 | ||||
| 	// - Criteria
 | ||||
| 
 | ||||
| 	suspend_workspace_cleanup = true; | ||||
| 	//swayc_t *current_ws = swayc_active_workspace();
 | ||||
| 	swayc_t *prev_focus = get_focused_container(&root_container); | ||||
| 	swayc_t *focused = move_focus_to_tiling(prev_focus); | ||||
| 
 | ||||
| 	// TODO: fix new_view
 | ||||
| 	swayc_t *view = new_view(focused, sway_view); | ||||
| 	ipc_event_window(view, "new"); | ||||
| 	set_focused_container(view); | ||||
| 
 | ||||
| 	swayc_t *output = swayc_parent_by_type(view, C_OUTPUT); | ||||
| 	arrange_windows(output, -1, -1); | ||||
| 
 | ||||
| 	swayc_t *workspace = swayc_parent_by_type(focused, C_WORKSPACE); | ||||
| 	if (workspace && workspace->fullscreen) { | ||||
| 		set_focused_container(workspace->fullscreen); | ||||
| 	} | ||||
| 	suspend_workspace_cleanup = false; | ||||
| 	temp_ws_cleanup(); | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue