x11/panelwindow: fix strut start/end, patch around awesome, resize all panels

This commit is contained in:
outfoxxed 2024-09-01 17:30:58 -07:00
parent 94e881e6b0
commit 95245cb6a5
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
2 changed files with 47 additions and 13 deletions

View file

@ -10,6 +10,7 @@
#include <qqmllist.h>
#include <qquickwindow.h>
#include <qscreen.h>
#include <qtimer.h>
#include <qtmetamacros.h>
#include <qtypes.h>
#include <xcb/xproto.h>
@ -17,6 +18,7 @@
#include "../core/generation.hpp"
#include "../core/panelinterface.hpp"
#include "../core/proxywindow.hpp"
#include "../core/qmlscreen.hpp"
#include "util.hpp"
class XPanelStack {
@ -56,6 +58,17 @@ public:
}
}
void updateLowerDimensions(XPanelWindow* exclude) {
auto& panels = this->mPanels[EngineGeneration::findObjectGeneration(exclude)];
// update all panels lower than the one we start from
auto found = false;
for (auto* panel: panels) {
if (panel == exclude) found = true;
else if (found) panel->updateDimensions(false);
}
}
private:
std::map<EngineGeneration*, QList<XPanelWindow*>> mPanels;
};
@ -151,9 +164,8 @@ qint32 XPanelWindow::exclusiveZone() const { return this->mExclusiveZone; }
void XPanelWindow::setExclusiveZone(qint32 exclusiveZone) {
if (this->mExclusiveZone == exclusiveZone) return;
this->mExclusiveZone = exclusiveZone;
const bool wasNormal = this->mExclusionMode == ExclusionMode::Normal;
this->setExclusionMode(ExclusionMode::Normal);
if (wasNormal) this->updateStrut();
this->updateStrut();
emit this->exclusiveZoneChanged();
}
@ -225,14 +237,16 @@ void XPanelWindow::connectScreen() {
this->mTrackedScreen,
&QScreen::geometryChanged,
this,
&XPanelWindow::updateDimensions
&XPanelWindow::updateDimensionsSlot
);
}
this->updateDimensions();
}
void XPanelWindow::updateDimensions() {
void XPanelWindow::updateDimensionsSlot() { this->updateDimensions(); }
void XPanelWindow::updateDimensions(bool propagate) {
if (this->window == nullptr || this->window->handle() == nullptr || this->mScreen == nullptr)
return;
@ -302,7 +316,15 @@ void XPanelWindow::updateDimensions() {
}
this->window->setGeometry(geometry);
this->updateStrut();
this->updateStrut(propagate);
// AwesomeWM incorrectly repositions the window without this.
// See https://github.com/polybar/polybar/blob/f0f9563ecf39e78ba04cc433cb7b38a83efde473/src/components/bar.cpp#L666
QTimer::singleShot(0, this, [this, geometry]() {
// forces second call not to be discarded as duplicate
this->window->setGeometry({0, 0, 0, 0});
this->window->setGeometry(geometry);
});
}
void XPanelWindow::updatePanelStack() {
@ -314,7 +336,10 @@ void XPanelWindow::updatePanelStack() {
}
void XPanelWindow::getExclusion(int& side, quint32& exclusiveZone) {
if (this->mExclusionMode == ExclusionMode::Ignore) return;
if (this->mExclusionMode == ExclusionMode::Ignore) {
exclusiveZone = 0;
return;
}
auto& anchors = this->mAnchors;
if (anchors.mLeft || anchors.mRight || anchors.mTop || anchors.mBottom) {
@ -344,7 +369,7 @@ void XPanelWindow::getExclusion(int& side, quint32& exclusiveZone) {
}
}
void XPanelWindow::updateStrut() {
void XPanelWindow::updateStrut(bool propagate) {
if (this->window == nullptr || this->window->handle() == nullptr) return;
auto* conn = x11Connection();
@ -359,13 +384,19 @@ void XPanelWindow::updateStrut() {
return;
}
// Due to missing headers it isn't even possible to do this right.
// We assume a single xinerama monitor with a matching size root.
auto screenGeometry = this->window->screen()->geometry();
auto horizontal = side == 0 || side == 1;
auto data = std::array<quint32, 12>();
data[side] = exclusiveZone;
// https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm45573693101552
// assuming "specified in root window coordinates" means relative to the window geometry
// in which case only the end position should be set, to the opposite extent.
data[side * 2 + 5] = side == 0 || side == 1 ? this->window->height() : this->window->width();
auto start = horizontal ? screenGeometry.top() + this->window->y()
: screenGeometry.left() + this->window->x();
data[4 + side * 2] = start;
data[5 + side * 2] = start + (horizontal ? this->window->height() : this->window->width());
xcb_change_property(
conn,
@ -388,6 +419,8 @@ void XPanelWindow::updateStrut() {
12,
data.data()
);
if (propagate) XPanelStack::instance()->updateLowerDimensions(this);
}
void XPanelWindow::updateAboveWindows() {

View file

@ -79,15 +79,16 @@ signals:
private slots:
void xInit();
void updateDimensions();
void updatePanelStack();
void updateDimensionsSlot();
private:
void connectScreen();
void getExclusion(int& side, quint32& exclusiveZone);
void updateStrut();
void updateStrut(bool propagate = true);
void updateAboveWindows();
void updateFocusable();
void updateDimensions(bool propagate = true);
QPointer<QScreen> mTrackedScreen = nullptr;
bool mAboveWindows = true;