input: decouple pointer focus from layer-surface keyboard_interactivity (#15899)

* input/layers: let new layer-surfaces take pointer focus

* input/layers: decouple pointer focus from keyboard interactivity

zwlr_layer_surface_v1::set_keyboard_interactivity:

  "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."

We were previously treating keyboard interactivity also as pointer
interactivity, by forcing pointer focus onto any new
'keyboard_interactivity != none' surfaces in onMap(), as well as
redirecting all regular pointer input to any existing
'keyboard_interactivity == exclusive' surface.

* layers: rename 'interactivity' identifiers to specify *keyboard*-interactivity

The Lua config field is also renamed from 'interactivity' to
'keyboard_interactivity'.
This commit is contained in:
Stephan
2026-08-21 23:03:40 +02:00
committed by GitHub
parent cd83a26c7e
commit d29916a91c
13 changed files with 58 additions and 95 deletions
+2 -2
View File
@@ -67,8 +67,8 @@ static int layerSurfaceIndex(lua_State* L) {
lua_pushboolean(L, ls->mapped());
else if (key == "layer")
lua_pushinteger(L, sc<lua_Integer>(ls->m_layer));
else if (key == "interactivity")
lua_pushinteger(L, sc<lua_Integer>(ls->m_interactivity));
else if (key == "keyboard_interactivity")
lua_pushinteger(L, sc<lua_Integer>(ls->m_keyboardInteractivity));
else if (key == "above_fullscreen")
lua_pushboolean(L, sc<bool>(ls->m_flags & Desktop::View::LAYER_FLAG_ABOVE_FULLSCREEN));
else
+1 -1
View File
@@ -108,7 +108,7 @@ void CFocusState::rawWindowFocus(PHLWINDOW pWindow, eFocusReason reason, SP<CWLS
return;
}
if (!g_pInputManager->m_exclusiveLSes.empty()) {
if (!g_pInputManager->m_exclusiveKeyboardLSes.empty()) {
Log::logger->log(Log::DEBUG, "Refusing a keyboard focus to a window because of an exclusive ls");
return;
}
-17
View File
@@ -325,23 +325,6 @@ SP<CWLSurfaceResource> CViewHitTester::layerPopupSurfaceAt(const Vector2D& pos,
return nullptr;
}
SP<CWLSurfaceResource> CViewHitTester::layerPopupSurfaceAt(const Vector2D& pos, const std::vector<PHLLSREF>* layerSurfaces, Vector2D* surfaceCoords, PHLLS* layerFound) const {
for (auto const& ls : *layerSurfaces | std::views::reverse) {
if (!ls->mapped() || !ls->acceptsInput())
continue;
auto SURFACEAT = ls->popupHead()->at(pos, true);
if (SURFACEAT) {
*layerFound = ls.lock();
*surfaceCoords = pos - SURFACEAT->coordsGlobal();
return SURFACEAT->wlSurface()->resource();
}
}
return nullptr;
}
SP<CWLSurfaceResource> CViewHitTester::layerSurfaceAt(const Vector2D& pos, std::vector<PHLLSREF>* layerSurfaces, Vector2D* surfaceCoords, PHLLS* layerFound,
bool aboveLockscreen) const {
for (auto const& ls : *layerSurfaces | std::views::reverse) {
-1
View File
@@ -23,7 +23,6 @@ namespace Desktop {
SP<CWLSurfaceResource> windowSurfaceAt(const Vector2D& pos, PHLWINDOW window, Vector2D& surfaceLocal) const;
Vector2D surfaceLocalAt(const Vector2D& pos, PHLWINDOW window, SP<CWLSurfaceResource> surface) const;
SP<CWLSurfaceResource> layerPopupSurfaceAt(const Vector2D& pos, PHLMONITOR monitor, Vector2D* surfaceCoords, PHLLS* layerFound) const;
SP<CWLSurfaceResource> layerPopupSurfaceAt(const Vector2D& pos, const std::vector<PHLLSREF>* layerSurfaces, Vector2D* surfaceCoords, PHLLS* layerFound) const;
SP<CWLSurfaceResource> layerSurfaceAt(const Vector2D& pos, std::vector<PHLLSREF>* layerSurfaces, Vector2D* surfaceCoords, PHLLS* layerFound,
bool aboveLockscreen = false) const;
+23 -28
View File
@@ -173,8 +173,8 @@ void CLayerSurface::onDestroy() {
void CLayerSurface::onMap() {
Log::logger->log(Log::DEBUG, "LayerSurface {:x} mapped", rc<uintptr_t>(m_layerSurface.get()));
m_mapped = true;
m_interactivity = m_layerSurface->m_current.interactivity;
m_mapped = true;
m_keyboardInteractivity = m_layerSurface->m_current.keyboardInteractivity;
m_flags |= LAYER_FLAG_ABOVE_FULLSCREEN;
m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_ALL);
@@ -193,29 +193,28 @@ void CLayerSurface::onMap() {
m_wlSurface->resource()->enter(PMONITOR->m_self.lock());
const bool ISEXCLUSIVE = m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
const bool KEYBOARD_EXCLUSIVE = m_layerSurface->m_current.keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
if (ISEXCLUSIVE)
g_pInputManager->m_exclusiveLSes.push_back(m_self);
if (KEYBOARD_EXCLUSIVE)
g_pInputManager->m_exclusiveKeyboardLSes.push_back(m_self);
const bool GRABSFOCUS = ISEXCLUSIVE ||
(m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
const bool GRABS_KEYBOARD = KEYBOARD_EXCLUSIVE ||
(m_layerSurface->m_current.keyboardInteractivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
// don't focus if constrained
(g_pSeatManager->m_mouse.expired() || !g_pInputManager->isConstrained()));
if (GRABSFOCUS) {
if (GRABS_KEYBOARD) {
// TODO: use the new superb really very cool grab
if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(m_wlSurface->resource()))
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
Desktop::focusState()->rawSurfaceFocus(m_wlSurface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
g_pSeatManager->setPointerFocus(m_wlSurface->resource(), LOCAL);
g_pInputManager->m_emptyFocusCursorSet = false;
}
// update pointer focus
g_pInputManager->simulateMouseMovement();
m_position = Vector2D(m_geometry.x, m_geometry.y);
CBox geomFixed = {m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y, m_geometry.width, m_geometry.height};
@@ -238,7 +237,7 @@ void CLayerSurface::onUnmap() {
IPC::Socket2::sock()->postEvent({.event = "closelayer", .data = m_layerSurface->m_layerNamespace});
Event::bus()->m_events.layer.closed.emit(m_self.lock());
std::erase_if(g_pInputManager->m_exclusiveLSes, [this](const auto& other) { return !other || other == m_self; });
std::erase_if(g_pInputManager->m_exclusiveKeyboardLSes, [this](const auto& other) { return !other || other == m_self; });
if (!m_monitor) {
Log::logger->log(Log::WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
@@ -380,7 +379,7 @@ void CLayerSurface::onCommit() {
m_realSize->setValueAndWarp(m_geometry.size());
}
if (m_mapped && (m_layerSurface->m_current.committed & CLayerShellResource::eCommittedState::STATE_INTERACTIVITY)) {
if (m_mapped && (m_layerSurface->m_current.committed & CLayerShellResource::eCommittedState::STATE_KEYBOARD_INTERACTIVITY)) {
bool WASLASTFOCUS = false;
m_layerSurface->m_surface->breadthfirst(
[&WASLASTFOCUS](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { WASLASTFOCUS = WASLASTFOCUS || g_pSeatManager->m_state.keyboardFocus == surf; },
@@ -392,35 +391,31 @@ void CLayerSurface::onCommit() {
},
nullptr);
}
const bool WASEXCLUSIVE = m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
const bool ISEXCLUSIVE = m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
const bool WAS_KEYBOARD_EXCLUSIVE = m_keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
const bool KEYBOARD_EXCLUSIVE = m_layerSurface->m_current.keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
if (!WASEXCLUSIVE && ISEXCLUSIVE)
g_pInputManager->m_exclusiveLSes.push_back(m_self);
else if (WASEXCLUSIVE && !ISEXCLUSIVE)
std::erase_if(g_pInputManager->m_exclusiveLSes, [this](const auto& other) { return !other || other == m_self; });
if (!WAS_KEYBOARD_EXCLUSIVE && KEYBOARD_EXCLUSIVE)
g_pInputManager->m_exclusiveKeyboardLSes.push_back(m_self);
else if (WAS_KEYBOARD_EXCLUSIVE && !KEYBOARD_EXCLUSIVE)
std::erase_if(g_pInputManager->m_exclusiveKeyboardLSes, [this](const auto& other) { return !other || other == m_self; });
// if the surface was focused and interactive but now isn't, refocus
if (WASLASTFOCUS && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
if (WASLASTFOCUS && m_layerSurface->m_current.keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
// so unfocus the surface here.
Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pInputManager->refocusLastWindow(m_monitor.lock());
} else if (WASLASTFOCUS && WASEXCLUSIVE && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
} else if (WASLASTFOCUS && WAS_KEYBOARD_EXCLUSIVE && m_layerSurface->m_current.keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
g_pInputManager->simulateMouseMovement();
} else if (!WASEXCLUSIVE && ISEXCLUSIVE) {
} else if (!WAS_KEYBOARD_EXCLUSIVE && KEYBOARD_EXCLUSIVE) {
// if now exclusive and not previously
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
Desktop::focusState()->rawSurfaceFocus(m_wlSurface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
g_pSeatManager->setPointerFocus(m_wlSurface->resource(), LOCAL);
g_pInputManager->m_emptyFocusCursorSet = false;
}
}
m_interactivity = m_layerSurface->m_current.interactivity;
m_keyboardInteractivity = m_layerSurface->m_current.keyboardInteractivity;
g_pHyprRenderer->damageSurface(m_wlSurface->resource(), m_position.x, m_position.y);
+1 -1
View File
@@ -58,7 +58,7 @@ namespace Desktop::View {
LayerFlags m_flags = LAYER_FLAG_ABOVE_FULLSCREEN;
// the header providing the enum type cannot be imported here
int m_interactivity = 0;
int m_keyboardInteractivity = 0;
uint32_t m_layer = 0;
+1 -1
View File
@@ -206,7 +206,7 @@ bool CWLSurface::keyboardFocusable() const {
if (m_view->type() == VIEW_TYPE_WINDOW || m_view->type() == VIEW_TYPE_SUBSURFACE || m_view->type() == VIEW_TYPE_POPUP)
return true;
if (const auto LS = CLayerSurface::fromView(m_view.lock()); LS && LS->m_layerSurface)
return LS->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
return LS->m_layerSurface->m_current.keyboardInteractivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
return false;
}
+1 -1
View File
@@ -1434,7 +1434,7 @@ void CWindow::mapWindow() {
// check LS focus grab
const auto PFORCEFOCUS = Desktop::viewState()->query().forceFocus().runWindow();
const auto PLSFROMFOCUS = Desktop::viewState()->query().type(VIEW_TYPE_LAYER_SURFACE).surface(Desktop::focusState()->surface()).runLayer();
if (PLSFROMFOCUS && PLSFROMFOCUS->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
if (PLSFROMFOCUS && PLSFROMFOCUS->m_layerSurface->m_current.keyboardInteractivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
m_state |= WINDOW_STATE_NO_INITIAL_FOCUS;
// emit the hook event here after basic stuff has been initialized
+2 -2
View File
@@ -729,7 +729,7 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
m_seatGrab.reset();
if (parentLayer && parentLayer->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
if (parentLayer && parentLayer->m_layerSurface->m_current.keyboardInteractivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
Desktop::focusState()->rawSurfaceFocus(parentLayer->wlSurface()->resource());
} else {
static auto PFOLLOWMOUSE = CConfigValue<Config::INTEGER>("input:follow_mouse");
@@ -766,7 +766,7 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
}
if (!refocus && layer)
refocus = layer->m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
refocus = layer->m_keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
if (refocus) {
auto candidate = Desktop::focusState()->window();
+6 -20
View File
@@ -452,20 +452,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
return;
}
// forced above all
if (!g_pInputManager->m_exclusiveLSes.empty() && !PROTO::data->dndActive()) {
if (!foundSurface)
foundSurface = Desktop::viewState()->hitTest().layerPopupSurfaceAt(mouseCoords, &g_pInputManager->m_exclusiveLSes, &surfaceCoords, &pFoundLayerSurface);
if (!foundSurface)
foundSurface = Desktop::viewState()->hitTest().layerSurfaceAt(mouseCoords, &g_pInputManager->m_exclusiveLSes, &surfaceCoords, &pFoundLayerSurface);
if (!foundSurface) {
foundSurface = (*g_pInputManager->m_exclusiveLSes.begin())->wlSurface()->resource();
surfacePos = (*g_pInputManager->m_exclusiveLSes.begin())->position(Desktop::View::IGeometric::GEOMETRIC_GOAL);
}
}
if (!foundSurface)
foundSurface = Desktop::viewState()->hitTest().layerPopupSurfaceAt(mouseCoords, PMONITOR, &surfaceCoords, &pFoundLayerSurface);
@@ -640,7 +626,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
if (!refocus && Desktop::focusState()->surface()) {
const auto PLS = Desktop::viewState()->query().type(Desktop::View::VIEW_TYPE_LAYER_SURFACE).surface(Desktop::focusState()->surface()).runLayer();
if (PLS && PLS->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
if (PLS && PLS->m_layerSurface->m_current.keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
allowKeyboardRefocus = false;
}
@@ -732,8 +718,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
Pointer::Cursor::overrideController->unsetOverride(Pointer::Cursor::CURSOR_OVERRIDE_WINDOW_EDGE);
}
if (pFoundLayerSurface && (pFoundLayerSurface->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) && FOLLOWMOUSE != 3 &&
(allowKeyboardRefocus || pFoundLayerSurface->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)) {
if (pFoundLayerSurface && (pFoundLayerSurface->m_layerSurface->m_current.keyboardInteractivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) && FOLLOWMOUSE != 3 &&
(allowKeyboardRefocus || pFoundLayerSurface->m_layerSurface->m_current.keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)) {
Desktop::focusState()->rawSurfaceFocus(foundSurface);
}
@@ -1847,7 +1833,7 @@ void CInputManager::refocus(std::optional<Vector2D> overridePos) {
}
bool CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
if (!m_exclusiveLSes.empty()) {
if (!m_exclusiveKeyboardLSes.empty()) {
Log::logger->log(Log::DEBUG, "CInputManager::refocusLastWindow: ignoring, exclusive LS present.");
return false;
}
@@ -1867,14 +1853,14 @@ bool CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
if (!foundSurface) {
foundSurface = Desktop::viewState()->hitTest().layerSurfaceAt(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
&surfaceCoords, &pFoundLayerSurface);
if (pFoundLayerSurface && pFoundLayerSurface->m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND)
if (pFoundLayerSurface && pFoundLayerSurface->m_keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND)
foundSurface = nullptr;
}
if (!foundSurface) {
foundSurface = Desktop::viewState()->hitTest().layerSurfaceAt(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
&surfaceCoords, &pFoundLayerSurface);
if (pFoundLayerSurface && pFoundLayerSurface->m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND)
if (pFoundLayerSurface && pFoundLayerSurface->m_keyboardInteractivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND)
foundSurface = nullptr;
}
+1 -1
View File
@@ -173,7 +173,7 @@ class CInputManager {
std::list<SSwitchDevice> m_switches;
// Exclusive layer surfaces
std::vector<PHLLSREF> m_exclusiveLSes;
std::vector<PHLLSREF> m_exclusiveKeyboardLSes;
// constraints
std::vector<WP<CPointerConstraint>> m_constraints;
+9 -9
View File
@@ -7,13 +7,13 @@
#include "../output/Monitor.hpp"
void CLayerShellResource::SState::reset() {
anchor = 0;
exclusive = 0;
interactivity = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
exclusiveEdge = sc<zwlrLayerSurfaceV1Anchor>(0);
desiredSize = {};
margin = {0, 0, 0, 0};
anchor = 0;
exclusive = 0;
keyboardInteractivity = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
exclusiveEdge = sc<zwlrLayerSurfaceV1Anchor>(0);
desiredSize = {};
margin = {0, 0, 0, 0};
}
CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, PHLMONITOR pMonitor,
@@ -113,8 +113,8 @@ CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<C
return;
}
markPending(STATE_INTERACTIVITY);
m_pending.interactivity = kbi;
markPending(STATE_KEYBOARD_INTERACTIVITY);
m_pending.keyboardInteractivity = kbi;
});
m_resource->setGetPopup([this](CZwlrLayerSurfaceV1* r, wl_resource* popup_) {
+11 -11
View File
@@ -34,13 +34,13 @@ class CLayerShellResource {
void sendClosed();
enum eCommittedState : uint8_t {
STATE_SIZE = (1 << 0),
STATE_ANCHOR = (1 << 1),
STATE_EXCLUSIVE = (1 << 2),
STATE_MARGIN = (1 << 3),
STATE_INTERACTIVITY = (1 << 4),
STATE_LAYER = (1 << 5),
STATE_EDGE = (1 << 6),
STATE_SIZE = (1 << 0),
STATE_ANCHOR = (1 << 1),
STATE_EXCLUSIVE = (1 << 2),
STATE_MARGIN = (1 << 3),
STATE_KEYBOARD_INTERACTIVITY = (1 << 4),
STATE_LAYER = (1 << 5),
STATE_EDGE = (1 << 6),
};
struct {
@@ -55,10 +55,10 @@ class CLayerShellResource {
uint32_t anchor = 0;
int32_t exclusive = 0;
Vector2D desiredSize;
zwlrLayerSurfaceV1KeyboardInteractivity interactivity = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
zwlrLayerShellV1Layer layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
zwlrLayerSurfaceV1Anchor exclusiveEdge = sc<zwlrLayerSurfaceV1Anchor>(0);
uint32_t committed = 0;
zwlrLayerSurfaceV1KeyboardInteractivity keyboardInteractivity = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
zwlrLayerShellV1Layer layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
zwlrLayerSurfaceV1Anchor exclusiveEdge = sc<zwlrLayerSurfaceV1Anchor>(0);
uint32_t committed = 0;
struct {
double left = 0, right = 0, top = 0, bottom = 0;