mirror of
https://github.com/labwc/labwc.git
synced 2026-02-25 01:40:28 -05:00
view: decouple always-on-top windows from the omnipresent state
Before this commit, always-on-{top,bottom} windows were always visible
on all workspaces (omnipresent) because the they were not in
per-workspace trees like normal windows.
This commit fixes this by introducing per-layer trees in
`struct workspace`.
I also added `enum view_layer` and `view->layer` for simplicity.
This commit is contained in:
parent
155c153658
commit
a2eae22fc2
11 changed files with 85 additions and 96 deletions
|
|
@ -62,10 +62,7 @@ enum lab_view_criteria {
|
||||||
/* No filter -> all focusable views */
|
/* No filter -> all focusable views */
|
||||||
LAB_VIEW_CRITERIA_NONE = 0,
|
LAB_VIEW_CRITERIA_NONE = 0,
|
||||||
|
|
||||||
/*
|
/* Includes omnipresent (visible on all desktops) views */
|
||||||
* Includes always-on-top views, e.g.
|
|
||||||
* what is visible on the current workspace
|
|
||||||
*/
|
|
||||||
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
||||||
|
|
||||||
/* Positive criteria */
|
/* Positive criteria */
|
||||||
|
|
|
||||||
|
|
@ -224,17 +224,13 @@ struct server {
|
||||||
struct ssd_button *hovered_button;
|
struct ssd_button *hovered_button;
|
||||||
|
|
||||||
/* Tree for all non-layer xdg/xwayland-shell surfaces */
|
/* Tree for all non-layer xdg/xwayland-shell surfaces */
|
||||||
struct wlr_scene_tree *view_tree;
|
struct wlr_scene_tree *workspace_tree;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Popups need to be rendered above always-on-top views, so we reparent
|
* Popups need to be rendered above always-on-top views, so we reparent
|
||||||
* them to this dedicated tree
|
* them to this dedicated tree
|
||||||
*/
|
*/
|
||||||
struct wlr_scene_tree *xdg_popup_tree;
|
struct wlr_scene_tree *xdg_popup_tree;
|
||||||
|
|
||||||
/* Tree for all non-layer xdg/xwayland-shell surfaces with always-on-top/below */
|
|
||||||
struct wlr_scene_tree *view_tree_always_on_top;
|
|
||||||
struct wlr_scene_tree *view_tree_always_on_bottom;
|
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
/* Tree for unmanaged xsurfaces without initialized view (usually popups) */
|
/* Tree for unmanaged xsurfaces without initialized view (usually popups) */
|
||||||
struct wlr_scene_tree *unmanaged_tree;
|
struct wlr_scene_tree *unmanaged_tree;
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,12 @@ enum view_wants_focus {
|
||||||
VIEW_WANTS_FOCUS_UNLIKELY,
|
VIEW_WANTS_FOCUS_UNLIKELY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum view_layer {
|
||||||
|
VIEW_LAYER_NORMAL = 0,
|
||||||
|
VIEW_LAYER_ALWAYS_ON_TOP,
|
||||||
|
VIEW_LAYER_ALWAYS_ON_BOTTOM,
|
||||||
|
};
|
||||||
|
|
||||||
struct view;
|
struct view;
|
||||||
struct wlr_surface;
|
struct wlr_surface;
|
||||||
struct foreign_toplevel;
|
struct foreign_toplevel;
|
||||||
|
|
@ -183,6 +189,7 @@ struct view {
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool tearing_hint;
|
bool tearing_hint;
|
||||||
enum lab_tristate force_tearing;
|
enum lab_tristate force_tearing;
|
||||||
|
enum view_layer layer;
|
||||||
bool visible_on_all_workspaces;
|
bool visible_on_all_workspaces;
|
||||||
enum lab_edge tiled;
|
enum lab_edge tiled;
|
||||||
enum lab_edge edges_visible;
|
enum lab_edge edges_visible;
|
||||||
|
|
@ -526,9 +533,6 @@ void view_toggle_maximize(struct view *view, enum view_axis axis);
|
||||||
bool view_wants_decorations(struct view *view);
|
bool view_wants_decorations(struct view *view);
|
||||||
void view_toggle_decorations(struct view *view);
|
void view_toggle_decorations(struct view *view);
|
||||||
|
|
||||||
bool view_is_always_on_top(struct view *view);
|
|
||||||
bool view_is_always_on_bottom(struct view *view);
|
|
||||||
bool view_is_omnipresent(struct view *view);
|
|
||||||
void view_toggle_always_on_top(struct view *view);
|
void view_toggle_always_on_top(struct view *view);
|
||||||
void view_toggle_always_on_bottom(struct view *view);
|
void view_toggle_always_on_bottom(struct view *view);
|
||||||
void view_toggle_visible_on_all_workspaces(struct view *view);
|
void view_toggle_visible_on_all_workspaces(struct view *view);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ struct workspace {
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
|
struct wlr_scene_tree *view_trees[3];
|
||||||
|
|
||||||
struct lab_cosmic_workspace *cosmic_workspace;
|
struct lab_cosmic_workspace *cosmic_workspace;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
58
src/debug.c
58
src/debug.c
|
|
@ -88,33 +88,56 @@ get_view_part(struct view *view, struct wlr_scene_node *node)
|
||||||
return ssd_debug_get_node_name(view->ssd, node);
|
return ssd_debug_get_node_name(view->ssd, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct workspace *
|
||||||
|
get_workspace_from_node(struct server *server, struct wlr_scene_node *node)
|
||||||
|
{
|
||||||
|
struct workspace *workspace;
|
||||||
|
wl_list_for_each(workspace, &server->workspaces.all, link) {
|
||||||
|
if (&workspace->tree->node == node) {
|
||||||
|
return workspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
get_special(struct server *server, struct wlr_scene_node *node)
|
get_special(struct server *server, struct wlr_scene_node *node)
|
||||||
{
|
{
|
||||||
|
struct wlr_scene_tree *grand_parent =
|
||||||
|
node->parent ? node->parent->node.parent : NULL;
|
||||||
|
struct wlr_scene_tree *grand_grand_parent =
|
||||||
|
grand_parent ? grand_parent->node.parent : NULL;
|
||||||
if (node == &server->scene->tree.node) {
|
if (node == &server->scene->tree.node) {
|
||||||
return "server->scene";
|
return "server->scene";
|
||||||
}
|
}
|
||||||
if (node == &server->menu_tree->node) {
|
if (node == &server->menu_tree->node) {
|
||||||
return "server->menu_tree";
|
return "server->menu_tree";
|
||||||
}
|
}
|
||||||
if (node == &server->view_tree->node) {
|
if (node == &server->workspace_tree->node) {
|
||||||
return "server->view_tree";
|
return "server->workspace_tree";
|
||||||
}
|
}
|
||||||
if (node == &server->view_tree_always_on_bottom->node) {
|
if (node->parent == server->workspace_tree) {
|
||||||
return "server->always_on_bottom";
|
struct workspace *workspace = get_workspace_from_node(server, node);
|
||||||
}
|
if (workspace) {
|
||||||
if (node == &server->view_tree_always_on_top->node) {
|
return workspace->name;
|
||||||
return "server->always_on_top";
|
|
||||||
}
|
|
||||||
if (node->parent == server->view_tree) {
|
|
||||||
struct workspace *workspace;
|
|
||||||
wl_list_for_each(workspace, &server->workspaces.all, link) {
|
|
||||||
if (&workspace->tree->node == node) {
|
|
||||||
return workspace->name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return "unknown workspace";
|
return "unknown workspace";
|
||||||
}
|
}
|
||||||
|
if (grand_parent == server->workspace_tree) {
|
||||||
|
struct workspace *workspace =
|
||||||
|
get_workspace_from_node(server, &node->parent->node);
|
||||||
|
if (workspace) {
|
||||||
|
struct wlr_scene_tree **trees = workspace->view_trees;
|
||||||
|
if (node == &trees[VIEW_LAYER_NORMAL]->node) {
|
||||||
|
return "normal";
|
||||||
|
} else if (node == &trees[VIEW_LAYER_ALWAYS_ON_TOP]->node) {
|
||||||
|
return "always_on_top";
|
||||||
|
} else if (node == &trees[VIEW_LAYER_ALWAYS_ON_BOTTOM]->node) {
|
||||||
|
return "always_on_bottom";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown tree";
|
||||||
|
}
|
||||||
if (node->parent == &server->scene->tree) {
|
if (node->parent == &server->scene->tree) {
|
||||||
struct output *output;
|
struct output *output;
|
||||||
wl_list_for_each(output, &server->outputs, link) {
|
wl_list_for_each(output, &server->outputs, link) {
|
||||||
|
|
@ -160,12 +183,7 @@ get_special(struct server *server, struct wlr_scene_node *node)
|
||||||
return "server->unmanaged_tree";
|
return "server->unmanaged_tree";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
struct wlr_scene_tree *grand_parent =
|
if (grand_grand_parent == server->workspace_tree && node->data) {
|
||||||
node->parent ? node->parent->node.parent : NULL;
|
|
||||||
if (grand_parent == server->view_tree && node->data) {
|
|
||||||
last_view = node_view_from_node(node);
|
|
||||||
}
|
|
||||||
if (node->parent == server->view_tree_always_on_top && node->data) {
|
|
||||||
last_view = node_view_from_node(node);
|
last_view = node_view_from_node(node);
|
||||||
}
|
}
|
||||||
const char *view_part = get_view_part(last_view, node);
|
const char *view_part = get_view_part(last_view, node);
|
||||||
|
|
|
||||||
|
|
@ -96,9 +96,9 @@ desktop_focus_view(struct view *view, bool raise)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Switch workspace if necessary to make the view visible
|
* Switch workspace if necessary to make the view visible
|
||||||
* (unnecessary for "always on {top,bottom}" views).
|
* (unnecessary for omnipresent views).
|
||||||
*/
|
*/
|
||||||
if (!view_is_always_on_top(view) && !view_is_always_on_bottom(view)) {
|
if (!view->visible_on_all_workspaces) {
|
||||||
workspaces_switch_to(view->workspace, /*update_focus*/ false);
|
workspaces_switch_to(view->workspace, /*update_focus*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
src/server.c
12
src/server.c
|
|
@ -576,16 +576,16 @@ server_init(struct server *server)
|
||||||
* | output->layer_tree[2] | top layer surfaces (e.g. waybar)
|
* | output->layer_tree[2] | top layer surfaces (e.g. waybar)
|
||||||
* | server->unmanaged_tree | unmanaged X11 surfaces (e.g. dmenu)
|
* | server->unmanaged_tree | unmanaged X11 surfaces (e.g. dmenu)
|
||||||
* | server->xdg_popup_tree | xdg popups on xdg windows
|
* | server->xdg_popup_tree | xdg popups on xdg windows
|
||||||
* | server->view_tree_always_on_top | always-on-top xdg/X11 windows
|
* | server->workspace_tree |
|
||||||
* | server->view_tree | normal xdg/X11 windows (e.g. firefox)
|
* | + workspace->tree |
|
||||||
* | server->view_tree_always_on_bottom | always-on-bottom xdg/X11 windows
|
* | + workspace->view_trees[1] | always-on-top xdg/X11 windows
|
||||||
|
* | + workspace->view_trees[0] | normal xdg/X11 windows (e.g. firefox)
|
||||||
|
* | + workspace->view_trees[2] | always-on-bottom xdg/X11 windows
|
||||||
* | output->layer_tree[1] | bottom layer surfaces
|
* | output->layer_tree[1] | bottom layer surfaces
|
||||||
* | output->layer_tree[0] | background layer surfaces (e.g. swaybg)
|
* | output->layer_tree[0] | background layer surfaces (e.g. swaybg)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
server->view_tree_always_on_bottom = wlr_scene_tree_create(&server->scene->tree);
|
server->workspace_tree = wlr_scene_tree_create(&server->scene->tree);
|
||||||
server->view_tree = wlr_scene_tree_create(&server->scene->tree);
|
|
||||||
server->view_tree_always_on_top = wlr_scene_tree_create(&server->scene->tree);
|
|
||||||
server->xdg_popup_tree = wlr_scene_tree_create(&server->scene->tree);
|
server->xdg_popup_tree = wlr_scene_tree_create(&server->scene->tree);
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
server->unmanaged_tree = wlr_scene_tree_create(&server->scene->tree);
|
server->unmanaged_tree = wlr_scene_tree_create(&server->scene->tree);
|
||||||
|
|
|
||||||
58
src/view.c
58
src/view.c
|
|
@ -268,13 +268,7 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
||||||
/*
|
if (view->workspace != view->server->workspaces.current) {
|
||||||
* Always-on-top views are always on the current desktop and are
|
|
||||||
* special in that they live in a different tree.
|
|
||||||
*/
|
|
||||||
struct server *server = view->server;
|
|
||||||
if (view->scene_tree->node.parent != server->workspaces.current->tree
|
|
||||||
&& !view_is_always_on_top(view)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +278,7 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (criteria & LAB_VIEW_CRITERIA_ALWAYS_ON_TOP) {
|
if (criteria & LAB_VIEW_CRITERIA_ALWAYS_ON_TOP) {
|
||||||
if (!view_is_always_on_top(view)) {
|
if (view->layer != VIEW_LAYER_ALWAYS_ON_TOP) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +288,7 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (criteria & LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP) {
|
if (criteria & LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP) {
|
||||||
if (view_is_always_on_top(view)) {
|
if (view->layer == VIEW_LAYER_ALWAYS_ON_TOP) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -304,11 +298,7 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (criteria & LAB_VIEW_CRITERIA_NO_OMNIPRESENT) {
|
if (criteria & LAB_VIEW_CRITERIA_NO_OMNIPRESENT) {
|
||||||
/*
|
if (view->visible_on_all_workspaces) {
|
||||||
* TODO: Once always-on-top views use a per-workspace
|
|
||||||
* sub-tree we can remove the check from this condition.
|
|
||||||
*/
|
|
||||||
if (view->visible_on_all_workspaces || view_is_always_on_top(view)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1547,48 +1537,30 @@ view_toggle_decorations(struct view *view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
view_is_always_on_top(struct view *view)
|
|
||||||
{
|
|
||||||
assert(view);
|
|
||||||
return view->scene_tree->node.parent ==
|
|
||||||
view->server->view_tree_always_on_top;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
view_toggle_always_on_top(struct view *view)
|
view_toggle_always_on_top(struct view *view)
|
||||||
{
|
{
|
||||||
assert(view);
|
assert(view);
|
||||||
if (view_is_always_on_top(view)) {
|
if (view->layer == VIEW_LAYER_ALWAYS_ON_TOP) {
|
||||||
view->workspace = view->server->workspaces.current;
|
view->layer = VIEW_LAYER_NORMAL;
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node,
|
|
||||||
view->workspace->tree);
|
|
||||||
} else {
|
} else {
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node,
|
view->layer = VIEW_LAYER_ALWAYS_ON_TOP;
|
||||||
view->server->view_tree_always_on_top);
|
|
||||||
}
|
}
|
||||||
}
|
wlr_scene_node_reparent(&view->scene_tree->node,
|
||||||
|
view->workspace->view_trees[view->layer]);
|
||||||
bool
|
|
||||||
view_is_always_on_bottom(struct view *view)
|
|
||||||
{
|
|
||||||
assert(view);
|
|
||||||
return view->scene_tree->node.parent ==
|
|
||||||
view->server->view_tree_always_on_bottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
view_toggle_always_on_bottom(struct view *view)
|
view_toggle_always_on_bottom(struct view *view)
|
||||||
{
|
{
|
||||||
assert(view);
|
assert(view);
|
||||||
if (view_is_always_on_bottom(view)) {
|
if (view->layer == VIEW_LAYER_ALWAYS_ON_BOTTOM) {
|
||||||
view->workspace = view->server->workspaces.current;
|
view->layer = VIEW_LAYER_NORMAL;
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node,
|
|
||||||
view->workspace->tree);
|
|
||||||
} else {
|
} else {
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node,
|
view->layer = VIEW_LAYER_ALWAYS_ON_BOTTOM;
|
||||||
view->server->view_tree_always_on_bottom);
|
|
||||||
}
|
}
|
||||||
|
wlr_scene_node_reparent(&view->scene_tree->node,
|
||||||
|
view->workspace->view_trees[view->layer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1607,7 +1579,7 @@ view_move_to_workspace(struct view *view, struct workspace *workspace)
|
||||||
if (view->workspace != workspace) {
|
if (view->workspace != workspace) {
|
||||||
view->workspace = workspace;
|
view->workspace = workspace;
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node,
|
wlr_scene_node_reparent(&view->scene_tree->node,
|
||||||
workspace->tree);
|
workspace->view_trees[view->layer]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,13 @@ add_workspace(struct server *server, const char *name)
|
||||||
struct workspace *workspace = znew(*workspace);
|
struct workspace *workspace = znew(*workspace);
|
||||||
workspace->server = server;
|
workspace->server = server;
|
||||||
workspace->name = xstrdup(name);
|
workspace->name = xstrdup(name);
|
||||||
workspace->tree = wlr_scene_tree_create(server->view_tree);
|
workspace->tree = wlr_scene_tree_create(server->workspace_tree);
|
||||||
|
workspace->view_trees[VIEW_LAYER_ALWAYS_ON_BOTTOM] =
|
||||||
|
wlr_scene_tree_create(workspace->tree);
|
||||||
|
workspace->view_trees[VIEW_LAYER_NORMAL] =
|
||||||
|
wlr_scene_tree_create(workspace->tree);
|
||||||
|
workspace->view_trees[VIEW_LAYER_ALWAYS_ON_TOP] =
|
||||||
|
wlr_scene_tree_create(workspace->tree);
|
||||||
wl_list_append(&server->workspaces.all, &workspace->link);
|
wl_list_append(&server->workspaces.all, &workspace->link);
|
||||||
wlr_scene_node_set_enabled(&workspace->tree->node, false);
|
wlr_scene_node_set_enabled(&workspace->tree->node, false);
|
||||||
|
|
||||||
|
|
@ -483,24 +489,17 @@ workspaces_switch_to(struct workspace *target, bool update_focus)
|
||||||
server->workspaces.current = target;
|
server->workspaces.current = target;
|
||||||
|
|
||||||
struct view *grabbed_view = server->grabbed_view;
|
struct view *grabbed_view = server->grabbed_view;
|
||||||
if (grabbed_view && !view_is_always_on_top(grabbed_view)) {
|
if (grabbed_view) {
|
||||||
view_move_to_workspace(grabbed_view, target);
|
view_move_to_workspace(grabbed_view, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure we are focusing what the user sees. Only refocus if
|
* Make sure we are focusing what the user sees. Only refocus if
|
||||||
* the focus is not already on an omnipresent or always-on-top view.
|
* the focus is not already on an omnipresent view.
|
||||||
*
|
|
||||||
* TODO: Decouple always-on-top views from the omnipresent state.
|
|
||||||
* One option for that would be to create a new scene tree
|
|
||||||
* as child of every workspace tree and then reparent a-o-t
|
|
||||||
* windows to that one. Combined with adjusting the condition
|
|
||||||
* below that should take care of the issue.
|
|
||||||
*/
|
*/
|
||||||
if (update_focus) {
|
if (update_focus) {
|
||||||
struct view *active_view = server->active_view;
|
struct view *active_view = server->active_view;
|
||||||
if (!active_view || (!active_view->visible_on_all_workspaces
|
if (!(active_view && active_view->visible_on_all_workspaces)) {
|
||||||
&& !view_is_always_on_top(active_view))) {
|
|
||||||
desktop_focus_topmost_view(server);
|
desktop_focus_topmost_view(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1019,7 +1019,8 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
view->workspace = server->workspaces.current;
|
view->workspace = server->workspaces.current;
|
||||||
view->scene_tree = wlr_scene_tree_create(view->workspace->tree);
|
view->scene_tree = wlr_scene_tree_create(
|
||||||
|
view->workspace->view_trees[VIEW_LAYER_NORMAL]);
|
||||||
wlr_scene_node_set_enabled(&view->scene_tree->node, false);
|
wlr_scene_node_set_enabled(&view->scene_tree->node, false);
|
||||||
|
|
||||||
struct wlr_scene_tree *tree = wlr_scene_xdg_surface_create(
|
struct wlr_scene_tree *tree = wlr_scene_xdg_surface_create(
|
||||||
|
|
|
||||||
|
|
@ -1018,7 +1018,8 @@ xwayland_view_create(struct server *server,
|
||||||
xsurface->data = view;
|
xsurface->data = view;
|
||||||
|
|
||||||
view->workspace = server->workspaces.current;
|
view->workspace = server->workspaces.current;
|
||||||
view->scene_tree = wlr_scene_tree_create(view->workspace->tree);
|
view->scene_tree = wlr_scene_tree_create(
|
||||||
|
view->workspace->view_trees[VIEW_LAYER_NORMAL]);
|
||||||
node_descriptor_create(&view->scene_tree->node,
|
node_descriptor_create(&view->scene_tree->node,
|
||||||
LAB_NODE_VIEW, view, /*data*/ NULL);
|
LAB_NODE_VIEW, view, /*data*/ NULL);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue