Docks/Fullscreen autodetect + fixed a crash

This commit is contained in:
vaxerski 2021-11-28 11:52:40 +01:00
parent c080bf5174
commit 05fb292c92
7 changed files with 97 additions and 13 deletions

View file

@ -32,7 +32,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
- [ ] Fix windows minimizing themselves to tray not being able to come back without pkill - [ ] Fix windows minimizing themselves to tray not being able to come back without pkill
- [x] Moving windows between workspaces without floating - [x] Moving windows between workspaces without floating
- [x] EWMH ~ Basic, idk if i'll add more. - [x] EWMH ~ Basic, idk if i'll add more.
- [ ] Docks / Fullscreen Apps etc. auto-detection - [x] Docks / Fullscreen Apps etc. auto-detection
- [ ] Fix animation flicker (if possible) - [ ] Fix animation flicker (if possible)
- [ ] Config expansion (rules, default workspaces, etc.) - [ ] Config expansion (rules, default workspaces, etc.)

View file

@ -114,6 +114,37 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f)); window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f));
} }
//
// Dock Checks
//
const auto wm_type_cookie = xcb_get_property(g_pWindowManager->DisplayConnection, false, windowID, HYPRATOMS["_NET_WM_WINDOW_TYPE"], XCB_GET_PROPERTY_TYPE_ANY, 0, (4294967295U));
const auto wm_type_cookiereply = xcb_get_property_reply(g_pWindowManager->DisplayConnection, wm_type_cookie, NULL);
xcb_atom_t TYPEATOM = NULL;
if (wm_type_cookiereply == NULL || xcb_get_property_value_length(wm_type_cookiereply) < 1) {
Debug::log(LOG, "No preferred type found.");
} else {
const auto ATOMS = (xcb_atom_t*)xcb_get_property_value(wm_type_cookiereply);
if (!ATOMS) {
Debug::log(ERR, "Atoms not found in preferred type!");
} else {
if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"])) {
// set to floating and set the immovable and nointerventions flag
window.setImmovable(true);
window.setNoInterventions(true);
window.setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
Debug::log(LOG, "New dock created, setting default XYWH to: " + std::to_string(GEOMETRY->x) + ", " + std::to_string(GEOMETRY->y)
+ ", " + std::to_string(GEOMETRY->width) + ", " + std::to_string(GEOMETRY->height));
}
}
}
free(wm_type_cookiereply);
//
//
//
// Also sets the old one // Also sets the old one
g_pWindowManager->calculateNewWindowParams(&window); g_pWindowManager->calculateNewWindowParams(&window);
@ -254,13 +285,21 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
// We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it. // 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 // this func also sets some stuff
CWindow* pNewWindow = nullptr;
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) { if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
Debug::log(LOG, "Window SHOULD be floating on start."); Debug::log(LOG, "Window SHOULD be floating on start.");
remapFloatingWindow(E->window); pNewWindow = remapFloatingWindow(E->window);
} else { } else {
Debug::log(LOG, "Window should NOT be floating on start."); Debug::log(LOG, "Window should NOT be floating on start.");
remapWindow(E->window); pNewWindow = remapWindow(E->window);
} }
if (!pNewWindow)
return;
// Do post-creation checks.
g_pWindowManager->doPostCreationChecks(pNewWindow);
} }
void Events::eventButtonPress(xcb_generic_event_t* event) { void Events::eventButtonPress(xcb_generic_event_t* event) {

View file

@ -17,10 +17,12 @@ std::pair<std::string, std::string> getClassName(int64_t window) {
char* CLASSINSTANCE = strndup(NEWCLASS, PROPLEN); char* CLASSINSTANCE = strndup(NEWCLASS, PROPLEN);
char* CLASSNAME; char* CLASSNAME;
bool freeClassName = true;
if (CLASSNAMEINDEX < PROPLEN) { if (CLASSNAMEINDEX < PROPLEN) {
CLASSNAME = strndup(NEWCLASS + CLASSNAMEINDEX, PROPLEN - CLASSNAMEINDEX); CLASSNAME = strndup(NEWCLASS + CLASSNAMEINDEX, PROPLEN - CLASSNAMEINDEX);
} else { } else {
CLASSNAME = ""; CLASSNAME = "";
freeClassName = false;
} }
std::string CLASSINST(CLASSINSTANCE); std::string CLASSINST(CLASSINSTANCE);
@ -28,6 +30,7 @@ std::pair<std::string, std::string> getClassName(int64_t window) {
free(class_cookiereply); free(class_cookiereply);
free(CLASSINSTANCE); free(CLASSINSTANCE);
if (freeClassName)
free(CLASSNAME); free(CLASSNAME);
return std::make_pair<>(CLASSINST, CLASSNAM); return std::make_pair<>(CLASSINST, CLASSNAM);

View file

@ -1,7 +1,7 @@
#include "window.hpp" #include "window.hpp"
#include "windowManager.hpp" #include "windowManager.hpp"
CWindow::CWindow() { this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); } CWindow::CWindow() { this->setImmovable(false); this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); }
CWindow::~CWindow() { } CWindow::~CWindow() { }
void CWindow::generateNodeID() { void CWindow::generateNodeID() {

View file

@ -62,6 +62,10 @@ public:
// Monitors // Monitors
EXPOSED_MEMBER(Monitor, int, i); EXPOSED_MEMBER(Monitor, int, i);
// Docks etc
EXPOSED_MEMBER(Immovable, bool, b);
EXPOSED_MEMBER(NoInterventions, bool, b);
private: private:

View file

@ -304,8 +304,8 @@ void CWindowManager::refreshDirtyWindows() {
if (window.getDirty()) { if (window.getDirty()) {
window.setDirty(false); window.setDirty(false);
// Check if the window isn't a node // Check if the window isn't a node or has the noInterventions prop
if (window.getChildNodeAID() != 0) if (window.getChildNodeAID() != 0 || window.getNoInterventions())
continue; continue;
setEffectiveSizePosUsingConfig(&window); setEffectiveSizePosUsingConfig(&window);
@ -632,6 +632,7 @@ void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) {
if (!pWindow) if (!pWindow)
return; return;
if (!pWindow->getNoInterventions()) {
pWindow->setPosition(pWindow->getDefaultPosition()); pWindow->setPosition(pWindow->getDefaultPosition());
pWindow->setSize(pWindow->getDefaultSize()); pWindow->setSize(pWindow->getDefaultSize());
@ -640,6 +641,7 @@ void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) {
pWindow->setRealPosition(pWindow->getPosition()); pWindow->setRealPosition(pWindow->getPosition());
pWindow->setRealSize(pWindow->getSize()); pWindow->setRealSize(pWindow->getSize());
}
Values[0] = XCB_STACK_MODE_ABOVE; Values[0] = XCB_STACK_MODE_ABOVE;
xcb_configure_window(DisplayConnection, pWindow->getDrawable(), XCB_CONFIG_WINDOW_STACK_MODE, Values); xcb_configure_window(DisplayConnection, pWindow->getDrawable(), XCB_CONFIG_WINDOW_STACK_MODE, Values);
@ -1160,6 +1162,9 @@ bool CWindowManager::shouldBeFloatedOnInit(int64_t window) {
if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_NOTIFICATION"])) { if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_NOTIFICATION"])) {
free(wm_type_cookiereply); free(wm_type_cookiereply);
return true; return true;
} else if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"])) {
free(wm_type_cookiereply);
return true;
} }
} }
} }
@ -1183,3 +1188,35 @@ void CWindowManager::updateActiveWindowName() {
PLASTWINDOW->setName(WINNAME); PLASTWINDOW->setName(WINNAME);
} }
} }
void CWindowManager::doPostCreationChecks(CWindow* pWindow) {
//
Debug::log(LOG, "Post creation checks init");
const auto window = pWindow->getDrawable();
PROP(wm_type_cookie, HYPRATOMS["_NET_WM_WINDOW_TYPE"], UINT32_MAX);
xcb_atom_t TYPEATOM = NULL;
if (wm_type_cookiereply == NULL || xcb_get_property_value_length(wm_type_cookiereply) < 1) {
Debug::log(LOG, "No preferred type found.");
} else {
const auto ATOMS = (xcb_atom_t*)xcb_get_property_value(wm_type_cookiereply);
if (!ATOMS) {
Debug::log(ERR, "Atoms not found in preferred type!");
} else {
if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_STATE_FULLSCREEN"])) {
// set it fullscreen
pWindow->setFullscreen(true);
setFocusedWindow(window);
KeybindManager::toggleActiveWindowFullscreen("");
}
}
}
free(wm_type_cookiereply);
Debug::log(LOG, "Post creation checks ended");
//
}

View file

@ -91,6 +91,7 @@ public:
CWindow* findWindowAtCursor(); CWindow* findWindowAtCursor();
bool shouldBeFloatedOnInit(int64_t); bool shouldBeFloatedOnInit(int64_t);
void doPostCreationChecks(CWindow*);
void setupRandrMonitors(); void setupRandrMonitors();
void createAndOpenAllPipes(); void createAndOpenAllPipes();