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
- [x] Moving windows between workspaces without floating
- [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)
- [ ] 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));
}
//
// 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
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.
// this func also sets some stuff
CWindow* pNewWindow = nullptr;
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
Debug::log(LOG, "Window SHOULD be floating on start.");
remapFloatingWindow(E->window);
pNewWindow = remapFloatingWindow(E->window);
} else {
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) {

View File

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

View File

@ -1,7 +1,7 @@
#include "window.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() { }
void CWindow::generateNodeID() {

View File

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

View File

@ -304,8 +304,8 @@ void CWindowManager::refreshDirtyWindows() {
if (window.getDirty()) {
window.setDirty(false);
// Check if the window isn't a node
if (window.getChildNodeAID() != 0)
// Check if the window isn't a node or has the noInterventions prop
if (window.getChildNodeAID() != 0 || window.getNoInterventions())
continue;
setEffectiveSizePosUsingConfig(&window);
@ -632,14 +632,16 @@ void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) {
if (!pWindow)
return;
pWindow->setPosition(pWindow->getDefaultPosition());
pWindow->setSize(pWindow->getDefaultSize());
if (!pWindow->getNoInterventions()) {
pWindow->setPosition(pWindow->getDefaultPosition());
pWindow->setSize(pWindow->getDefaultSize());
pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(10,10));
pWindow->setEffectiveSize(pWindow->getDefaultSize());
pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(10, 10));
pWindow->setEffectiveSize(pWindow->getDefaultSize());
pWindow->setRealPosition(pWindow->getPosition());
pWindow->setRealSize(pWindow->getSize());
pWindow->setRealPosition(pWindow->getPosition());
pWindow->setRealSize(pWindow->getSize());
}
Values[0] = XCB_STACK_MODE_ABOVE;
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"])) {
free(wm_type_cookiereply);
return true;
} else if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"])) {
free(wm_type_cookiereply);
return true;
}
}
}
@ -1182,4 +1187,36 @@ void CWindowManager::updateActiveWindowName() {
Debug::log(LOG, "Update, window got name: " + 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();
bool shouldBeFloatedOnInit(int64_t);
void doPostCreationChecks(CWindow*);
void setupRandrMonitors();
void createAndOpenAllPipes();