Hyprland/src/managers/XWaylandManager.cpp

281 lines
11 KiB
C++
Raw Normal View History

2022-03-18 20:03:39 +01:00
#include "XWaylandManager.hpp"
#include "../Compositor.hpp"
#include "../events/Events.hpp"
#include "../config/ConfigValue.hpp"
2024-05-11 00:28:33 +02:00
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XWayland.hpp"
#define OUTPUT_MANAGER_VERSION 3
#define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3
#define OUTPUT_DESCRIPTION_MUTABLE_SINCE_VERSION 3
2022-03-18 20:03:39 +01:00
CHyprXWaylandManager::CHyprXWaylandManager() {
;
2022-03-18 20:03:39 +01:00
}
CHyprXWaylandManager::~CHyprXWaylandManager() {
#ifndef NO_XWAYLAND
unsetenv("DISPLAY");
#endif
}
2022-03-18 20:03:39 +01:00
SP<CWLSurfaceResource> CHyprXWaylandManager::getWindowSurface(PHLWINDOW pWindow) {
return pWindow->m_pWLSurface->resource();
2022-03-18 20:03:39 +01:00
}
void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool activate) {
2022-08-31 11:12:46 +02:00
if (!pSurface)
return;
2024-05-11 00:28:33 +02:00
// TODO:
// this cannot be nicely done until we rewrite wlr_surface
for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped)
2024-05-11 00:28:33 +02:00
continue;
if (w->m_pWLSurface->resource() != pSurface)
2024-05-11 00:28:33 +02:00
continue;
if (w->m_bIsX11) {
if (activate) {
w->m_pXWaylandSurface->setMinimized(false);
w->m_pXWaylandSurface->restackToTop();
}
w->m_pXWaylandSurface->activate(activate);
} else {
w->m_pXDGSurface->toplevel->setActive(activate);
if (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastWindow->m_bIsX11)
activateSurface(g_pCompositor->m_pLastFocus.lock(), false);
}
2024-05-11 00:28:33 +02:00
}
2022-03-18 20:03:39 +01:00
}
void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {
2022-04-05 18:29:58 +02:00
if (pWindow->m_bIsX11) {
setWindowSize(pWindow, pWindow->m_vRealSize.value()); // update xwayland output pos
2022-05-11 15:03:31 +02:00
2022-10-28 20:18:10 +02:00
if (activate) {
pWindow->m_pXWaylandSurface->setMinimized(false);
if (pWindow->m_iX11Type != 2)
pWindow->m_pXWaylandSurface->restackToTop();
2022-10-28 20:18:10 +02:00
}
pWindow->m_pXWaylandSurface->activate(activate);
2024-05-11 00:28:33 +02:00
} else if (pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel)
pWindow->m_pXDGSurface->toplevel->setActive(activate);
2022-04-02 18:57:09 +02:00
2022-10-25 15:19:24 +02:00
if (activate) {
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
2022-10-25 15:19:24 +02:00
g_pCompositor->m_pLastWindow = pWindow;
}
2022-08-31 17:02:44 +02:00
2022-09-10 13:11:02 +02:00
if (!pWindow->m_bPinned)
pWindow->m_pWorkspace->m_pLastFocusedWindow = pWindow;
2022-04-02 18:57:09 +02:00
}
void CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow, CBox* pbox) {
2022-03-18 20:03:39 +01:00
if (pWindow->m_bIsX11) {
const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get();
2022-10-17 15:26:18 +02:00
if (SIZEHINTS && pWindow->m_iX11Type != 2) {
// WM_SIZE_HINTS' x,y,w,h is deprecated it seems.
// Source: https://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#wm_normal_hints_property
pbox->x = pWindow->m_pXWaylandSurface->geometry.x;
pbox->y = pWindow->m_pXWaylandSurface->geometry.y;
if ((SIZEHINTS->flags & 0x2 /* ICCCM USSize */) || (SIZEHINTS->flags & 0x8 /* ICCCM PSize */)) {
pbox->w = SIZEHINTS->base_width;
pbox->h = SIZEHINTS->base_height;
} else {
pbox->w = pWindow->m_pXWaylandSurface->geometry.w;
pbox->h = pWindow->m_pXWaylandSurface->geometry.h;
}
} else
*pbox = pWindow->m_pXWaylandSurface->geometry;
2024-05-11 00:28:33 +02:00
} else if (pWindow->m_pXDGSurface)
*pbox = pWindow->m_pXDGSurface->current.geometry;
2022-03-18 20:03:39 +01:00
}
void CHyprXWaylandManager::sendCloseWindow(PHLWINDOW pWindow) {
2023-06-18 18:14:48 +02:00
if (pWindow->m_bIsX11)
pWindow->m_pXWaylandSurface->close();
2024-05-11 00:28:33 +02:00
else if (pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel)
pWindow->m_pXDGSurface->toplevel->close();
2022-03-18 20:03:39 +01:00
}
void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool force) {
2023-02-28 20:36:36 +01:00
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
// calculate pos
// TODO: this should be decoupled from setWindowSize IMO
Vector2D windowPos = pWindow->m_vRealPosition.value();
if (pWindow->m_bIsX11 && PMONITOR) {
windowPos = windowPos - PMONITOR->vecPosition; // normalize to monitor
if (*PXWLFORCESCALEZERO)
windowPos = windowPos * PMONITOR->scale; // scale if applicable
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
}
if (!force && ((pWindow->m_vPendingReportedSize == size && windowPos == pWindow->m_vReportedPosition) || (pWindow->m_vPendingReportedSize == size && !pWindow->m_bIsX11)))
return;
pWindow->m_vReportedPosition = windowPos;
pWindow->m_vPendingReportedSize = size;
2023-06-11 21:52:13 +02:00
pWindow->m_fX11SurfaceScaledBy = 1.f;
if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) {
size = size * PMONITOR->scale;
pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale;
2023-06-11 21:52:13 +02:00
}
if (pWindow->m_bIsX11)
pWindow->m_pXWaylandSurface->configure({windowPos, size});
2024-05-11 00:28:33 +02:00
else if (pWindow->m_pXDGSurface->toplevel)
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor()));
2022-03-18 20:03:39 +01:00
}
bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
2022-03-20 13:37:07 +01:00
if (pWindow->m_bIsX11) {
for (auto& a : pWindow->m_pXWaylandSurface->atoms)
if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLBAR"] ||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_UTILITY"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] ||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] ||
a == HYPRATOMS["_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"]) {
if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"])
pWindow->m_bX11ShouldntFocus = true;
pWindow->m_bNoInitialFocus = true;
return true;
}
2022-03-20 19:26:16 +01:00
if (pWindow->m_pXWaylandSurface->modal) {
2022-03-22 18:29:13 +01:00
pWindow->m_bIsModal = true;
2022-03-20 19:26:16 +01:00
return true;
2022-03-22 18:29:13 +01:00
}
2022-03-20 19:26:16 +01:00
if (pWindow->m_pXWaylandSurface->transient)
return true;
if (pWindow->m_pXWaylandSurface->role.contains("task_dialog") || pWindow->m_pXWaylandSurface->role.contains("pop-up"))
return true;
2022-04-18 13:10:58 +02:00
if (pWindow->m_pXWaylandSurface->overrideRedirect)
return true;
const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get();
if (pWindow->m_pXWaylandSurface->transient || pWindow->m_pXWaylandSurface->parent ||
(SIZEHINTS && (SIZEHINTS->min_width == SIZEHINTS->max_width) && (SIZEHINTS->min_height == SIZEHINTS->max_height)))
2022-03-20 19:26:16 +01:00
return true;
2022-03-21 17:24:41 +01:00
} else {
2024-05-11 00:28:33 +02:00
const auto PSTATE = pending ? &pWindow->m_pXDGSurface->toplevel->pending : &pWindow->m_pXDGSurface->toplevel->current;
2022-09-25 20:07:48 +02:00
2024-05-11 00:28:33 +02:00
if (pWindow->m_pXDGSurface->toplevel->parent ||
(PSTATE->minSize.x != 0 && PSTATE->minSize.y != 0 && (PSTATE->minSize.x == PSTATE->maxSize.x || PSTATE->minSize.y == PSTATE->maxSize.y)))
2022-03-21 17:24:41 +01:00
return true;
2022-03-20 13:37:07 +01:00
}
return false;
}
void CHyprXWaylandManager::checkBorders(PHLWINDOW pWindow) {
2022-03-22 21:28:57 +01:00
if (!pWindow->m_bIsX11)
return;
for (auto& a : pWindow->m_pXWaylandSurface->atoms) {
if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_NOTIFICATION"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] ||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_COMBO"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] ||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"]) {
2022-09-25 20:07:48 +02:00
2022-03-22 21:28:57 +01:00
pWindow->m_bX11DoesntWantBorders = true;
return;
}
}
if (pWindow->m_iX11Type == 2) {
2022-03-22 21:28:57 +01:00
pWindow->m_bX11DoesntWantBorders = true;
}
2022-03-30 17:39:04 +02:00
}
void CHyprXWaylandManager::setWindowFullscreen(PHLWINDOW pWindow, bool fullscreen) {
2023-06-18 18:14:48 +02:00
if (pWindow->m_bIsX11)
pWindow->m_pXWaylandSurface->setFullscreen(fullscreen);
2024-05-11 00:28:33 +02:00
else if (pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel)
pWindow->m_pXDGSurface->toplevel->setFullscreen(fullscreen);
}
Vector2D CHyprXWaylandManager::getMaxSizeForWindow(PHLWINDOW pWindow) {
if (!validMapped(pWindow))
2022-08-05 19:41:50 +02:00
return Vector2D(99999, 99999);
core: Improve handling of window properties (#6776) * add mWindowProperties modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp * support int values modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * create m_sWindowData modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * simplify some properties modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/managers/KeybindManager.cpp * store multiple values in CWindowOverridableVar modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * use SET_PROP priority for exec rules modified: src/config/ConfigManager.hpp modified: src/desktop/Window.cpp * add default value modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * add setprop toggle modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp * add setprop toggle modified: src/debug/HyprCtl.cpp * make window rules functional modified: src/config/ConfigManager.cpp modified: src/desktop/Window.cpp * minor fixes modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp * properly clean layout data modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp * remove newline modified: src/events/Windows.cpp * fixes modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * use CamelCase modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp
2024-07-11 16:10:42 +02:00
if ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel) ||
pWindow->m_sWindowData.noMaxSize.valueOrDefault())
2022-08-05 19:41:50 +02:00
return Vector2D(99999, 99999);
auto MAXSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->max_width, pWindow->m_pXWaylandSurface->sizeHints->max_height) :
2024-05-11 00:28:33 +02:00
pWindow->m_pXDGSurface->toplevel->current.maxSize;
if (MAXSIZE.x < 5)
MAXSIZE.x = 99999;
if (MAXSIZE.y < 5)
MAXSIZE.y = 99999;
return MAXSIZE;
}
Vector2D CHyprXWaylandManager::getMinSizeForWindow(PHLWINDOW pWindow) {
if (!validMapped(pWindow))
return Vector2D(0, 0);
if ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel))
return Vector2D(0, 0);
auto MINSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->min_width, pWindow->m_pXWaylandSurface->sizeHints->min_height) :
2024-05-11 00:28:33 +02:00
pWindow->m_pXDGSurface->toplevel->current.minSize;
MINSIZE = MINSIZE.clamp({1, 1});
return MINSIZE;
}
Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
CMonitor* pMonitor = nullptr;
double bestDistance = __FLT_MAX__;
for (auto& m : g_pCompositor->m_vMonitors) {
const auto SIZ = *PXWLFORCESCALEZERO ? m->vecTransformedSize : m->vecSize;
double distance =
vecToRectDistanceSquared(coord, {m->vecXWaylandPosition.x, m->vecXWaylandPosition.y}, {m->vecXWaylandPosition.x + SIZ.x - 1, m->vecXWaylandPosition.y + SIZ.y - 1});
if (distance < bestDistance) {
bestDistance = distance;
pMonitor = m.get();
}
}
if (!pMonitor)
return Vector2D{};
// get local coords
Vector2D result = coord - pMonitor->vecXWaylandPosition;
// if scaled, unscale
if (*PXWLFORCESCALEZERO)
result = result / pMonitor->scale;
// add pos
result = result + pMonitor->vecPosition;
return result;
}