xwayland: set _NET_WORKAREA property (#12148)

This commit is contained in:
jmanc3 2025-10-29 06:24:34 -05:00 committed by GitHub
parent 9eb82774e5
commit ce9787b3f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 67 additions and 1 deletions

View file

@ -1789,6 +1789,37 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR
return VECNOTINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y);
}
CBox CCompositor::calculateX11WorkArea() {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
CBox workbox = {0, 0, 0, 0};
bool firstMonitor = true;
for (const auto& monitor : m_monitors) {
// we ignore monitor->m_position on purpose
auto x = monitor->m_reservedTopLeft.x;
auto y = monitor->m_reservedTopLeft.y;
auto w = monitor->m_size.x - monitor->m_reservedBottomRight.x - x;
auto h = monitor->m_size.y - monitor->m_reservedBottomRight.y - y;
CBox box = {x, y, w, h};
if ((*PXWLFORCESCALEZERO))
box.scale(monitor->m_scale);
if (firstMonitor) {
firstMonitor = false;
workbox = box;
} else {
// if this monitor creates a different workbox than previous monitor, we remove the _NET_WORKAREA property all together
if ((std::abs(box.x - workbox.x) > 3) || (std::abs(box.y - workbox.y) > 3) || (std::abs(box.w - workbox.w) > 3) || (std::abs(box.h - workbox.h) > 3)) {
workbox = {0, 0, 0, 0};
break;
}
}
}
// returning 0, 0 will remove the _NET_WORKAREA property
return workbox;
}
PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) {
return getMonitorInDirection(m_lastMonitor.lock(), dir);
}
@ -2983,6 +3014,11 @@ void CCompositor::arrangeMonitors() {
}
PROTO::xdgOutput->updateAllOutputs();
#ifndef NO_XWAYLAND
CBox box = g_pCompositor->calculateX11WorkArea();
g_pXWayland->m_wm->updateWorkArea(box.x, box.y, box.w, box.h);
#endif
}
void CCompositor::enterUnsafeState() {

View file

@ -125,6 +125,7 @@ class CCompositor {
WORKSPACEID getNextAvailableNamedWorkspace();
bool isPointOnAnyMonitor(const Vector2D&);
bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr);
CBox calculateX11WorkArea();
PHLMONITOR getMonitorInDirection(const char&);
PHLMONITOR getMonitorInDirection(PHLMONITOR, const char&);
void updateAllWindowsAnimatedDecorationValues();

View file

@ -7,6 +7,7 @@
#include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "xwayland/XWayland.hpp"
SWorkspaceGaps CHyprDwindleLayout::getWorkspaceGaps(const PHLWORKSPACE& pWorkspace) {
const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(pWorkspace);
@ -597,6 +598,11 @@ void CHyprDwindleLayout::recalculateMonitor(const MONITORID& monid) {
calculateWorkspace(PMONITOR->m_activeSpecialWorkspace);
calculateWorkspace(PMONITOR->m_activeWorkspace);
#ifndef NO_XWAYLAND
CBox box = g_pCompositor->calculateX11WorkArea();
g_pXWayland->m_wm->updateWorkArea(box.x, box.y, box.w, box.h);
#endif
}
void CHyprDwindleLayout::calculateWorkspace(const PHLWORKSPACE& pWorkspace) {

View file

@ -9,6 +9,7 @@
#include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "xwayland/XWayland.hpp"
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) {
for (auto& nd : m_masterNodesData) {
@ -293,6 +294,11 @@ void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) {
calculateWorkspace(PMONITOR->m_activeSpecialWorkspace);
calculateWorkspace(PMONITOR->m_activeWorkspace);
#ifndef NO_XWAYLAND
CBox box = g_pCompositor->calculateX11WorkArea();
g_pXWayland->m_wm->updateWorkArea(box.x, box.y, box.w, box.h);
#endif
}
void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {

View file

@ -987,7 +987,7 @@ CXWM::CXWM() : m_connection(makeUnique<CXCBConnection>(g_pXWayland->m_server->m_
xcb_atom_t supported[] = {
HYPRATOMS["_NET_WM_STATE"], HYPRATOMS["_NET_ACTIVE_WINDOW"], HYPRATOMS["_NET_WM_MOVERESIZE"], HYPRATOMS["_NET_WM_STATE_FOCUSED"],
HYPRATOMS["_NET_WM_STATE_MODAL"], HYPRATOMS["_NET_WM_STATE_FULLSCREEN"], HYPRATOMS["_NET_WM_STATE_MAXIMIZED_VERT"], HYPRATOMS["_NET_WM_STATE_MAXIMIZED_HORZ"],
HYPRATOMS["_NET_WM_STATE_HIDDEN"], HYPRATOMS["_NET_CLIENT_LIST"], HYPRATOMS["_NET_CLIENT_LIST_STACKING"],
HYPRATOMS["_NET_WM_STATE_HIDDEN"], HYPRATOMS["_NET_CLIENT_LIST"], HYPRATOMS["_NET_CLIENT_LIST_STACKING"], HYPRATOMS["_NET_WORKAREA"],
};
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_SUPPORTED"], XCB_ATOM_ATOM, 32, sizeof(supported) / sizeof(*supported), supported);
@ -1193,6 +1193,22 @@ void CXWM::updateClientList() {
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_CLIENT_LIST_STACKING"], XCB_ATOM_WINDOW, 32, windows.size(), windows.data());
}
void CXWM::updateWorkArea(int x, int y, int w, int h) {
if (!g_pXWayland || !g_pXWayland->m_wm || !g_pXWayland->m_wm->getConnection() || !m_screen || !m_screen->root)
return;
auto connection = g_pXWayland->m_wm->getConnection();
if (w <= 0 || h <= 0) {
xcb_delete_property(connection, m_screen->root, HYPRATOMS["_NET_WORKAREA"]);
xcb_flush(connection);
return;
}
uint32_t values[4] = {sc<uint32_t>(x), sc<uint32_t>(y), sc<uint32_t>(w), sc<uint32_t>(h)};
xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_WORKAREA"], XCB_ATOM_CARDINAL, 32, 4, values);
xcb_flush(connection);
}
bool CXWM::isWMWindow(xcb_window_t w) {
return w == m_wmWindow || w == m_clipboard.window || w == m_dndSelection.window;
}

View file

@ -118,6 +118,7 @@ class CXWM {
int onEvent(int fd, uint32_t mask);
SP<CX11DataDevice> getDataDevice();
SP<IDataOffer> createX11DataOffer(SP<CWLSurfaceResource> surf, SP<IDataSource> source);
void updateWorkArea(int x, int y, int w, int h);
private:
void setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot);