diff --git a/src/defines.hpp b/src/defines.hpp index b9ffd5d..a5635c6 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -6,6 +6,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -43,3 +48,6 @@ #define VECTORDELTANONZERO(veca, vecb) ((int)abs(veca.x - vecb.x) > 0 || (int)abs(veca.y - vecb.y) > 0) + +#define PROP(cookie, name, len) const auto cookie = xcb_get_property(DisplayConnection, false, window, name, XCB_GET_PROPERTY_TYPE_ANY, 0, len); \ + const auto cookie##reply = xcb_get_property_reply(DisplayConnection, cookie, NULL) \ No newline at end of file diff --git a/src/events/events.cpp b/src/events/events.cpp index 883474f..a5b1820 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -47,6 +47,46 @@ void Events::eventDestroy(xcb_generic_event_t* event) { } } +CWindow* Events::remapFloatingWindow(int windowID) { + CWindow window; + window.setDrawable(windowID); + window.setIsFloating(true); + window.setDirty(true); + if (!g_pWindowManager->getMonitorFromCursor()) { + Debug::log(ERR, "Monitor was null! (remapWindow)"); + // rip! we cannot continue. + } + const auto CURRENTSCREEN = g_pWindowManager->getMonitorFromCursor()->ID; + window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); + window.setMonitor(CURRENTSCREEN); + + window.setDefaultPosition(Vector2D(0, 0)); + window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f)); + + // Also sets the old one + g_pWindowManager->calculateNewWindowParams(&window); + + // Set real size. No animations in the beginning. Maybe later. TODO? + window.setRealPosition(window.getEffectivePosition()); + window.setRealSize(window.getEffectiveSize()); + + // Add to arr + g_pWindowManager->addWindowToVectorSafe(window); + + Debug::log(LOG, "Created a new window! X: " + std::to_string(window.getPosition().x) + ", Y: " + std::to_string(window.getPosition().y) + ", W: " + std::to_string(window.getSize().x) + ", H:" + std::to_string(window.getSize().y) + " ID: " + std::to_string(windowID)); + + // Set map values + g_pWindowManager->Values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; + xcb_change_window_attributes_checked(g_pWindowManager->DisplayConnection, windowID, XCB_CW_EVENT_MASK, g_pWindowManager->Values); + + g_pWindowManager->setFocusedWindow(windowID); + + // Make all floating windows above + g_pWindowManager->setAllFloatingWindowsTop(); + + return g_pWindowManager->getWindowFromDrawable(windowID); +} + CWindow* Events::remapWindow(int windowID, bool wasfloating) { // Do the setup of the window's params and stuf CWindow window; @@ -145,7 +185,13 @@ void Events::eventMapWindow(xcb_generic_event_t* event) { // Map the window xcb_map_window(g_pWindowManager->DisplayConnection, E->window); - remapWindow(E->window); + // We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it. + // this func also sets some stuff + if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) { + remapFloatingWindow(E->window); + } else { + remapWindow(E->window); + } } void Events::eventButtonPress(xcb_generic_event_t* event) { diff --git a/src/events/events.hpp b/src/events/events.hpp index b477a3d..b2b3369 100644 --- a/src/events/events.hpp +++ b/src/events/events.hpp @@ -17,6 +17,7 @@ namespace Events { // Bypass some events for floating windows CWindow* remapWindow(int, bool floating = false); + CWindow* remapFloatingWindow(int); // A thread to notify xcb to redraw our shiz void redraw(); diff --git a/src/window.hpp b/src/window.hpp index fc14844..c981951 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -32,7 +32,7 @@ public: // ------------------------------------- // - std::string getName(); + EXPOSED_MEMBER(Name, std::string, sz); // Tells the window manager to reload the window's params EXPOSED_MEMBER(Dirty, bool, b); diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 1059bca..e2ba4f3 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -195,6 +195,8 @@ void CWindowManager::setupManager() { ConfigManager::loadConfigLoadVars(); Debug::log(LOG, "Finished setup!"); + + // TODO: EWMH } bool CWindowManager::handleEvent() { @@ -257,6 +259,8 @@ bool CWindowManager::handleEvent() { free(ev); } + // TODO: sanity check on open/closed window. + // refresh and apply the parameters of all dirty windows. refreshDirtyWindows(); @@ -918,4 +922,48 @@ void CWindowManager::setAllFloatingWindowsTop() { xcb_configure_window(g_pWindowManager->DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_STACK_MODE, Values); } } +} + +bool CWindowManager::shouldBeFloatedOnInit(int64_t window) { + // Should be floated also sets some properties + const auto GEOMETRY = xcb_get_geometry(DisplayConnection, window); + xcb_get_geometry_reply_t* geom; + const auto WINDOWATTRCOOKIE = xcb_get_window_attributes(DisplayConnection, window); + const auto ATTRIBUTES = xcb_get_window_attributes_reply(DisplayConnection, WINDOWATTRCOOKIE, 0); + + + PROP(transient_cookie, XCB_ATOM_WM_TRANSIENT_FOR, UINT32_MAX); + PROP(title_cookie, XCB_ATOM_WM_NAME, 128); + PROP(class_cookie, XCB_ATOM_WM_CLASS, 128); + PROP(wm_machine_cookie, XCB_ATOM_WM_CLIENT_MACHINE, UINT32_MAX); + + // get stuffza + + // floating for krunner + // TODO: config this + const size_t PROPLEN = xcb_get_property_value_length(class_cookiereply); + char* NEWCLASS = (char*)xcb_get_property_value(class_cookiereply); + const size_t CLASSNAMEINDEX = strnlen(NEWCLASS, PROPLEN) + 1; + + const char* CLASSINSTANCE = strndup(NEWCLASS, PROPLEN); + const char* CLASSNAME; + if (CLASSNAMEINDEX < PROPLEN) { + CLASSNAME = strndup(NEWCLASS + CLASSNAMEINDEX, PROPLEN - CLASSNAMEINDEX); + } else { + CLASSNAME = ""; + } + + Debug::log(LOG, "New window got class " + (std::string)CLASSINSTANCE + " -> " + CLASSNAME); + + free(class_cookiereply); + + xcb_change_property(DisplayConnection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen("hypr"), "hypr"); + + // TODO: add a role cookie, somehow. + + if (((std::string)CLASSNAME).find("krunner") != std::string::npos) { + return true; + } + + return false; } \ No newline at end of file diff --git a/src/windowManager.hpp b/src/windowManager.hpp index fdf947e..08cbf9c 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -77,6 +77,8 @@ public: // finds a window that's tiled at cursor. CWindow* findWindowAtCursor(); + bool shouldBeFloatedOnInit(int64_t); + private: // Internal WM functions that don't have to be exposed