logo

inaban

Distrustful Wayland Compositor (inspired by XMonad and dwm) git clone https://hacktivis.me/git/inaban.git
commit: 11c5d8c85278dbd8451246fbb785028a29b3ed7e
parent 06916d1c45dc733d61de0f4a9cc3a52114e64f86
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Tue, 13 Apr 2021 09:52:50 +0200

Revert "Add basic implementation of wlr layer shell"

This reverts commit 96007178c0e997d9b993a8de7c08944404d0752f.

Diffstat:

Dlayers.c333-------------------------------------------------------------------------------
Dlayers.h27---------------------------
Dprotocols/wlr-layer-shell-unstable-v1.xml285-------------------------------------------------------------------------------
3 files changed, 0 insertions(+), 645 deletions(-)

diff --git a/layers.c b/layers.c @@ -1,333 +0,0 @@ -// Copyright 2019 Drew DeVault -// Copyright 2019-2020 Inaban Authors <https://hacktivis.me/git/inaban> -// SPDX-License-Identifier: BSD-3-Clause -#include "layers.h" - -#include "server.h" - -#include <stdlib.h> -#include <string.h> -#include <wayland-server.h> -#include <wlr/types/wlr_layer_shell_v1.h> - -static void -apply_exclusive(struct wlr_box *usable_area, - uint32_t anchor, - int32_t exclusive, - int32_t margin_top, - int32_t margin_right, - int32_t margin_bottom, - int32_t margin_left) -{ - if(exclusive <= 0) - { - return; - } - struct - { - uint32_t anchors; - int *positive_axis; - int *negative_axis; - int margin; - } edges[] = { - { - .anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, - .positive_axis = &usable_area->y, - .negative_axis = &usable_area->height, - .margin = margin_top, - }, - { - .anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .positive_axis = NULL, - .negative_axis = &usable_area->height, - .margin = margin_bottom, - }, - { - .anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .positive_axis = &usable_area->x, - .negative_axis = &usable_area->width, - .margin = margin_left, - }, - { - .anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .positive_axis = NULL, - .negative_axis = &usable_area->width, - .margin = margin_right, - }, - }; - for(size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); ++i) - { - if((anchor & edges[i].anchors) == edges[i].anchors) - { - if(edges[i].positive_axis) - { - *edges[i].positive_axis += exclusive + edges[i].margin; - } - if(edges[i].negative_axis) - { - *edges[i].negative_axis -= exclusive + edges[i].margin; - } - } - } -} - -static void -arrange_layer(struct wlr_output *output, - struct wl_list *list /* struct *inaban_layer_surface */, - struct wlr_box *usable_area, - bool exclusive) -{ - struct inaban_layer_surface *inaban_surface; - struct wlr_box full_area = {0}; - wlr_output_effective_resolution(output, &full_area.width, &full_area.height); - wl_list_for_each_reverse(inaban_surface, list, link) - { - struct wlr_layer_surface_v1 *layer = inaban_surface->layer_surface; - struct wlr_layer_surface_v1_state *state = &layer->current; - if(exclusive != (state->exclusive_zone > 0)) - { - continue; - } - struct wlr_box bounds; - if(state->exclusive_zone == -1) - { - bounds = full_area; - } - else - { - bounds = *usable_area; - } - struct wlr_box box = {.width = state->desired_width, .height = state->desired_height}; - // Horizontal axis - const uint32_t both_horiz = - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - if((state->anchor & both_horiz) && box.width == 0) - { - box.x = bounds.x; - box.width = bounds.width; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) - { - box.x = bounds.x; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) - { - box.x = bounds.x + (bounds.width - box.width); - } - else - { - box.x = bounds.x + ((bounds.width / 2) - (box.width / 2)); - } - // Vertical axis - const uint32_t both_vert = - ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - if((state->anchor & both_vert) && box.height == 0) - { - box.y = bounds.y; - box.height = bounds.height; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) - { - box.y = bounds.y; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) - { - box.y = bounds.y + (bounds.height - box.height); - } - else - { - box.y = bounds.y + ((bounds.height / 2) - (box.height / 2)); - } - // Margin - if((state->anchor & both_horiz) == both_horiz) - { - box.x += state->margin.left; - box.width -= state->margin.left + state->margin.right; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) - { - box.x += state->margin.left; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) - { - box.x -= state->margin.right; - } - if((state->anchor & both_vert) == both_vert) - { - box.y += state->margin.top; - box.height -= state->margin.top + state->margin.bottom; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) - { - box.y += state->margin.top; - } - else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) - { - box.y -= state->margin.bottom; - } - if(box.width < 0 || box.height < 0) - { - // TODO: Bubble up a protocol error? - wlr_layer_surface_v1_close(layer); - continue; - } - - // Apply - inaban_surface->geo = box; - apply_exclusive(usable_area, - state->anchor, - state->exclusive_zone, - state->margin.top, - state->margin.right, - state->margin.bottom, - state->margin.left); - wlr_layer_surface_v1_configure(layer, box.width, box.height); - } -} - -void -arrange_layers(struct inaban_output *output) -{ - struct wlr_box usable_area = {0}; - wlr_output_effective_resolution(output->wlr_output, &usable_area.width, &usable_area.height); - - // Arrange exclusive surfaces from top->bottom - arrange_layer( - output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &usable_area, true); - arrange_layer( - output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &usable_area, true); - arrange_layer( - output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &usable_area, true); - arrange_layer(output->wlr_output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], - &usable_area, - true); - - // Arrange non-exlusive surfaces from top->bottom - arrange_layer( - output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &usable_area, false); - arrange_layer( - output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &usable_area, false); - arrange_layer( - output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &usable_area, false); - arrange_layer(output->wlr_output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], - &usable_area, - false); - - // Find topmost keyboard interactive layer, if such a layer exists - uint32_t layers_above_shell[] = { - ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, - ZWLR_LAYER_SHELL_V1_LAYER_TOP, - }; - size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]); - struct inaban_layer_surface *layer, *topmost = NULL; - for(size_t i = 0; i < nlayers; ++i) - { - wl_list_for_each_reverse(layer, &output->layers[layers_above_shell[i]], link) - { - if(layer->layer_surface->current.keyboard_interactive) - { - topmost = layer; - break; - } - } - if(topmost != NULL) - { - break; - } - } - - // TODO: Focus topmost layer -} - -static void -handle_output_destroy(struct wl_listener *listener, void *data) -{ - struct inaban_layer_surface *layer = wl_container_of(listener, layer, output_destroy); - layer->layer_surface->output = NULL; - wl_list_remove(&layer->output_destroy.link); - wlr_layer_surface_v1_close(layer->layer_surface); -} - -static void -handle_surface_commit(struct wl_listener *listener, void *data) -{ - struct inaban_layer_surface *layer = wl_container_of(listener, layer, surface_commit); - struct wlr_layer_surface_v1 *layer_surface = layer->layer_surface; - struct wlr_output *wlr_output = layer_surface->output; - if(wlr_output != NULL) - { - struct inaban_output *output = wlr_output->data; - arrange_layers(output); - } -} - -static void -handle_destroy(struct wl_listener *listener, void *data) -{ - struct inaban_layer_surface *layer = wl_container_of(listener, layer, destroy); - wl_list_remove(&layer->link); - wl_list_remove(&layer->destroy.link); - wl_list_remove(&layer->map.link); - wl_list_remove(&layer->surface_commit.link); - if(layer->layer_surface->output) - { - wl_list_remove(&layer->output_destroy.link); - arrange_layers((struct inaban_output *)layer->layer_surface->output->data); - } - free(layer); -} - -static void -handle_map(struct wl_listener *listener, void *data) -{ - struct wlr_layer_surface_v1 *layer_surface = data; - wlr_surface_send_enter(layer_surface->surface, layer_surface->output); -} - -void -server_new_layer_surface(struct wl_listener *listener, void *data) -{ - struct inaban_server *server = wl_container_of(listener, server, new_layer_surface); - struct wlr_layer_surface_v1 *layer_surface = data; - if(!layer_surface->output) - { - struct wlr_output *output = - wlr_output_layout_output_at(server->output_layout, server->cursor->x, server->cursor->y); - layer_surface->output = output; - } - - struct inaban_output *output = layer_surface->output->data; - struct inaban_layer_surface *inaban_surface = calloc(1, sizeof(struct inaban_layer_surface)); - if(!inaban_surface) - { - return; - } - inaban_surface->layer_surface = layer_surface; - layer_surface->data = inaban_surface; - inaban_surface->server = server; - - inaban_surface->surface_commit.notify = handle_surface_commit; - wl_signal_add(&layer_surface->surface->events.commit, &inaban_surface->surface_commit); - inaban_surface->output_destroy.notify = handle_output_destroy; - wl_signal_add(&layer_surface->output->events.destroy, &inaban_surface->output_destroy); - inaban_surface->destroy.notify = handle_destroy; - wl_signal_add(&layer_surface->events.destroy, &inaban_surface->destroy); - inaban_surface->map.notify = handle_map; - wl_signal_add(&layer_surface->events.map, &inaban_surface->map); - // TODO: popups - - // TODO: Listen for subsurfaces - wl_list_insert(&output->layers[layer_surface->layer], &inaban_surface->link); - // Temporarily set the layer's current state to client_pending - // So that we can easily arrange it - struct wlr_layer_surface_v1_state old_state = layer_surface->current; - layer_surface->current = layer_surface->client_pending; - arrange_layers(output); - layer_surface->current = old_state; -} diff --git a/layers.h b/layers.h @@ -1,27 +0,0 @@ -// Copyright 2019 Drew DeVault -// Copyright 2019-2020 Inaban Authors <https://hacktivis.me/git/inaban> -// SPDX-License-Identifier: BSD-3-Clause -#ifndef _INABAN_LAYERS_H -#define _INABAN_LAYERS_H -#include <wayland-server.h> -#include <wlr/types/wlr_layer_shell_v1.h> - -struct inaban_server; - -struct inaban_layer_surface -{ - struct wlr_layer_surface_v1 *layer_surface; - struct inaban_server *server; - struct wl_list link; - - struct wl_listener destroy; - struct wl_listener map; - struct wl_listener surface_commit; - struct wl_listener output_destroy; - - struct wlr_box geo; -}; - -void server_new_layer_surface(struct wl_listener *listener, void *data); - -#endif /* _INABAN_LAYERS_H↵*/ diff --git a/protocols/wlr-layer-shell-unstable-v1.xml b/protocols/wlr-layer-shell-unstable-v1.xml @@ -1,285 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<protocol name="wlr_layer_shell_unstable_v1"> - <copyright> - Copyright © 2017 Drew DeVault - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that copyright notice and this permission - notice appear in supporting documentation, and that the name of - the copyright holders not be used in advertising or publicity - pertaining to distribution of the software without specific, - written prior permission. The copyright holders make no - representations about the suitability of this software for any - purpose. It is provided "as is" without express or implied - warranty. - - THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - THIS SOFTWARE. - </copyright> - - <interface name="zwlr_layer_shell_v1" version="1"> - <description summary="create surfaces that are layers of the desktop"> - Clients can use this interface to assign the surface_layer role to - wl_surfaces. Such surfaces are assigned to a "layer" of the output and - rendered with a defined z-depth respective to each other. They may also be - anchored to the edges and corners of a screen and specify input handling - semantics. This interface should be suitable for the implementation of - many desktop shell components, and a broad number of other applications - that interact with the desktop. - </description> - - <request name="get_layer_surface"> - <description summary="create a layer_surface from a surface"> - Create a layer surface for an existing surface. This assigns the role of - layer_surface, or raises a protocol error if another role is already - assigned. - - Creating a layer surface from a wl_surface which has a buffer attached - or committed is a client error, and any attempts by a client to attach - or manipulate a buffer prior to the first layer_surface.configure call - must also be treated as errors. - - You may pass NULL for output to allow the compositor to decide which - output to use. Generally this will be the one that the user most - recently interacted with. - - Clients can specify a namespace that defines the purpose of the layer - surface. - </description> - <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/> - <arg name="surface" type="object" interface="wl_surface"/> - <arg name="output" type="object" interface="wl_output" allow-null="true"/> - <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/> - <arg name="namespace" type="string" summary="namespace for the layer surface"/> - </request> - - <enum name="error"> - <entry name="role" value="0" summary="wl_surface has another role"/> - <entry name="invalid_layer" value="1" summary="layer value is invalid"/> - <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/> - </enum> - - <enum name="layer"> - <description summary="available layers for surfaces"> - These values indicate which layers a surface can be rendered in. They - are ordered by z depth, bottom-most first. Traditional shell surfaces - will typically be rendered between the bottom and top layers. - Fullscreen shell surfaces are typically rendered at the top layer. - Multiple surfaces can share a single layer, and ordering within a - single layer is undefined. - </description> - - <entry name="background" value="0"/> - <entry name="bottom" value="1"/> - <entry name="top" value="2"/> - <entry name="overlay" value="3"/> - </enum> - </interface> - - <interface name="zwlr_layer_surface_v1" version="1"> - <description summary="layer metadata interface"> - An interface that may be implemented by a wl_surface, for surfaces that - are designed to be rendered as a layer of a stacked desktop-like - environment. - - Layer surface state (size, anchor, exclusive zone, margin, interactivity) - is double-buffered, and will be applied at the time wl_surface.commit of - the corresponding wl_surface is called. - </description> - - <request name="set_size"> - <description summary="sets the size of the surface"> - Sets the size of the surface in surface-local coordinates. The - compositor will display the surface centered with respect to its - anchors. - - If you pass 0 for either value, the compositor will assign it and - inform you of the assignment in the configure event. You must set your - anchor to opposite edges in the dimensions you omit; not doing so is a - protocol error. Both values are 0 by default. - - Size is double-buffered, see wl_surface.commit. - </description> - <arg name="width" type="uint"/> - <arg name="height" type="uint"/> - </request> - - <request name="set_anchor"> - <description summary="configures the anchor point of the surface"> - Requests that the compositor anchor the surface to the specified edges - and corners. If two orthogonal edges are specified (e.g. 'top' and - 'left'), then the anchor point will be the intersection of the edges - (e.g. the top left corner of the output); otherwise the anchor point - will be centered on that edge, or in the center if none is specified. - - Anchor is double-buffered, see wl_surface.commit. - </description> - <arg name="anchor" type="uint" enum="anchor"/> - </request> - - <request name="set_exclusive_zone"> - <description summary="configures the exclusive geometry of this surface"> - Requests that the compositor avoids occluding an area of the surface - with other surfaces. The compositor's use of this information is - implementation-dependent - do not assume that this region will not - actually be occluded. - - A positive value is only meaningful if the surface is anchored to an - edge, rather than a corner. The zone is the number of surface-local - coordinates from the edge that is considered exclusive. - - Surfaces that do not wish to have an exclusive zone may instead specify - how they should interact with surfaces that do. If set to zero, the - surface indicates that it would like to be moved to avoid occluding - surfaces with a positive exclusive zone. If set to -1, the surface - indicates that it would not like to be moved to accommodate for other - surfaces, and the compositor should extend it all the way to the edges - it is anchored to. - - For example, a panel might set its exclusive zone to 10, so that - maximized shell surfaces are not shown on top of it. A notification - might set its exclusive zone to 0, so that it is moved to avoid - occluding the panel, but shell surfaces are shown underneath it. A - wallpaper or lock screen might set their exclusive zone to -1, so that - they stretch below or over the panel. - - The default value is 0. - - Exclusive zone is double-buffered, see wl_surface.commit. - </description> - <arg name="zone" type="int"/> - </request> - - <request name="set_margin"> - <description summary="sets a margin from the anchor point"> - Requests that the surface be placed some distance away from the anchor - point on the output, in surface-local coordinates. Setting this value - for edges you are not anchored to has no effect. - - The exclusive zone includes the margin. - - Margin is double-buffered, see wl_surface.commit. - </description> - <arg name="top" type="int"/> - <arg name="right" type="int"/> - <arg name="bottom" type="int"/> - <arg name="left" type="int"/> - </request> - - <request name="set_keyboard_interactivity"> - <description summary="requests keyboard events"> - Set to 1 to request that the seat send keyboard events to this layer - surface. For layers below the shell surface layer, the seat will use - normal focus semantics. For layers above the shell surface layers, the - seat will always give exclusive keyboard focus to the top-most layer - which has keyboard interactivity set to true. - - Layer surfaces receive pointer, touch, and tablet events normally. If - you do not want to receive them, set the input region on your surface - to an empty region. - - Events is double-buffered, see wl_surface.commit. - </description> - <arg name="keyboard_interactivity" type="uint"/> - </request> - - <request name="get_popup"> - <description summary="assign this layer_surface as an xdg_popup parent"> - This assigns an xdg_popup's parent to this layer_surface. This popup - should have been created via xdg_surface::get_popup with the parent set - to NULL, and this request must be invoked before committing the popup's - initial state. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - </description> - <arg name="popup" type="object" interface="xdg_popup"/> - </request> - - <request name="ack_configure"> - <description summary="ack a configure event"> - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - </description> - <arg name="serial" type="uint" summary="the serial from the configure event"/> - </request> - - <request name="destroy" type="destructor"> - <description summary="destroy the layer_surface"> - This request destroys the layer surface. - </description> - </request> - - <event name="configure"> - <description summary="suggest a surface change"> - The configure event asks the client to resize its surface. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - The client is free to dismiss all but the last configure event it - received. - - The width and height arguments specify the size of the window in - surface-local coordinates. - - The size is a hint, in the sense that the client is free to ignore it if - it doesn't resize, pick a smaller size (to satisfy aspect ratio or - resize in steps of NxM pixels). If the client picks a smaller size and - is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the - surface will be centered on this axis. - - If the width or height arguments are zero, it means the client should - decide its own window dimension. - </description> - <arg name="serial" type="uint"/> - <arg name="width" type="uint"/> - <arg name="height" type="uint"/> - </event> - - <event name="closed"> - <description summary="surface should be closed"> - The closed event is sent by the compositor when the surface will no - longer be shown. The output may have been destroyed or the user may - have asked for it to be removed. Further changes to the surface will be - ignored. The client should destroy the resource after receiving this - event, and create a new surface if they so choose. - </description> - </event> - - <enum name="error"> - <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/> - <entry name="invalid_size" value="1" summary="size is invalid"/> - <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/> - </enum> - - <enum name="anchor" bitfield="true"> - <entry name="top" value="1" summary="the top edge of the anchor rectangle"/> - <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/> - <entry name="left" value="4" summary="the left edge of the anchor rectangle"/> - <entry name="right" value="8" summary="the right edge of the anchor rectangle"/> - </enum> - </interface> -</protocol>