Keep an up-to-date wlr scene-graph
At the moment it isn't used at all and a lot of data is duplicated. This is a temporary state introduced for nicer diff separation into several commits.
This commit is contained in:
parent
8c191d2d41
commit
f144eb1438
16 changed files with 336 additions and 20 deletions
|
@ -9,23 +9,33 @@
|
|||
#define KIWMI_DESKTOP_DESKTOP_H
|
||||
|
||||
#include <wayland-server.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
#include "desktop/stratum.h"
|
||||
|
||||
struct kiwmi_desktop {
|
||||
struct wlr_compositor *compositor;
|
||||
|
||||
struct wlr_xdg_shell *xdg_shell;
|
||||
struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager;
|
||||
struct wlr_layer_shell_v1 *layer_shell;
|
||||
|
||||
struct wlr_data_device_manager *data_device_manager;
|
||||
|
||||
struct wlr_output_layout *output_layout;
|
||||
struct wl_list outputs; // struct kiwmi_output::link
|
||||
struct wl_list views; // struct kiwmi_view::link
|
||||
|
||||
float bg_color[4];
|
||||
struct wlr_scene *scene;
|
||||
struct wlr_scene_rect *background_rect;
|
||||
struct wlr_scene_tree *strata[KIWMI_STRATA_COUNT];
|
||||
|
||||
struct wl_listener xdg_shell_new_surface;
|
||||
struct wl_listener xdg_toplevel_new_decoration;
|
||||
struct wl_listener layer_shell_new_surface;
|
||||
struct wl_listener new_output;
|
||||
struct wl_listener output_layout_change;
|
||||
|
||||
struct {
|
||||
struct wl_signal new_output;
|
||||
|
|
27
include/desktop/desktop_surface.h
Normal file
27
include/desktop/desktop_surface.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* Copyright (c), Niclas Meyer <niclas@countingsort.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef KIWMI_DESKTOP_DESKTOP_SURFACE_H
|
||||
#define KIWMI_DESKTOP_DESKTOP_SURFACE_H
|
||||
|
||||
enum kiwmi_desktop_surface_type {
|
||||
KIWMI_DESKTOP_SURFACE_VIEW,
|
||||
KIWMI_DESKTOP_SURFACE_LAYER,
|
||||
};
|
||||
|
||||
struct kiwmi_desktop_surface {
|
||||
// The tree is where the config is supposed to put custom decorations (it
|
||||
// also contains the surface_node)
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_node *surface_node;
|
||||
|
||||
struct wlr_scene_tree *popups_tree;
|
||||
|
||||
enum kiwmi_desktop_surface_type type;
|
||||
};
|
||||
|
||||
#endif /* KIWMI_DESKTOP_DESKTOP_SURFACE_H */
|
|
@ -14,10 +14,13 @@
|
|||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/box.h>
|
||||
|
||||
#include "desktop/desktop_surface.h"
|
||||
#include "desktop/output.h"
|
||||
|
||||
struct kiwmi_layer {
|
||||
struct wl_list link;
|
||||
struct kiwmi_desktop_surface desktop_surface;
|
||||
|
||||
struct wlr_layer_surface_v1 *layer_surface;
|
||||
uint32_t layer; // enum zwlr_layer_shell_v1_layer
|
||||
|
||||
|
|
|
@ -11,16 +11,21 @@
|
|||
#include <wayland-server.h>
|
||||
#include <wlr/util/box.h>
|
||||
|
||||
#include "desktop/stratum.h"
|
||||
|
||||
struct kiwmi_output {
|
||||
struct wl_list link;
|
||||
struct kiwmi_desktop *desktop;
|
||||
struct wlr_output *wlr_output;
|
||||
|
||||
struct wl_listener frame;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener mode;
|
||||
|
||||
struct wl_list layers[4]; // struct kiwmi_layer_surface::link
|
||||
struct wl_list layers[4]; // struct kiwmi_layer::link
|
||||
struct wlr_scene_tree *strata[KIWMI_STRATA_COUNT];
|
||||
|
||||
struct wlr_box usable_area;
|
||||
|
||||
int damaged;
|
||||
|
@ -42,6 +47,7 @@ struct kiwmi_render_data {
|
|||
};
|
||||
|
||||
void new_output_notify(struct wl_listener *listener, void *data);
|
||||
void output_layout_change_notify(struct wl_listener *listener, void *data);
|
||||
|
||||
void output_damage(struct kiwmi_output *output);
|
||||
|
||||
|
|
20
include/desktop/popup.h
Normal file
20
include/desktop/popup.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (c), Niclas Meyer <niclas@countingsort.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef KIWMI_DESKTOP_POPUP_H
|
||||
#define KIWMI_DESKTOP_POPUP_H
|
||||
|
||||
struct wlr_xdg_popup;
|
||||
struct kiwmi_desktop_surface;
|
||||
|
||||
struct kiwmi_desktop_surface *
|
||||
popup_get_desktop_surface(struct wlr_xdg_popup *popup);
|
||||
void popup_attach(
|
||||
struct wlr_xdg_popup *popup,
|
||||
struct kiwmi_desktop_surface *desktop_surface);
|
||||
|
||||
#endif /* KIWMI_DESKTOP_POPUP_H */
|
|
@ -17,6 +17,8 @@
|
|||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/edges.h>
|
||||
|
||||
#include "desktop/desktop_surface.h"
|
||||
|
||||
enum kiwmi_view_prop {
|
||||
KIWMI_VIEW_PROP_APP_ID,
|
||||
KIWMI_VIEW_PROP_TITLE,
|
||||
|
@ -29,6 +31,7 @@ enum kiwmi_view_type {
|
|||
struct kiwmi_view {
|
||||
struct wl_list link;
|
||||
struct wl_list children; // struct kiwmi_view_child::link
|
||||
struct kiwmi_desktop_surface desktop_surface;
|
||||
|
||||
struct kiwmi_desktop *desktop;
|
||||
|
||||
|
@ -143,6 +146,7 @@ void view_set_activated(struct kiwmi_view *view, bool activated);
|
|||
void view_set_size(struct kiwmi_view *view, uint32_t width, uint32_t height);
|
||||
void view_set_pos(struct kiwmi_view *view, uint32_t x, uint32_t y);
|
||||
void view_set_tiled(struct kiwmi_view *view, enum wlr_edges edges);
|
||||
void view_set_hidden(struct kiwmi_view *view, bool hidden);
|
||||
struct wlr_surface *view_surface_at(
|
||||
struct kiwmi_view *view,
|
||||
double sx,
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "desktop/layer_shell.h"
|
||||
#include "desktop/output.h"
|
||||
#include "desktop/stratum.h"
|
||||
#include "desktop/view.h"
|
||||
#include "desktop/xdg_shell.h"
|
||||
#include "input/cursor.h"
|
||||
|
@ -49,6 +51,25 @@ desktop_init(struct kiwmi_desktop *desktop)
|
|||
desktop->bg_color[2] = 0.1f;
|
||||
desktop->bg_color[3] = 1.0f;
|
||||
|
||||
desktop->scene = wlr_scene_create();
|
||||
if (!desktop->scene) {
|
||||
wlr_log(WLR_ERROR, "failed to create scene");
|
||||
return false;
|
||||
}
|
||||
|
||||
const float bg_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
desktop->background_rect =
|
||||
wlr_scene_rect_create(&desktop->scene->node, 0, 0, bg_color);
|
||||
// No point in showing black
|
||||
wlr_scene_node_set_enabled(&desktop->background_rect->node, false);
|
||||
|
||||
// Create a scene-graph tree for each stratum
|
||||
for (size_t i = 0; i < KIWMI_STRATA_COUNT; ++i) {
|
||||
desktop->strata[i] = wlr_scene_tree_create(&desktop->scene->node);
|
||||
}
|
||||
|
||||
wlr_scene_attach_output_layout(desktop->scene, desktop->output_layout);
|
||||
|
||||
desktop->xdg_shell = wlr_xdg_shell_create(server->wl_display);
|
||||
desktop->xdg_shell_new_surface.notify = xdg_shell_new_surface_notify;
|
||||
wl_signal_add(
|
||||
|
@ -75,6 +96,10 @@ desktop_init(struct kiwmi_desktop *desktop)
|
|||
desktop->new_output.notify = new_output_notify;
|
||||
wl_signal_add(&server->backend->events.new_output, &desktop->new_output);
|
||||
|
||||
desktop->output_layout_change.notify = output_layout_change_notify;
|
||||
wl_signal_add(
|
||||
&desktop->output_layout->events.change, &desktop->output_layout_change);
|
||||
|
||||
wl_signal_init(&desktop->events.new_output);
|
||||
wl_signal_init(&desktop->events.view_map);
|
||||
wl_signal_init(&desktop->events.request_active_output);
|
||||
|
@ -87,6 +112,8 @@ desktop_fini(struct kiwmi_desktop *desktop)
|
|||
{
|
||||
wlr_output_layout_destroy(desktop->output_layout);
|
||||
desktop->output_layout = NULL;
|
||||
wlr_scene_node_destroy(&desktop->scene->node);
|
||||
desktop->scene = NULL;
|
||||
}
|
||||
|
||||
struct kiwmi_output *
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#include <wlr/util/log.h>
|
||||
|
||||
#include "desktop/desktop.h"
|
||||
#include "desktop/desktop_surface.h"
|
||||
#include "desktop/output.h"
|
||||
#include "desktop/stratum.h"
|
||||
#include "input/seat.h"
|
||||
#include "server.h"
|
||||
|
||||
|
@ -24,6 +26,9 @@ kiwmi_layer_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
{
|
||||
struct kiwmi_layer *layer = wl_container_of(listener, layer, destroy);
|
||||
|
||||
wlr_scene_node_destroy(&layer->desktop_surface.tree->node);
|
||||
wlr_scene_node_destroy(&layer->desktop_surface.popups_tree->node);
|
||||
|
||||
wl_list_remove(&layer->destroy.link);
|
||||
wl_list_remove(&layer->map.link);
|
||||
wl_list_remove(&layer->unmap.link);
|
||||
|
@ -42,25 +47,22 @@ kiwmi_layer_commit_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
struct kiwmi_layer *layer = wl_container_of(listener, layer, commit);
|
||||
struct kiwmi_output *output = layer->output;
|
||||
|
||||
struct wlr_box old_geom = layer->geom;
|
||||
|
||||
if (layer->layer_surface->current.committed != 0) {
|
||||
arrange_layers(output);
|
||||
}
|
||||
|
||||
bool layer_changed = layer->layer != layer->layer_surface->current.layer;
|
||||
bool geom_changed = memcmp(&old_geom, &layer->geom, sizeof(old_geom)) != 0;
|
||||
bool buffer_changed = pixman_region32_not_empty(
|
||||
&layer->layer_surface->surface->buffer_damage);
|
||||
|
||||
if (layer_changed) {
|
||||
if (layer->layer != layer->layer_surface->current.layer) {
|
||||
wl_list_remove(&layer->link);
|
||||
layer->layer = layer->layer_surface->current.layer;
|
||||
wl_list_insert(&output->layers[layer->layer], &layer->link);
|
||||
|
||||
enum kiwmi_stratum new_stratum =
|
||||
stratum_from_layer_shell_layer(layer->layer);
|
||||
|
||||
wlr_scene_node_reparent(
|
||||
&layer->desktop_surface.tree->node,
|
||||
&output->strata[new_stratum]->node);
|
||||
}
|
||||
|
||||
if (buffer_changed || layer_changed || geom_changed) {
|
||||
if (layer->layer_surface->current.committed != 0) {
|
||||
output_damage(layer->output);
|
||||
arrange_layers(output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +71,10 @@ kiwmi_layer_map_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
{
|
||||
struct kiwmi_layer *layer = wl_container_of(listener, layer, map);
|
||||
|
||||
wlr_scene_node_set_enabled(&layer->desktop_surface.tree->node, true);
|
||||
wlr_scene_node_set_enabled(&layer->desktop_surface.popups_tree->node, true);
|
||||
|
||||
arrange_layers(layer->output);
|
||||
output_damage(layer->output);
|
||||
}
|
||||
|
||||
|
@ -77,6 +83,11 @@ kiwmi_layer_unmap_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
{
|
||||
struct kiwmi_layer *layer = wl_container_of(listener, layer, unmap);
|
||||
|
||||
wlr_scene_node_set_enabled(&layer->desktop_surface.tree->node, false);
|
||||
wlr_scene_node_set_enabled(
|
||||
&layer->desktop_surface.popups_tree->node, false);
|
||||
|
||||
arrange_layers(layer->output);
|
||||
output_damage(layer->output);
|
||||
}
|
||||
|
||||
|
@ -245,6 +256,13 @@ arrange_layer(
|
|||
|
||||
layer->geom = arranged_area;
|
||||
|
||||
wlr_scene_node_set_position(
|
||||
&layer->desktop_surface.tree->node, layer->geom.x, layer->geom.y);
|
||||
wlr_scene_node_set_position(
|
||||
&layer->desktop_surface.popups_tree->node,
|
||||
layer->geom.x,
|
||||
layer->geom.y);
|
||||
|
||||
apply_exclusive(
|
||||
usable_area,
|
||||
state->anchor,
|
||||
|
@ -415,6 +433,8 @@ layer_shell_new_surface_notify(struct wl_listener *listener, void *data)
|
|||
layer->output = output;
|
||||
layer->layer = layer_surface->current.layer;
|
||||
|
||||
layer->desktop_surface.type = KIWMI_DESKTOP_SURFACE_LAYER;
|
||||
|
||||
layer->destroy.notify = kiwmi_layer_destroy_notify;
|
||||
wl_signal_add(&layer_surface->events.destroy, &layer->destroy);
|
||||
|
||||
|
@ -427,10 +447,25 @@ layer_shell_new_surface_notify(struct wl_listener *listener, void *data)
|
|||
layer->unmap.notify = kiwmi_layer_unmap_notify;
|
||||
wl_signal_add(&layer_surface->events.unmap, &layer->unmap);
|
||||
|
||||
layer_surface->data = layer;
|
||||
|
||||
enum kiwmi_stratum stratum = stratum_from_layer_shell_layer(layer->layer);
|
||||
|
||||
layer->desktop_surface.tree =
|
||||
wlr_scene_tree_create(&output->strata[stratum]->node);
|
||||
layer->desktop_surface.popups_tree =
|
||||
wlr_scene_tree_create(&output->strata[KIWMI_STRATUM_POPUPS]->node);
|
||||
layer->desktop_surface.surface_node = wlr_scene_subsurface_tree_create(
|
||||
&layer->desktop_surface.tree->node, layer->layer_surface->surface);
|
||||
|
||||
wlr_scene_node_set_enabled(&layer->desktop_surface.tree->node, false);
|
||||
wlr_scene_node_set_enabled(
|
||||
&layer->desktop_surface.popups_tree->node, false);
|
||||
|
||||
wl_list_insert(&output->layers[layer->layer], &layer->link);
|
||||
|
||||
// Temporarily set the layer's current state to pending
|
||||
// So that we can easily arrange it
|
||||
// so that we can easily arrange it
|
||||
struct wlr_layer_surface_v1_state old_state = layer_surface->current;
|
||||
layer_surface->current = layer_surface->pending;
|
||||
arrange_layers(output);
|
||||
|
|
|
@ -276,6 +276,12 @@ output_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
}
|
||||
}
|
||||
|
||||
if (output->desktop->scene) {
|
||||
for (size_t i = 0; i < KIWMI_STRATA_COUNT; ++i) {
|
||||
wlr_scene_node_destroy(&output->strata[i]->node);
|
||||
}
|
||||
}
|
||||
|
||||
if (output->desktop->output_layout) {
|
||||
wlr_output_layout_remove(
|
||||
output->desktop->output_layout, output->wlr_output);
|
||||
|
@ -382,15 +388,23 @@ new_output_notify(struct wl_listener *listener, void *data)
|
|||
|
||||
wlr_output_create_global(wlr_output);
|
||||
|
||||
size_t len_outputs = sizeof(output->layers) / sizeof(output->layers[0]);
|
||||
for (size_t i = 0; i < len_outputs; ++i) {
|
||||
size_t len_layers = sizeof(output->layers) / sizeof(output->layers[0]);
|
||||
for (size_t i = 0; i < len_layers; ++i) {
|
||||
wl_list_init(&output->layers[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < KIWMI_STRATA_COUNT; ++i) {
|
||||
output->strata[i] = wlr_scene_tree_create(&desktop->strata[i]->node);
|
||||
}
|
||||
|
||||
wl_signal_init(&output->events.destroy);
|
||||
wl_signal_init(&output->events.resize);
|
||||
wl_signal_init(&output->events.usable_area_change);
|
||||
|
||||
wl_list_insert(&desktop->outputs, &output->link);
|
||||
|
||||
wlr_output_layout_add_auto(desktop->output_layout, wlr_output);
|
||||
|
||||
wl_signal_emit(&desktop->events.new_output, output);
|
||||
}
|
||||
|
||||
|
@ -401,3 +415,32 @@ output_damage(struct kiwmi_output *output)
|
|||
output->damaged = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
output_layout_change_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||
{
|
||||
struct kiwmi_desktop *desktop =
|
||||
wl_container_of(listener, desktop, output_layout_change);
|
||||
|
||||
struct wlr_box *ol_box =
|
||||
wlr_output_layout_get_box(desktop->output_layout, NULL);
|
||||
wlr_scene_node_set_position(
|
||||
&desktop->background_rect->node, ol_box->x, ol_box->y);
|
||||
wlr_scene_rect_set_size(
|
||||
desktop->background_rect, ol_box->width, ol_box->height);
|
||||
|
||||
struct wlr_output_layout_output *ol_output;
|
||||
wl_list_for_each (ol_output, &desktop->output_layout->outputs, link) {
|
||||
struct kiwmi_output *output = ol_output->output->data;
|
||||
|
||||
struct wlr_box *box = wlr_output_layout_get_box(
|
||||
desktop->output_layout, output->wlr_output);
|
||||
|
||||
for (size_t i = 0; i < KIWMI_STRATA_COUNT; ++i) {
|
||||
if (output->strata[i]) {
|
||||
wlr_scene_node_set_position(
|
||||
&output->strata[i]->node, box->x, box->y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
71
kiwmi/desktop/popup.c
Normal file
71
kiwmi/desktop/popup.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* Copyright (c), Niclas Meyer <niclas@countingsort.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "desktop/popup.h"
|
||||
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "desktop/desktop_surface.h"
|
||||
#include "desktop/layer_shell.h"
|
||||
#include "desktop/view.h"
|
||||
|
||||
struct kiwmi_desktop_surface *
|
||||
popup_get_desktop_surface(struct wlr_xdg_popup *popup)
|
||||
{
|
||||
struct wlr_surface *parent = popup->parent;
|
||||
while (parent) {
|
||||
if (wlr_surface_is_xdg_surface(parent)) {
|
||||
struct wlr_xdg_surface *xdg_surface =
|
||||
wlr_xdg_surface_from_wlr_surface(parent);
|
||||
switch (xdg_surface->role) {
|
||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||
parent = xdg_surface->popup->parent;
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
struct kiwmi_view *view = xdg_surface->data;
|
||||
return &view->desktop_surface;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
} else if (wlr_surface_is_layer_surface(parent)) {
|
||||
struct wlr_layer_surface_v1 *layer_surface =
|
||||
wlr_layer_surface_v1_from_wlr_surface(parent);
|
||||
struct kiwmi_layer *layer = layer_surface->data;
|
||||
return &layer->desktop_surface;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
popup_attach(
|
||||
struct wlr_xdg_popup *popup,
|
||||
struct kiwmi_desktop_surface *desktop_surface)
|
||||
{
|
||||
struct wlr_scene_tree *parent_tree = desktop_surface->popups_tree;
|
||||
if (wlr_surface_is_xdg_surface(popup->parent)) {
|
||||
struct wlr_xdg_surface *xdg_surface =
|
||||
wlr_xdg_surface_from_wlr_surface(popup->parent);
|
||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP
|
||||
&& xdg_surface->data) {
|
||||
parent_tree = xdg_surface->data;
|
||||
}
|
||||
}
|
||||
|
||||
struct wlr_scene_node *node =
|
||||
wlr_scene_xdg_surface_create(&parent_tree->node, popup->base);
|
||||
if (!node) {
|
||||
wlr_log(WLR_ERROR, "failed to attach popup to scene");
|
||||
return;
|
||||
}
|
||||
popup->base->data = node;
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
#include <wlr/util/log.h>
|
||||
|
||||
#include "desktop/output.h"
|
||||
#include "desktop/stratum.h"
|
||||
#include "input/cursor.h"
|
||||
#include "input/seat.h"
|
||||
#include "server.h"
|
||||
|
@ -105,6 +106,9 @@ view_set_pos(struct kiwmi_view *view, uint32_t x, uint32_t y)
|
|||
view->x = x;
|
||||
view->y = y;
|
||||
|
||||
wlr_scene_node_set_position(&view->desktop_surface.tree->node, x, y);
|
||||
wlr_scene_node_set_position(&view->desktop_surface.popups_tree->node, x, y);
|
||||
|
||||
struct kiwmi_view_child *child;
|
||||
wl_list_for_each (child, &view->children, link) {
|
||||
if (child->impl && child->impl->reconfigure) {
|
||||
|
@ -131,6 +135,20 @@ view_set_tiled(struct kiwmi_view *view, enum wlr_edges edges)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
view_set_hidden(struct kiwmi_view *view, bool hidden)
|
||||
{
|
||||
view->hidden = hidden;
|
||||
|
||||
if (!view->mapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_scene_node_set_enabled(&view->desktop_surface.tree->node, !hidden);
|
||||
wlr_scene_node_set_enabled(
|
||||
&view->desktop_surface.popups_tree->node, !hidden);
|
||||
}
|
||||
|
||||
struct wlr_surface *
|
||||
view_surface_at(
|
||||
struct kiwmi_view *view,
|
||||
|
@ -296,12 +314,26 @@ view_create(
|
|||
|
||||
wl_list_init(&view->children);
|
||||
|
||||
view->desktop_surface.type = KIWMI_DESKTOP_SURFACE_VIEW;
|
||||
|
||||
wl_signal_init(&view->events.unmap);
|
||||
wl_signal_init(&view->events.request_move);
|
||||
wl_signal_init(&view->events.request_resize);
|
||||
wl_signal_init(&view->events.post_render);
|
||||
wl_signal_init(&view->events.pre_render);
|
||||
|
||||
view->desktop_surface.tree = wlr_scene_tree_create(
|
||||
&view->desktop->strata[KIWMI_STRATUM_NORMAL]->node);
|
||||
view->desktop_surface.popups_tree = wlr_scene_tree_create(
|
||||
&view->desktop->strata[KIWMI_STRATUM_POPUPS]->node);
|
||||
|
||||
view_set_hidden(view, true);
|
||||
wlr_scene_node_lower_to_bottom(&view->desktop_surface.tree->node);
|
||||
wlr_scene_node_lower_to_bottom(&view->desktop_surface.popups_tree->node);
|
||||
|
||||
wlr_scene_node_set_position(&view->desktop_surface.tree->node, 0, 0);
|
||||
wlr_scene_node_set_position(&view->desktop_surface.popups_tree->node, 0, 0);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <pixman.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/edges.h>
|
||||
|
@ -18,6 +19,7 @@
|
|||
|
||||
#include "desktop/desktop.h"
|
||||
#include "desktop/output.h"
|
||||
#include "desktop/popup.h"
|
||||
#include "desktop/view.h"
|
||||
#include "input/cursor.h"
|
||||
#include "input/input.h"
|
||||
|
@ -191,6 +193,14 @@ xdg_surface_unmap_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
if (view->mapped) {
|
||||
view->mapped = false;
|
||||
|
||||
wlr_scene_node_set_enabled(&view->desktop_surface.tree->node, false);
|
||||
wlr_scene_node_set_enabled(
|
||||
&view->desktop_surface.popups_tree->node, false);
|
||||
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
cursor_refresh_focus(server->input.cursor, NULL, NULL, NULL);
|
||||
|
||||
struct kiwmi_output *output;
|
||||
wl_list_for_each (output, &view->desktop->outputs, link) {
|
||||
output_damage(output);
|
||||
|
@ -223,7 +233,11 @@ xdg_surface_commit_notify(struct wl_listener *listener, void *UNUSED(data))
|
|||
static void
|
||||
xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||
{
|
||||
struct kiwmi_view *view = wl_container_of(listener, view, destroy);
|
||||
struct kiwmi_view *view = wl_container_of(listener, view, destroy);
|
||||
|
||||
wlr_scene_node_destroy(&view->desktop_surface.tree->node);
|
||||
wlr_scene_node_destroy(&view->desktop_surface.popups_tree->node);
|
||||
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
struct kiwmi_seat *seat = server->input.seat;
|
||||
|
@ -380,6 +394,15 @@ xdg_shell_new_surface_notify(struct wl_listener *listener, void *data)
|
|||
|
||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||
wlr_log(WLR_DEBUG, "New xdg_shell popup");
|
||||
struct kiwmi_desktop_surface *desktop_surface =
|
||||
popup_get_desktop_surface(xdg_surface->popup);
|
||||
if (desktop_surface) {
|
||||
popup_attach(xdg_surface->popup, desktop_surface);
|
||||
|
||||
struct kiwmi_server *server =
|
||||
wl_container_of(desktop, server, desktop);
|
||||
cursor_refresh_focus(server->input.cursor, NULL, NULL, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -402,6 +425,9 @@ xdg_shell_new_surface_notify(struct wl_listener *listener, void *data)
|
|||
view->xdg_surface = xdg_surface;
|
||||
view->wlr_surface = xdg_surface->surface;
|
||||
|
||||
view->desktop_surface.surface_node = wlr_scene_xdg_surface_create(
|
||||
&view->desktop_surface.tree->node, xdg_surface);
|
||||
|
||||
view->map.notify = xdg_surface_map_notify;
|
||||
wl_signal_add(&xdg_surface->events.map, &view->map);
|
||||
|
||||
|
@ -431,6 +457,8 @@ xdg_shell_new_surface_notify(struct wl_listener *listener, void *data)
|
|||
|
||||
view_init_subsurfaces(NULL, view);
|
||||
|
||||
wlr_xdg_surface_get_geometry(view->xdg_surface, &view->geom);
|
||||
|
||||
wl_list_insert(&desktop->views, &view->link);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,10 @@ seat_focus_view(struct kiwmi_seat *seat, struct kiwmi_view *view)
|
|||
// move view to front
|
||||
wl_list_remove(&view->link);
|
||||
wl_list_insert(&desktop->views, &view->link);
|
||||
|
||||
wlr_scene_node_raise_to_top(&view->desktop_surface.tree->node);
|
||||
wlr_scene_node_raise_to_top(&view->desktop_surface.popups_tree->node);
|
||||
|
||||
cursor_refresh_focus(seat->input->cursor, NULL, NULL, NULL);
|
||||
|
||||
seat->focused_view = view;
|
||||
|
|
|
@ -69,6 +69,11 @@ l_kiwmi_server_bg_color(lua_State *L)
|
|||
server->desktop.bg_color[1] = color[1];
|
||||
server->desktop.bg_color[2] = color[2];
|
||||
// ignore alpha
|
||||
color[3] = 1.0f;
|
||||
|
||||
wlr_scene_rect_set_color(server->desktop.background_rect, color);
|
||||
bool black = color[0] == 0.0f && color[1] == 0.0f && color[2] == 0.0f;
|
||||
wlr_scene_node_set_enabled(&server->desktop.background_rect->node, !black);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ l_kiwmi_view_hide(lua_State *L)
|
|||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
|
||||
view->hidden = true;
|
||||
view_set_hidden(view, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ l_kiwmi_view_show(lua_State *L)
|
|||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
|
||||
view->hidden = false;
|
||||
view_set_hidden(view, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ kiwmi_sources = files(
|
|||
'desktop/desktop.c',
|
||||
'desktop/layer_shell.c',
|
||||
'desktop/output.c',
|
||||
'desktop/popup.c',
|
||||
'desktop/stratum.c',
|
||||
'desktop/view.c',
|
||||
'desktop/xdg_shell.c',
|
||||
|
|
Loading…
Reference in a new issue