forked from quickshell/quickshell
		
	x11/panelwindow: fix strut start/end, patch around awesome, resize all panels
This commit is contained in:
		
							parent
							
								
									94e881e6b0
								
							
						
					
					
						commit
						95245cb6a5
					
				
					 2 changed files with 47 additions and 13 deletions
				
			
		| 
						 | 
					@ -10,6 +10,7 @@
 | 
				
			||||||
#include <qqmllist.h>
 | 
					#include <qqmllist.h>
 | 
				
			||||||
#include <qquickwindow.h>
 | 
					#include <qquickwindow.h>
 | 
				
			||||||
#include <qscreen.h>
 | 
					#include <qscreen.h>
 | 
				
			||||||
 | 
					#include <qtimer.h>
 | 
				
			||||||
#include <qtmetamacros.h>
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
#include <qtypes.h>
 | 
					#include <qtypes.h>
 | 
				
			||||||
#include <xcb/xproto.h>
 | 
					#include <xcb/xproto.h>
 | 
				
			||||||
| 
						 | 
					@ -17,6 +18,7 @@
 | 
				
			||||||
#include "../core/generation.hpp"
 | 
					#include "../core/generation.hpp"
 | 
				
			||||||
#include "../core/panelinterface.hpp"
 | 
					#include "../core/panelinterface.hpp"
 | 
				
			||||||
#include "../core/proxywindow.hpp"
 | 
					#include "../core/proxywindow.hpp"
 | 
				
			||||||
 | 
					#include "../core/qmlscreen.hpp"
 | 
				
			||||||
#include "util.hpp"
 | 
					#include "util.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class XPanelStack {
 | 
					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:
 | 
					private:
 | 
				
			||||||
	std::map<EngineGeneration*, QList<XPanelWindow*>> mPanels;
 | 
						std::map<EngineGeneration*, QList<XPanelWindow*>> mPanels;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -151,9 +164,8 @@ qint32 XPanelWindow::exclusiveZone() const { return this->mExclusiveZone; }
 | 
				
			||||||
void XPanelWindow::setExclusiveZone(qint32 exclusiveZone) {
 | 
					void XPanelWindow::setExclusiveZone(qint32 exclusiveZone) {
 | 
				
			||||||
	if (this->mExclusiveZone == exclusiveZone) return;
 | 
						if (this->mExclusiveZone == exclusiveZone) return;
 | 
				
			||||||
	this->mExclusiveZone = exclusiveZone;
 | 
						this->mExclusiveZone = exclusiveZone;
 | 
				
			||||||
	const bool wasNormal = this->mExclusionMode == ExclusionMode::Normal;
 | 
					 | 
				
			||||||
	this->setExclusionMode(ExclusionMode::Normal);
 | 
						this->setExclusionMode(ExclusionMode::Normal);
 | 
				
			||||||
	if (wasNormal) this->updateStrut();
 | 
						this->updateStrut();
 | 
				
			||||||
	emit this->exclusiveZoneChanged();
 | 
						emit this->exclusiveZoneChanged();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,14 +237,16 @@ void XPanelWindow::connectScreen() {
 | 
				
			||||||
		    this->mTrackedScreen,
 | 
							    this->mTrackedScreen,
 | 
				
			||||||
		    &QScreen::geometryChanged,
 | 
							    &QScreen::geometryChanged,
 | 
				
			||||||
		    this,
 | 
							    this,
 | 
				
			||||||
		    &XPanelWindow::updateDimensions
 | 
							    &XPanelWindow::updateDimensionsSlot
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->updateDimensions();
 | 
						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)
 | 
						if (this->window == nullptr || this->window->handle() == nullptr || this->mScreen == nullptr)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -302,7 +316,15 @@ void XPanelWindow::updateDimensions() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->window->setGeometry(geometry);
 | 
						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() {
 | 
					void XPanelWindow::updatePanelStack() {
 | 
				
			||||||
| 
						 | 
					@ -314,7 +336,10 @@ void XPanelWindow::updatePanelStack() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void XPanelWindow::getExclusion(int& side, quint32& exclusiveZone) {
 | 
					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;
 | 
						auto& anchors = this->mAnchors;
 | 
				
			||||||
	if (anchors.mLeft || anchors.mRight || anchors.mTop || anchors.mBottom) {
 | 
						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;
 | 
						if (this->window == nullptr || this->window->handle() == nullptr) return;
 | 
				
			||||||
	auto* conn = x11Connection();
 | 
						auto* conn = x11Connection();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,13 +384,19 @@ void XPanelWindow::updateStrut() {
 | 
				
			||||||
		return;
 | 
							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>();
 | 
						auto data = std::array<quint32, 12>();
 | 
				
			||||||
	data[side] = exclusiveZone;
 | 
						data[side] = exclusiveZone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm45573693101552
 | 
						auto start = horizontal ? screenGeometry.top() + this->window->y()
 | 
				
			||||||
	// assuming "specified in root window coordinates" means relative to the window geometry
 | 
						                        : screenGeometry.left() + this->window->x();
 | 
				
			||||||
	// 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();
 | 
						data[4 + side * 2] = start;
 | 
				
			||||||
 | 
						data[5 + side * 2] = start + (horizontal ? this->window->height() : this->window->width());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xcb_change_property(
 | 
						xcb_change_property(
 | 
				
			||||||
	    conn,
 | 
						    conn,
 | 
				
			||||||
| 
						 | 
					@ -388,6 +419,8 @@ void XPanelWindow::updateStrut() {
 | 
				
			||||||
	    12,
 | 
						    12,
 | 
				
			||||||
	    data.data()
 | 
						    data.data()
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (propagate) XPanelStack::instance()->updateLowerDimensions(this);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void XPanelWindow::updateAboveWindows() {
 | 
					void XPanelWindow::updateAboveWindows() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,15 +79,16 @@ signals:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
	void xInit();
 | 
						void xInit();
 | 
				
			||||||
	void updateDimensions();
 | 
					 | 
				
			||||||
	void updatePanelStack();
 | 
						void updatePanelStack();
 | 
				
			||||||
 | 
						void updateDimensionsSlot();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void connectScreen();
 | 
						void connectScreen();
 | 
				
			||||||
	void getExclusion(int& side, quint32& exclusiveZone);
 | 
						void getExclusion(int& side, quint32& exclusiveZone);
 | 
				
			||||||
	void updateStrut();
 | 
						void updateStrut(bool propagate = true);
 | 
				
			||||||
	void updateAboveWindows();
 | 
						void updateAboveWindows();
 | 
				
			||||||
	void updateFocusable();
 | 
						void updateFocusable();
 | 
				
			||||||
 | 
						void updateDimensions(bool propagate = true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QPointer<QScreen> mTrackedScreen = nullptr;
 | 
						QPointer<QScreen> mTrackedScreen = nullptr;
 | 
				
			||||||
	bool mAboveWindows = true;
 | 
						bool mAboveWindows = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue