diff --git a/src/Compositor.hpp b/src/Compositor.hpp index f14a3cae..fb58a6f3 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -55,7 +55,6 @@ public: CWindow* m_pLastFocus = nullptr; SMonitor* m_pLastMonitor = nullptr; - // ------------------------------------------------- // SMonitor* getMonitorFromID(const int&); @@ -77,4 +76,19 @@ private: }; -inline std::unique_ptr g_pCompositor; \ No newline at end of file +inline std::unique_ptr g_pCompositor; + +// For XWayland +inline std::map HYPRATOMS = { + HYPRATOM("_NET_WM_WINDOW_TYPE"), + HYPRATOM("_NET_WM_WINDOW_TYPE_NORMAL"), + HYPRATOM("_NET_WM_WINDOW_TYPE_DOCK"), + HYPRATOM("_NET_WM_WINDOW_TYPE_DIALOG"), + HYPRATOM("_NET_WM_WINDOW_TYPE_UTILITY"), + HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLBAR"), + HYPRATOM("_NET_WM_WINDOW_TYPE_SPLASH"), + HYPRATOM("_NET_WM_WINDOW_TYPE_MENU"), + HYPRATOM("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"), + HYPRATOM("_NET_WM_WINDOW_TYPE_POPUP_MENU"), + HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLTIP"), + HYPRATOM("_NET_WM_WINDOW_TYPE_NOTIFICATION")}; \ No newline at end of file diff --git a/src/defines.hpp b/src/defines.hpp index d048c658..0be79cb6 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -20,4 +20,6 @@ #define ALPHA(c) ((double)(((c) >> 24) & 0xff) / 255.0) #define RED(c) ((double)(((c) >> 16) & 0xff) / 255.0) #define GREEN(c) ((double)(((c) >> 8) & 0xff) / 255.0) -#define BLUE(c) ((double)(((c)) & 0xff) / 255.0) \ No newline at end of file +#define BLUE(c) ((double)(((c)) & 0xff) / 255.0) + +#define HYPRATOM(name) {name, 0} \ No newline at end of file diff --git a/src/events/Events.cpp b/src/events/Events.cpp index dd34bba8..583d52aa 100644 --- a/src/events/Events.cpp +++ b/src/events/Events.cpp @@ -396,7 +396,10 @@ void Events::listener_mapWindow(wl_listener* listener, void* data) { PWINDOW->m_iMonitorID = PMONITOR->ID; PWINDOW->m_bMappedX11 = true; - g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); + if (g_pXWaylandManager->shouldBeFloated(PWINDOW)) + g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW); + else + g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); g_pCompositor->focusWindow(PWINDOW); @@ -579,11 +582,21 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) { const auto XCBCONNECTION = xcb_connect(g_pXWaylandManager->m_sWLRXWayland->display_name, NULL); const auto ERR = xcb_connection_has_error(XCBCONNECTION); if (ERR) { - Debug::log(LogLevel::ERR, "xcb_connection_has_error failed with %i", ERR); + Debug::log(LogLevel::ERR, "XWayland -> xcb_connection_has_error failed with %i", ERR); return; } - // TODO: atoms + for (auto& ATOM : HYPRATOMS) { + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(XCBCONNECTION, 0, ATOM.first.length(), ATOM.first.c_str()); + xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(XCBCONNECTION, cookie, NULL); + + if (!reply) { + Debug::log(LogLevel::ERR, "XWayland -> Atom failed: %s", ATOM.first.c_str()); + continue; + } + + ATOM.second = reply->atom; + } wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sWLRSeat); diff --git a/src/events/Events.hpp b/src/events/Events.hpp index 90c23eaa..9a1a9cb1 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -21,6 +21,11 @@ namespace Events { LISTENER(destroyPopup); LISTENER(commitPopup); + LISTENER(newPopupXDG); + LISTENER(mapPopupXDG); + LISTENER(unmapPopupXDG); + LISTENER(destroyPopupXDG); + LISTENER(commitPopupXDG); // Surface XDG (window) LISTENER(newXDGSurface); diff --git a/src/includes.hpp b/src/includes.hpp index c5955e73..c29644de 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -69,6 +69,7 @@ extern "C" { #include #include #include +#include } #undef class diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 129c2142..9f97cece 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -303,4 +303,12 @@ void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) { if (PMONITOR) DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID; +} + +void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) { + const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(pWindow); + const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); + + pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height); + pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.x) / 2.f, PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.y) / 2.f); } \ No newline at end of file diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index b9136727..5c2cbde8 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -35,6 +35,7 @@ public: virtual void changeWindowFloatingMode(CWindow*); virtual void onBeginDragWindow(); virtual void onMouseMove(const Vector2D&); + virtual void onWindowCreatedFloating(CWindow*); private: diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index bf0d135b..c3fbd667 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -14,5 +14,6 @@ public: virtual void changeWindowFloatingMode(CWindow*) = 0; virtual void onBeginDragWindow() = 0; virtual void onMouseMove(const Vector2D&) = 0; + virtual void onWindowCreatedFloating(CWindow*) = 0; }; \ No newline at end of file diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 96bf65fa..8edad6ad 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -78,6 +78,10 @@ void CKeybindManager::toggleActiveFloating(std::string args) { if (g_pCompositor->windowValidMapped(ACTIVEWINDOW)) { ACTIVEWINDOW->m_bIsFloating = !ACTIVEWINDOW->m_bIsFloating; + + ACTIVEWINDOW->m_vRealPosition = ACTIVEWINDOW->m_vRealPosition + Vector2D(5, 5); + ACTIVEWINDOW->m_vSize = ACTIVEWINDOW->m_vRealPosition - Vector2D(10, 10); + g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW); } } \ No newline at end of file diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 13b57b82..50d12383 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -84,4 +84,17 @@ wlr_surface* CHyprXWaylandManager::surfaceAt(CWindow* pWindow, const Vector2D& c return wlr_surface_surface_at(pWindow->m_uSurface.xwayland->surface, client.x, client.y, &surface.x, &surface.y); return wlr_xdg_surface_surface_at(pWindow->m_uSurface.xdg, client.x, client.y, &surface.x, &surface.y); +} + +bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) { + if (pWindow->m_bIsX11) { + for (size_t i = 0; i < pWindow->m_uSurface.xwayland->window_type_len; i++) + 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"]) + return true; + } + + return false; } \ No newline at end of file diff --git a/src/managers/XWaylandManager.hpp b/src/managers/XWaylandManager.hpp index e439c9fb..11f3ac92 100644 --- a/src/managers/XWaylandManager.hpp +++ b/src/managers/XWaylandManager.hpp @@ -18,6 +18,7 @@ public: void setWindowSize(CWindow*, const Vector2D&); void setWindowStyleTiled(CWindow*, uint32_t); wlr_surface* surfaceAt(CWindow*, const Vector2D&, Vector2D&); + bool shouldBeFloated(CWindow*); }; inline std::unique_ptr g_pXWaylandManager; \ No newline at end of file