2022-03-18 20:03:39 +01:00
|
|
|
#include "XWaylandManager.hpp"
|
|
|
|
#include "../Compositor.hpp"
|
|
|
|
#include "../events/Events.hpp"
|
2023-06-23 21:14:04 +02:00
|
|
|
#include "xdg-output-unstable-v1-protocol.h"
|
|
|
|
|
|
|
|
#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-10-27 12:26:35 +02:00
|
|
|
#ifndef NO_XWAYLAND
|
|
|
|
m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1);
|
2022-03-18 20:03:39 +01:00
|
|
|
|
2022-10-27 12:26:35 +02:00
|
|
|
if (!m_sWLRXWayland) {
|
|
|
|
Debug::log(ERR, "Couldn't start up the XWaylandManager because wlr_xwayland_create returned a nullptr!");
|
|
|
|
return;
|
|
|
|
}
|
2022-03-18 20:03:39 +01:00
|
|
|
|
2022-10-27 12:26:35 +02:00
|
|
|
addWLSignal(&m_sWLRXWayland->events.ready, &Events::listen_readyXWayland, m_sWLRXWayland, "XWayland Manager");
|
|
|
|
addWLSignal(&m_sWLRXWayland->events.new_surface, &Events::listen_surfaceXWayland, m_sWLRXWayland, "XWayland Manager");
|
2022-03-18 20:03:39 +01:00
|
|
|
|
2022-10-27 12:26:35 +02:00
|
|
|
setenv("DISPLAY", m_sWLRXWayland->display_name, 1);
|
2022-03-18 20:03:39 +01:00
|
|
|
|
2023-09-06 12:51:36 +02:00
|
|
|
Debug::log(LOG, "CHyprXWaylandManager started on display {}", m_sWLRXWayland->display_name);
|
2022-10-27 12:26:35 +02:00
|
|
|
#else
|
2022-12-16 18:17:31 +01:00
|
|
|
unsetenv("DISPLAY"); // unset DISPLAY so that X11 apps do not try to start on a different/invalid DISPLAY
|
2022-10-27 12:26:35 +02:00
|
|
|
#endif
|
2022-03-18 20:03:39 +01:00
|
|
|
}
|
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
CHyprXWaylandManager::~CHyprXWaylandManager() {}
|
2022-03-18 20:03:39 +01:00
|
|
|
|
|
|
|
wlr_surface* CHyprXWaylandManager::getWindowSurface(CWindow* pWindow) {
|
|
|
|
if (pWindow->m_bIsX11)
|
|
|
|
return pWindow->m_uSurface.xwayland->surface;
|
|
|
|
|
|
|
|
return pWindow->m_uSurface.xdg->surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) {
|
2022-08-31 11:12:46 +02:00
|
|
|
if (!pSurface)
|
|
|
|
return;
|
|
|
|
|
2023-02-03 13:43:43 +01:00
|
|
|
if (wlr_xdg_surface_try_from_wlr_surface(pSurface)) {
|
2023-06-18 18:14:48 +02:00
|
|
|
if (const auto PSURF = wlr_xdg_surface_try_from_wlr_surface(pSurface); PSURF && PSURF->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
2022-08-21 23:16:54 +02:00
|
|
|
wlr_xdg_toplevel_set_activated(PSURF->toplevel, activate);
|
2023-06-18 18:14:48 +02:00
|
|
|
|
2023-02-03 13:43:43 +01:00
|
|
|
} else if (wlr_xwayland_surface_try_from_wlr_surface(pSurface)) {
|
2023-11-24 11:54:21 +01:00
|
|
|
const auto XSURF = wlr_xwayland_surface_try_from_wlr_surface(pSurface);
|
|
|
|
wlr_xwayland_surface_activate(XSURF, activate);
|
2022-07-07 21:47:59 +02:00
|
|
|
|
2023-11-24 11:54:21 +01:00
|
|
|
if (activate && !XSURF->override_redirect)
|
|
|
|
wlr_xwayland_surface_restack(XSURF, nullptr, XCB_STACK_MODE_ABOVE);
|
2022-04-05 18:29:58 +02:00
|
|
|
}
|
2022-03-18 20:03:39 +01:00
|
|
|
}
|
|
|
|
|
2022-04-02 18:57:09 +02:00
|
|
|
void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
2022-04-05 18:29:58 +02:00
|
|
|
if (pWindow->m_bIsX11) {
|
2024-03-02 01:35:17 +01:00
|
|
|
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) {
|
|
|
|
wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false);
|
2023-11-24 11:54:21 +01:00
|
|
|
if (!pWindow->m_uSurface.xwayland->override_redirect)
|
|
|
|
wlr_xwayland_surface_restack(pWindow->m_uSurface.xwayland, nullptr, XCB_STACK_MODE_ABOVE);
|
2022-10-28 20:18:10 +02:00
|
|
|
}
|
2022-12-16 18:17:31 +01:00
|
|
|
|
2022-04-02 18:57:09 +02:00
|
|
|
wlr_xwayland_surface_activate(pWindow->m_uSurface.xwayland, activate);
|
2022-12-16 18:17:31 +01:00
|
|
|
} else
|
2022-04-02 18:57:09 +02:00
|
|
|
wlr_xdg_toplevel_set_activated(pWindow->m_uSurface.xdg->toplevel, activate);
|
|
|
|
|
2022-10-25 15:19:24 +02:00
|
|
|
if (activate) {
|
2022-12-16 18:17:31 +01:00
|
|
|
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)
|
|
|
|
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow;
|
2022-04-02 18:57:09 +02:00
|
|
|
}
|
|
|
|
|
2023-11-04 18:03:05 +01:00
|
|
|
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, CBox* pbox) {
|
2022-03-18 20:03:39 +01:00
|
|
|
if (pWindow->m_bIsX11) {
|
2022-10-17 12:18:45 +02:00
|
|
|
const auto SIZEHINTS = pWindow->m_uSurface.xwayland->size_hints;
|
|
|
|
|
2022-10-17 15:26:18 +02:00
|
|
|
if (SIZEHINTS && pWindow->m_iX11Type != 2) {
|
2022-12-16 18:17:31 +01:00
|
|
|
pbox->x = SIZEHINTS->x;
|
|
|
|
pbox->y = SIZEHINTS->y;
|
|
|
|
pbox->width = SIZEHINTS->width;
|
2022-10-17 12:18:45 +02:00
|
|
|
pbox->height = SIZEHINTS->height;
|
|
|
|
} else {
|
2022-12-16 18:17:31 +01:00
|
|
|
pbox->x = pWindow->m_uSurface.xwayland->x;
|
|
|
|
pbox->y = pWindow->m_uSurface.xwayland->y;
|
|
|
|
pbox->width = pWindow->m_uSurface.xwayland->width;
|
2022-10-17 12:18:45 +02:00
|
|
|
pbox->height = pWindow->m_uSurface.xwayland->height;
|
|
|
|
}
|
2023-11-04 18:03:05 +01:00
|
|
|
} else {
|
|
|
|
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, pbox->pWlr());
|
|
|
|
pbox->applyFromWlr();
|
|
|
|
}
|
2022-03-18 20:03:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CHyprXWaylandManager::getTitle(CWindow* pWindow) {
|
2022-03-22 17:41:23 +01:00
|
|
|
try {
|
|
|
|
if (pWindow->m_bIsX11) {
|
2024-02-29 02:21:15 +01:00
|
|
|
if (!pWindow->m_bIsMapped)
|
2024-02-29 00:14:50 +01:00
|
|
|
return "";
|
|
|
|
|
2022-03-29 15:30:08 +02:00
|
|
|
if (pWindow->m_uSurface.xwayland && pWindow->m_uSurface.xwayland->title) {
|
2022-03-22 17:41:23 +01:00
|
|
|
return std::string(pWindow->m_uSurface.xwayland->title);
|
|
|
|
}
|
2022-03-24 18:22:01 +01:00
|
|
|
} else if (pWindow->m_uSurface.xdg) {
|
2024-02-29 18:23:44 +01:00
|
|
|
if (pWindow->m_bFadingOut || !pWindow->m_uSurface.xdg)
|
|
|
|
return "";
|
|
|
|
|
2022-03-29 15:30:08 +02:00
|
|
|
if (pWindow->m_uSurface.xdg->toplevel && pWindow->m_uSurface.xdg->toplevel->title) {
|
2022-03-24 18:22:01 +01:00
|
|
|
return std::string(pWindow->m_uSurface.xdg->toplevel->title);
|
|
|
|
}
|
2022-03-22 17:41:23 +01:00
|
|
|
} else {
|
|
|
|
return "";
|
2022-03-22 17:31:19 +01:00
|
|
|
}
|
2022-12-16 18:17:31 +01:00
|
|
|
} catch (...) { Debug::log(ERR, "Error in getTitle (probably null title)"); }
|
2022-03-22 17:41:23 +01:00
|
|
|
|
2022-03-24 18:22:01 +01:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CHyprXWaylandManager::getAppIDClass(CWindow* pWindow) {
|
|
|
|
try {
|
|
|
|
if (pWindow->m_bIsX11) {
|
2024-02-29 02:21:15 +01:00
|
|
|
if (!pWindow->m_bIsMapped)
|
2024-02-29 00:14:50 +01:00
|
|
|
return "";
|
|
|
|
|
2023-02-03 17:17:31 +01:00
|
|
|
if (pWindow->m_uSurface.xwayland && pWindow->m_uSurface.xwayland->_class) {
|
2022-03-24 18:22:01 +01:00
|
|
|
return std::string(pWindow->m_uSurface.xwayland->_class);
|
|
|
|
}
|
|
|
|
} else if (pWindow->m_uSurface.xdg) {
|
2024-02-29 18:23:44 +01:00
|
|
|
if (pWindow->m_bFadingOut || !pWindow->m_uSurface.xdg)
|
|
|
|
return "";
|
|
|
|
|
2023-02-03 17:17:31 +01:00
|
|
|
if (pWindow->m_uSurface.xdg->toplevel && pWindow->m_uSurface.xdg->toplevel->app_id) {
|
2022-03-24 18:22:01 +01:00
|
|
|
return std::string(pWindow->m_uSurface.xdg->toplevel->app_id);
|
2022-03-22 17:41:23 +01:00
|
|
|
}
|
2023-06-18 18:14:48 +02:00
|
|
|
} else
|
2022-03-22 17:41:23 +01:00
|
|
|
return "";
|
2023-09-06 12:51:36 +02:00
|
|
|
} catch (std::logic_error& e) { Debug::log(ERR, "Error in getAppIDClass: {}", e.what()); }
|
2022-03-18 20:03:39 +01:00
|
|
|
|
2022-03-22 17:31:19 +01:00
|
|
|
return "";
|
2022-03-18 20:03:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
|
2023-06-18 18:14:48 +02:00
|
|
|
if (pWindow->m_bIsX11)
|
2022-03-18 20:03:39 +01:00
|
|
|
wlr_xwayland_surface_close(pWindow->m_uSurface.xwayland);
|
2023-06-18 18:14:48 +02:00
|
|
|
else
|
2022-03-18 20:03:39 +01:00
|
|
|
wlr_xdg_toplevel_send_close(pWindow->m_uSurface.xdg->toplevel);
|
|
|
|
}
|
|
|
|
|
2023-02-28 20:36:36 +01:00
|
|
|
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool force) {
|
|
|
|
|
2024-02-18 16:00:34 +01:00
|
|
|
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling");
|
2023-08-15 19:15:37 +02:00
|
|
|
|
|
|
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
2022-07-28 23:55:00 +02:00
|
|
|
|
2024-02-05 21:56:20 +01:00
|
|
|
size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
|
2024-02-05 15:08:08 +01:00
|
|
|
|
2023-08-15 19:15:37 +02:00
|
|
|
// calculate pos
|
|
|
|
// TODO: this should be decoupled from setWindowSize IMO
|
2024-03-02 01:35:17 +01:00
|
|
|
Vector2D windowPos = pWindow->m_vRealPosition.value();
|
2022-07-28 23:55:00 +02:00
|
|
|
|
2023-12-17 20:58:11 +01:00
|
|
|
if (pWindow->m_bIsX11 && PMONITOR) {
|
2023-08-15 19:15:37 +02:00
|
|
|
windowPos = windowPos - PMONITOR->vecPosition; // normalize to monitor
|
2024-02-18 16:00:34 +01:00
|
|
|
if (**PXWLFORCESCALEZERO)
|
2023-08-15 19:15:37 +02:00
|
|
|
windowPos = windowPos * PMONITOR->scale; // scale if applicable
|
|
|
|
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
|
|
|
|
}
|
|
|
|
|
2023-11-10 01:13:22 +01:00
|
|
|
if (!force && ((pWindow->m_vPendingReportedSize == size && windowPos == pWindow->m_vReportedPosition) || (pWindow->m_vPendingReportedSize == size && !pWindow->m_bIsX11)))
|
2023-08-15 19:15:37 +02:00
|
|
|
return;
|
|
|
|
|
2023-10-20 21:15:41 +02:00
|
|
|
pWindow->m_vReportedPosition = windowPos;
|
|
|
|
pWindow->m_vPendingReportedSize = size;
|
2023-06-11 21:52:13 +02:00
|
|
|
|
|
|
|
pWindow->m_fX11SurfaceScaledBy = 1.f;
|
|
|
|
|
2024-02-18 16:00:34 +01:00
|
|
|
if (**PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) {
|
2023-12-17 20:58:11 +01:00
|
|
|
size = size * PMONITOR->scale;
|
|
|
|
pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale;
|
2023-06-11 21:52:13 +02:00
|
|
|
}
|
|
|
|
|
2022-03-19 15:59:53 +01:00
|
|
|
if (pWindow->m_bIsX11)
|
2023-09-03 12:51:48 +02:00
|
|
|
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, windowPos.x, windowPos.y, size.x, size.y);
|
2022-06-22 15:45:56 +02:00
|
|
|
else
|
2023-11-10 01:13:22 +01:00
|
|
|
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y), size.floor()));
|
2022-03-18 20:03:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
|
2023-11-11 18:13:20 +01:00
|
|
|
if (pWindow->m_bIsX11)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wlr_xdg_toplevel_set_tiled(pWindow->m_uSurface.xdg->toplevel, edgez);
|
|
|
|
wlr_xdg_toplevel_set_maximized(pWindow->m_uSurface.xdg->toplevel, true);
|
2022-03-18 20:03:39 +01:00
|
|
|
}
|
|
|
|
|
2022-03-19 10:53:39 +01:00
|
|
|
wlr_surface* CHyprXWaylandManager::surfaceAt(CWindow* pWindow, const Vector2D& client, Vector2D& surface) {
|
|
|
|
if (pWindow->m_bIsX11)
|
|
|
|
return wlr_surface_surface_at(pWindow->m_uSurface.xwayland->surface, client.x, client.y, &surface.x, &surface.y);
|
2022-03-18 20:03:39 +01:00
|
|
|
|
2022-03-19 10:53:39 +01:00
|
|
|
return wlr_xdg_surface_surface_at(pWindow->m_uSurface.xdg, client.x, client.y, &surface.x, &surface.y);
|
2022-03-20 13:37:07 +01:00
|
|
|
}
|
|
|
|
|
2024-02-29 00:14:50 +01:00
|
|
|
bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow, bool pending) {
|
2022-03-20 13:37:07 +01:00
|
|
|
if (pWindow->m_bIsX11) {
|
|
|
|
for (size_t i = 0; i < pWindow->m_uSurface.xwayland->window_type_len; i++)
|
2022-12-16 18:17:31 +01:00
|
|
|
if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLBAR"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_UTILITY"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] ||
|
2023-04-22 23:20:48 +02:00
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"]) {
|
2022-12-20 00:43:47 +01:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"])
|
|
|
|
pWindow->m_bX11ShouldntFocus = true;
|
|
|
|
|
2024-03-03 01:18:53 +01:00
|
|
|
pWindow->m_bNoInitialFocus = true;
|
2022-12-16 18:17:31 +01:00
|
|
|
return true;
|
|
|
|
}
|
2022-03-20 19:26:16 +01:00
|
|
|
|
2022-04-24 17:53:50 +02:00
|
|
|
if (pWindow->m_uSurface.xwayland->role) {
|
|
|
|
try {
|
|
|
|
std::string winrole = std::string(pWindow->m_uSurface.xwayland->role);
|
2022-07-06 16:50:11 +02:00
|
|
|
if (winrole.contains("pop-up") || winrole.contains("task_dialog")) {
|
2022-04-24 17:53:50 +02:00
|
|
|
return true;
|
|
|
|
}
|
2023-09-06 12:51:36 +02:00
|
|
|
} catch (std::exception& e) { Debug::log(ERR, "Error in shouldBeFloated, winrole threw {}", e.what()); }
|
2022-04-24 17:53:50 +02:00
|
|
|
}
|
|
|
|
|
2022-03-22 18:29:13 +01:00
|
|
|
if (pWindow->m_uSurface.xwayland->modal) {
|
|
|
|
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
|
|
|
|
2023-06-18 18:14:48 +02:00
|
|
|
if (pWindow->m_iX11Type == 2)
|
2022-04-18 13:10:58 +02:00
|
|
|
return true; // override_redirect
|
|
|
|
|
2022-03-20 19:26:16 +01:00
|
|
|
const auto SIZEHINTS = pWindow->m_uSurface.xwayland->size_hints;
|
2022-03-22 21:28:57 +01:00
|
|
|
if (SIZEHINTS && (pWindow->m_uSurface.xwayland->parent || ((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-02-29 00:14:50 +01:00
|
|
|
const auto PSTATE = pending ? &pWindow->m_uSurface.xdg->toplevel->pending : &pWindow->m_uSurface.xdg->toplevel->current;
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
if ((PSTATE->min_width != 0 && PSTATE->min_height != 0 && (PSTATE->min_width == PSTATE->max_width || PSTATE->min_height == PSTATE->max_height)) ||
|
|
|
|
pWindow->m_uSurface.xdg->toplevel->parent)
|
2022-03-21 17:24:41 +01:00
|
|
|
return true;
|
2022-03-20 13:37:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2022-03-20 19:14:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprXWaylandManager::moveXWaylandWindow(CWindow* pWindow, const Vector2D& pos) {
|
2022-04-07 18:54:31 +02:00
|
|
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
|
|
|
return;
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2023-06-18 18:14:48 +02:00
|
|
|
if (!pWindow->m_bIsX11)
|
|
|
|
return;
|
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.value().x, pWindow->m_vRealSize.value().y);
|
2022-03-22 17:31:19 +01:00
|
|
|
}
|
2022-03-22 21:28:57 +01:00
|
|
|
|
|
|
|
void CHyprXWaylandManager::checkBorders(CWindow* pWindow) {
|
|
|
|
if (!pWindow->m_bIsX11)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < pWindow->m_uSurface.xwayland->window_type_len; i++) {
|
2022-12-16 18:17:31 +01:00
|
|
|
if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_NOTIFICATION"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_COMBO"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] ||
|
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] ||
|
2022-03-22 21:28:57 +01:00
|
|
|
pWindow->m_uSurface.xwayland->window_type[i] == 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-03 13:06:13 +01:00
|
|
|
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(CWindow* pWindow, bool fullscreen) {
|
2023-06-18 18:14:48 +02:00
|
|
|
if (pWindow->m_bIsX11)
|
2022-03-30 17:39:04 +02:00
|
|
|
wlr_xwayland_surface_set_fullscreen(pWindow->m_uSurface.xwayland, fullscreen);
|
2023-06-18 18:14:48 +02:00
|
|
|
else
|
2022-03-30 17:39:04 +02:00
|
|
|
wlr_xdg_toplevel_set_fullscreen(pWindow->m_uSurface.xdg->toplevel, fullscreen);
|
2022-05-25 18:42:38 +02:00
|
|
|
|
2022-05-29 11:24:42 +02:00
|
|
|
if (pWindow->m_phForeignToplevel)
|
|
|
|
wlr_foreign_toplevel_handle_v1_set_fullscreen(pWindow->m_phForeignToplevel, fullscreen);
|
2022-08-05 18:10:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Vector2D CHyprXWaylandManager::getMaxSizeForWindow(CWindow* pWindow) {
|
2022-08-05 19:41:50 +02:00
|
|
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
|
|
|
return Vector2D(99999, 99999);
|
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
if ((pWindow->m_bIsX11 && !pWindow->m_uSurface.xwayland->size_hints) || (!pWindow->m_bIsX11 && !pWindow->m_uSurface.xdg->toplevel) ||
|
|
|
|
pWindow->m_sAdditionalConfigData.noMaxSize)
|
2022-08-05 19:41:50 +02:00
|
|
|
return Vector2D(99999, 99999);
|
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
auto MAXSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_uSurface.xwayland->size_hints->max_width, pWindow->m_uSurface.xwayland->size_hints->max_height) :
|
|
|
|
Vector2D(pWindow->m_uSurface.xdg->toplevel->current.max_width, pWindow->m_uSurface.xdg->toplevel->current.max_height);
|
2022-08-05 18:10:59 +02:00
|
|
|
|
|
|
|
if (MAXSIZE.x < 5)
|
|
|
|
MAXSIZE.x = 99999;
|
|
|
|
if (MAXSIZE.y < 5)
|
|
|
|
MAXSIZE.y = 99999;
|
|
|
|
|
|
|
|
return MAXSIZE;
|
2023-08-15 20:09:32 +02:00
|
|
|
}
|
|
|
|
|
2024-03-02 16:25:32 +01:00
|
|
|
Vector2D CHyprXWaylandManager::getMinSizeForWindow(CWindow* pWindow) {
|
|
|
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
|
|
|
return Vector2D(0, 0);
|
|
|
|
|
|
|
|
if ((pWindow->m_bIsX11 && !pWindow->m_uSurface.xwayland->size_hints) || (!pWindow->m_bIsX11 && !pWindow->m_uSurface.xdg->toplevel))
|
|
|
|
return Vector2D(0, 0);
|
|
|
|
|
|
|
|
auto MINSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_uSurface.xwayland->size_hints->min_width, pWindow->m_uSurface.xwayland->size_hints->min_height) :
|
|
|
|
Vector2D(pWindow->m_uSurface.xdg->toplevel->current.min_width, pWindow->m_uSurface.xdg->toplevel->current.min_height);
|
|
|
|
|
|
|
|
MINSIZE = MINSIZE.clamp({1, 1});
|
|
|
|
|
|
|
|
return MINSIZE;
|
|
|
|
}
|
|
|
|
|
2023-08-15 20:09:32 +02:00
|
|
|
Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
|
|
|
|
|
2024-02-18 16:00:34 +01:00
|
|
|
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling");
|
2023-08-15 20:09:32 +02:00
|
|
|
|
2023-09-04 17:30:44 +02:00
|
|
|
CMonitor* pMonitor = nullptr;
|
|
|
|
double bestDistance = __FLT_MAX__;
|
2023-08-15 20:09:32 +02:00
|
|
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
2024-02-18 16:00:34 +01:00
|
|
|
const auto SIZ = **PXWLFORCESCALEZERO ? m->vecTransformedSize : m->vecSize;
|
2023-09-04 17:30:44 +02:00
|
|
|
|
|
|
|
double distance =
|
2023-09-10 21:19:06 +02:00
|
|
|
vecToRectDistanceSquared(coord, {m->vecXWaylandPosition.x, m->vecXWaylandPosition.y}, {m->vecXWaylandPosition.x + SIZ.x - 1, m->vecXWaylandPosition.y + SIZ.y - 1});
|
2023-09-04 17:30:44 +02:00
|
|
|
|
|
|
|
if (distance < bestDistance) {
|
|
|
|
bestDistance = distance;
|
|
|
|
pMonitor = m.get();
|
2023-08-15 20:09:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pMonitor)
|
|
|
|
return Vector2D{};
|
|
|
|
|
|
|
|
// get local coords
|
|
|
|
Vector2D result = coord - pMonitor->vecXWaylandPosition;
|
|
|
|
// if scaled, unscale
|
2024-02-18 16:00:34 +01:00
|
|
|
if (**PXWLFORCESCALEZERO)
|
2023-08-15 20:09:32 +02:00
|
|
|
result = result / pMonitor->scale;
|
|
|
|
// add pos
|
|
|
|
result = result + pMonitor->vecPosition;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|