diff --git a/src/KeybindManager.cpp b/src/KeybindManager.cpp index 539a50b..02488c1 100644 --- a/src/KeybindManager.cpp +++ b/src/KeybindManager.cpp @@ -146,22 +146,7 @@ void KeybindManager::changeworkspace(std::string arg) { } void KeybindManager::toggleActiveWindowFullscreen(std::string unusedArg) { - if (!g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow)) - return; - - const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); - const auto MONITOR = g_pWindowManager->getMonitorFromWindow(PWINDOW); - - g_pWindowManager->setAllWorkspaceWindowsDirtyByID(g_pWindowManager->activeWorkspaces[MONITOR->ID]); - - PWINDOW->setFullscreen(!PWINDOW->getFullscreen()); - g_pWindowManager->getWorkspaceByID(PWINDOW->getWorkspaceID())->setHasFullscreenWindow(PWINDOW->getFullscreen()); - - // Fix windows over and below fullscreen. - if (PWINDOW->getFullscreen()) - g_pWindowManager->setAllWorkspaceWindowsUnderFullscreen(g_pWindowManager->activeWorkspaces[MONITOR->ID]); - else - g_pWindowManager->setAllWorkspaceWindowsAboveFullscreen(g_pWindowManager->activeWorkspaces[MONITOR->ID]); + g_pWindowManager->toggleWindowFullscrenn(g_pWindowManager->LastWindow); } void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) { diff --git a/src/events/events.cpp b/src/events/events.cpp index 7eaf324..32c8244 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -533,6 +533,9 @@ void Events::eventExpose(xcb_generic_event_t* event) { void Events::eventClientMessage(xcb_generic_event_t* event) { const auto E = reinterpret_cast(event); + if (!g_pWindowManager->statusBar) + g_pWindowManager->handleClientMessage(E); // Client message handling + RETURNIFMAIN; // Only for the bar // Tray clients diff --git a/src/utilities/XCBProps.cpp b/src/utilities/XCBProps.cpp index 26115f5..9ff6148 100644 --- a/src/utilities/XCBProps.cpp +++ b/src/utilities/XCBProps.cpp @@ -76,4 +76,34 @@ std::string getWindowName(uint64_t window) { free(name_cookiereply); return stringname; +} + +void removeAtom(const int& window, xcb_atom_t prop, xcb_atom_t atom) { + xcb_grab_server(DisplayConnection); + + const auto REPLY = xcb_get_property_reply(DisplayConnection, xcb_get_property(DisplayConnection, false, window, prop, XCB_GET_PROPERTY_TYPE_ANY, 0, 4096), NULL); + + if (!REPLY || xcb_get_property_value_length(REPLY) == 0) { + free(REPLY); + xcb_ungrab_server(DisplayConnection); + } + + xcb_atom_t* atomsList = (xcb_atom_t*)xcb_get_property_value(REPLY); + if (!atomsList) { + free(REPLY); + xcb_ungrab_server(DisplayConnection); + } + + int valuesnum = 0; + const int current_size = xcb_get_property_value_length(REPLY) / (REPLY->format / 8); + xcb_atom_t values[current_size]; + for (int i = 0; i < current_size; i++) { + if (atomsList[i] != atom) + values[valuesnum++] = atomsList[i]; + } + + xcb_change_property(DisplayConnection, XCB_PROP_MODE_REPLACE, window, prop, XCB_ATOM_ATOM, 32, valuesnum, values); + + free(REPLY); + xcb_ungrab_server(DisplayConnection); } \ No newline at end of file diff --git a/src/utilities/XCBProps.hpp b/src/utilities/XCBProps.hpp index 1cffdc7..b6ea488 100644 --- a/src/utilities/XCBProps.hpp +++ b/src/utilities/XCBProps.hpp @@ -2,8 +2,10 @@ #include #include - +#include std::pair getClassName(int64_t window); std::string getRoleName(int64_t window); -std::string getWindowName(uint64_t window); \ No newline at end of file +std::string getWindowName(uint64_t window); + +void removeAtom(const int& window, xcb_atom_t prop, xcb_atom_t atom); \ No newline at end of file diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 5a22f4f..3f2b2c9 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -1717,4 +1717,61 @@ void CWindowManager::setAllWorkspaceWindowsUnderFullscreen(const int& workspace) w.setUnderFullscreen(true); } } +} + +void CWindowManager::toggleWindowFullscrenn(const int& window) { + const auto PWINDOW = getWindowFromDrawable(window); + + if (!PWINDOW) + return; + + const auto MONITOR = getMonitorFromWindow(PWINDOW); + + setAllWorkspaceWindowsDirtyByID(activeWorkspaces[MONITOR->ID]); + + PWINDOW->setFullscreen(!PWINDOW->getFullscreen()); + getWorkspaceByID(PWINDOW->getWorkspaceID())->setHasFullscreenWindow(PWINDOW->getFullscreen()); + + // Fix windows over and below fullscreen. + if (PWINDOW->getFullscreen()) + setAllWorkspaceWindowsUnderFullscreen(activeWorkspaces[MONITOR->ID]); + else + setAllWorkspaceWindowsAboveFullscreen(activeWorkspaces[MONITOR->ID]); + + // EWMH + Values[0] = HYPRATOMS["_NET_WM_STATE_FULLSCREEN"]; + if (PWINDOW->getFullscreen()) + xcb_change_property(DisplayConnection, XCB_PROP_MODE_APPEND, window, HYPRATOMS["_NET_WM_STATE"], XCB_ATOM_ATOM, 32, 1, Values); + else + removeAtom(window, HYPRATOMS["_NET_WM_STATE"], HYPRATOMS["_NET_WM_STATE_FULLSCREEN"]); + + Debug::log(LOG, "Set fullscreen to " + std::to_string(PWINDOW->getFullscreen()) + " for " + std::to_string(window)); +} + +void CWindowManager::handleClientMessage(xcb_client_message_event_t* E) { + + const auto PWINDOW = getWindowFromDrawable(E->window); + + if (!PWINDOW) + return; + + if (E->type == HYPRATOMS["_NET_WM_STATE"]) { + // The window wants to change its' state. + // For now we only support FULLSCREEN + + if (E->data.data32[1] == HYPRATOMS["_NET_WM_STATE_FULLSCREEN"]) { + // Toggle fullscreen + toggleWindowFullscrenn(PWINDOW->getDrawable()); + + Debug::log(LOG, "Message recieved to toggle fullscreen for " + std::to_string(PWINDOW->getDrawable())); + } + } else if (E->type == HYPRATOMS["_NET_ACTIVE_WINDOW"]) { + // Change the focused window + if (E->format != 32) + return; + + setFocusedWindow(PWINDOW->getDrawable()); + + Debug::log(LOG, "Message recieved to set active for " + std::to_string(PWINDOW->getDrawable())); + } } \ No newline at end of file diff --git a/src/windowManager.hpp b/src/windowManager.hpp index 67505e0..8a0751d 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -82,6 +82,7 @@ public: void moveActiveFocusTo(char); void moveActiveWindowToWorkspace(int); void warpCursorTo(Vector2D); + void toggleWindowFullscrenn(const int&); void changeWorkspaceByID(int); void setAllWorkspaceWindowsDirtyByID(int); @@ -124,6 +125,8 @@ public: void setAllWorkspaceWindowsAboveFullscreen(const int&); void setAllWorkspaceWindowsUnderFullscreen(const int&); + void handleClientMessage(xcb_client_message_event_t*); + private: // Internal WM functions that don't have to be exposed