mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-12-24 02:19:49 +01:00
added intelligent transients
This commit is contained in:
parent
786fa73c8c
commit
1421d42cae
8 changed files with 92 additions and 15 deletions
|
@ -11,6 +11,7 @@ max_fps=60 # max fps for updates of config & animations
|
|||
layout=0 # 0 - dwindle (default), 1 - master
|
||||
focus_when_hover=1 # 0 - do not switch the focus when hover (only for tiling)
|
||||
main_mod=SUPER # For moving, resizing
|
||||
intelligent_transients=1 # keeps transients always on top.
|
||||
|
||||
|
||||
# Execs
|
||||
|
|
|
@ -15,6 +15,7 @@ void ConfigManager::init() {
|
|||
configValues["gaps_out"].intValue = 20;
|
||||
configValues["rounding"].intValue = 5;
|
||||
configValues["main_mod"].strValue = "SUPER";
|
||||
configValues["intelligent_transients"].intValue = 1;
|
||||
|
||||
configValues["focus_when_hover"].intValue = 1;
|
||||
|
||||
|
|
|
@ -303,9 +303,6 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
|
|||
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);
|
||||
|
||||
// Make all floating windows above
|
||||
g_pWindowManager->setAllFloatingWindowsTop();
|
||||
|
||||
// Fix docks
|
||||
if (window.getDock())
|
||||
g_pWindowManager->recalcAllDocks();
|
||||
|
@ -432,9 +429,6 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
|
|||
// Focus
|
||||
g_pWindowManager->setFocusedWindow(windowID);
|
||||
|
||||
// Make all floating windows above
|
||||
g_pWindowManager->setAllFloatingWindowsTop();
|
||||
|
||||
return PWINDOWINARR;
|
||||
}
|
||||
|
||||
|
@ -481,6 +475,12 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
|||
// Do ICCCM
|
||||
g_pWindowManager->getICCCMWMProtocols(pNewWindow);
|
||||
|
||||
// Do transient checks
|
||||
EWMH::checkTransient(E->window);
|
||||
|
||||
// Make all floating windows above
|
||||
g_pWindowManager->setAllFloatingWindowsTop();
|
||||
|
||||
// Set not under
|
||||
pNewWindow->setUnderFullscreen(false);
|
||||
pNewWindow->setDirty(true);
|
||||
|
|
|
@ -128,4 +128,43 @@ void EWMH::updateWindow(xcb_window_t win) {
|
|||
long data[] = {XCB_ICCCM_WM_STATE_NORMAL, XCB_NONE};
|
||||
xcb_change_property(g_pWindowManager->DisplayConnection, XCB_PROP_MODE_REPLACE, win, HYPRATOMS["WM_STATE"], HYPRATOMS["WM_STATE"], 32, 2, data);
|
||||
}
|
||||
}
|
||||
|
||||
void EWMH::checkTransient(xcb_window_t window) {
|
||||
|
||||
const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(window);
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
// Check if it's a transient
|
||||
const auto TRANSIENTCOOKIE = xcb_get_property(g_pWindowManager->DisplayConnection, false, window, 68 /* TRANSIENT_FOR */, XCB_GET_PROPERTY_TYPE_ANY, 0, UINT32_MAX);
|
||||
const auto TRANSIENTREPLY = xcb_get_property_reply(g_pWindowManager->DisplayConnection, TRANSIENTCOOKIE, NULL);
|
||||
|
||||
if (!TRANSIENTREPLY || xcb_get_property_value_length(TRANSIENTREPLY) == 0) {
|
||||
Debug::log(WARN, "Transient check failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_window_t transientWindow;
|
||||
if (!xcb_icccm_get_wm_transient_for_from_reply(&transientWindow, TRANSIENTREPLY)) {
|
||||
Debug::log(WARN, "Transient reply failed.");
|
||||
free(TRANSIENTREPLY);
|
||||
return;
|
||||
}
|
||||
|
||||
// set the flags
|
||||
const auto PPARENTWINDOW = g_pWindowManager->getWindowFromDrawable(transientWindow);
|
||||
|
||||
if (!PPARENTWINDOW) {
|
||||
free(TRANSIENTREPLY);
|
||||
Debug::log(LOG, "Transient set for a nonexistent window, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
PPARENTWINDOW->addTransientChild(window);
|
||||
|
||||
Debug::log(LOG, "Added a transient child to " + std::to_string(transientWindow) + ".");
|
||||
|
||||
free(TRANSIENTREPLY);
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace EWMH {
|
|||
void setFrameExtents(xcb_window_t);
|
||||
void refreshAllExtents();
|
||||
void updateDesktops();
|
||||
void checkTransient(xcb_window_t);
|
||||
|
||||
namespace DesktopInfo {
|
||||
inline int lastid = 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "window.hpp"
|
||||
#include "windowManager.hpp"
|
||||
|
||||
CWindow::CWindow() { this->setLastUpdatePosition(Vector2D(0,0)); this->setLastUpdateSize(Vector2D(0,0)); this->setDock(false); this->setUnderFullscreen(false); this->setIsSleeping(true); this->setFirstAnimFrame(true); this->setIsAnimated(false); this->setDead(false); this->setMasterChildIndex(0); this->setMaster(false); this->setCanKill(false); this->setImmovable(false); this->setNoInterventions(false); this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); }
|
||||
CWindow::CWindow() { this->setTransient(false); this->setLastUpdatePosition(Vector2D(0,0)); this->setLastUpdateSize(Vector2D(0,0)); this->setDock(false); this->setUnderFullscreen(false); this->setIsSleeping(true); this->setFirstAnimFrame(true); this->setIsAnimated(false); this->setDead(false); this->setMasterChildIndex(0); this->setMaster(false); this->setCanKill(false); this->setImmovable(false); this->setNoInterventions(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() {
|
||||
|
@ -45,4 +45,30 @@ void CWindow::recalcSizePosRecursive() {
|
|||
g_pWindowManager->getWindowFromDrawable(m_iChildNodeBID)->recalcSizePosRecursive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::bringTopRecursiveTransients() {
|
||||
// check if its enabled
|
||||
if (ConfigManager::getInt("intelligent_transients") != 1)
|
||||
return;
|
||||
|
||||
// first top all the children if floating
|
||||
for (auto& c : m_vecChildren) {
|
||||
if (const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(c); PWINDOW) {
|
||||
if (PWINDOW->getIsFloating())
|
||||
g_pWindowManager->setAWindowTop(c);
|
||||
}
|
||||
}
|
||||
|
||||
// THEN top their children
|
||||
for (auto& c : m_vecChildren) {
|
||||
if (const auto PCHILD = g_pWindowManager->getWindowFromDrawable(c); PCHILD) {
|
||||
// recurse
|
||||
PCHILD->bringTopRecursiveTransients();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::addTransientChild(xcb_window_t w) {
|
||||
m_vecChildren.push_back(w);
|
||||
}
|
|
@ -39,7 +39,9 @@ public:
|
|||
// Tells the window manager to reload the window's params
|
||||
EXPOSED_MEMBER(Dirty, bool, b);
|
||||
|
||||
void bringTopRecursiveTransients();
|
||||
void setDirtyRecursive(bool);
|
||||
void addTransientChild(xcb_drawable_t);
|
||||
// ONLY for dwindle layout!
|
||||
void recalcSizePosRecursive();
|
||||
|
||||
|
@ -95,7 +97,9 @@ public:
|
|||
EXPOSED_MEMBER(Dock, bool, b);
|
||||
EXPOSED_MEMBER(DockAlign, EDockAlign, e);
|
||||
|
||||
// todo: Transients
|
||||
// Transient
|
||||
EXPOSED_MEMBER(Children, std::vector<int64_t>, vec);
|
||||
EXPOSED_MEMBER(Transient, bool, b);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -460,11 +460,6 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) {
|
|||
|
||||
float values[1];
|
||||
if (const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(window); PWINDOW) {
|
||||
if (PWINDOW->getIsFloating()) {
|
||||
values[0] = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(g_pWindowManager->DisplayConnection, window, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
}
|
||||
|
||||
// Apply rounded corners, does all the checks inside.
|
||||
// The border changed so let's not make it rectangular maybe
|
||||
applyShapeToWindow(PWINDOW);
|
||||
|
@ -472,9 +467,15 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) {
|
|||
|
||||
LastWindow = window;
|
||||
|
||||
if (g_pWindowManager->getWindowFromDrawable(window))
|
||||
const auto PNEWFOCUS = g_pWindowManager->getWindowFromDrawable(window);
|
||||
|
||||
if (PNEWFOCUS) {
|
||||
applyShapeToWindow(g_pWindowManager->getWindowFromDrawable(window));
|
||||
|
||||
// Transients
|
||||
PNEWFOCUS->bringTopRecursiveTransients();
|
||||
}
|
||||
|
||||
// set focus in X11
|
||||
xcb_set_input_focus(DisplayConnection, XCB_INPUT_FOCUS_POINTER_ROOT, window, XCB_CURRENT_TIME);
|
||||
|
||||
|
@ -1557,9 +1558,13 @@ void CWindowManager::updateBarInfo() {
|
|||
|
||||
void CWindowManager::setAllFloatingWindowsTop() {
|
||||
for (auto& window : windows) {
|
||||
if (window.getIsFloating()) {
|
||||
if (window.getIsFloating() && !window.getTransient()) {
|
||||
Values[0] = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(g_pWindowManager->DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_STACK_MODE, Values);
|
||||
|
||||
window.bringTopRecursiveTransients();
|
||||
} else if (window.getChildren().size() > 0) {
|
||||
window.bringTopRecursiveTransients();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue