forked from quickshell/quickshell
		
	popups: add popup windows
This commit is contained in:
		
							parent
							
								
									8cf0659444
								
							
						
					
					
						commit
						b675b3676c
					
				
					 20 changed files with 586 additions and 71 deletions
				
			
		| 
						 | 
					@ -46,6 +46,7 @@ set(QT_FPDEPS Gui Qml Quick QuickControls2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (BUILD_TESTING)
 | 
					if (BUILD_TESTING)
 | 
				
			||||||
	enable_testing()
 | 
						enable_testing()
 | 
				
			||||||
 | 
						add_definitions(-DQS_TEST)
 | 
				
			||||||
	list(APPEND QT_FPDEPS Test)
 | 
						list(APPEND QT_FPDEPS Test)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								docs
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								docs
									
										
									
									
									
								
							| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
Subproject commit b218d3ec30f8ff2c51d4caf17509b9d21cf0c088
 | 
					Subproject commit 2d0b15bbd52ea61bd79880b89fae0a589010d1f3
 | 
				
			||||||
							
								
								
									
										2
									
								
								examples
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								examples
									
										
									
									
									
								
							| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
Subproject commit f76b43db25fb06a016ccf64ec2b28079c325c346
 | 
					Subproject commit 9437c6a840faf7180ab7dfb5425a402ca8a4b58c
 | 
				
			||||||
| 
						 | 
					@ -15,9 +15,14 @@ qt_add_executable(quickshell
 | 
				
			||||||
	windowinterface.cpp
 | 
						windowinterface.cpp
 | 
				
			||||||
	floatingwindow.cpp
 | 
						floatingwindow.cpp
 | 
				
			||||||
	panelinterface.cpp
 | 
						panelinterface.cpp
 | 
				
			||||||
 | 
						popupwindow.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
 | 
					set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
 | 
				
			||||||
qt_add_qml_module(quickshell URI Quickshell VERSION 0.1)
 | 
					qt_add_qml_module(quickshell URI Quickshell VERSION 0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(quickshell PRIVATE ${QT_DEPS})
 | 
					target_link_libraries(quickshell PRIVATE ${QT_DEPS})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (BUILD_TESTING)
 | 
				
			||||||
 | 
						add_subdirectory(test)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,3 +9,6 @@
 | 
				
			||||||
// make the type visible in the docs even if not a QML_ELEMENT
 | 
					// make the type visible in the docs even if not a QML_ELEMENT
 | 
				
			||||||
#define QSDOC_ELEMENT
 | 
					#define QSDOC_ELEMENT
 | 
				
			||||||
#define QSDOC_NAMED_ELEMENT(name)
 | 
					#define QSDOC_NAMED_ELEMENT(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// overridden properties
 | 
				
			||||||
 | 
					#define QSDOC_PROPERTY_OVERRIDE(...)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,7 @@ void FloatingWindowInterface::onReload(QObject* oldInstance) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QQmlListProperty<QObject> FloatingWindowInterface::data() { return this->window->data(); }
 | 
					QQmlListProperty<QObject> FloatingWindowInterface::data() { return this->window->data(); }
 | 
				
			||||||
 | 
					ProxyWindowBase* FloatingWindowInterface::proxyWindow() const { return this->window; }
 | 
				
			||||||
QQuickItem* FloatingWindowInterface::contentItem() const { return this->window->contentItem(); }
 | 
					QQuickItem* FloatingWindowInterface::contentItem() const { return this->window->contentItem(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NOLINTBEGIN
 | 
					// NOLINTBEGIN
 | 
				
			||||||
| 
						 | 
					@ -57,6 +58,4 @@ proxyPair(QColor, color, setColor);
 | 
				
			||||||
proxyPair(PendingRegion*, mask, setMask);
 | 
					proxyPair(PendingRegion*, mask, setMask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef proxyPair
 | 
					#undef proxyPair
 | 
				
			||||||
#undef proxySet
 | 
					 | 
				
			||||||
#undef proxyGet
 | 
					 | 
				
			||||||
// NOLINTEND
 | 
					// NOLINTEND
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onReload(QObject* oldInstance) override;
 | 
						void onReload(QObject* oldInstance) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] ProxyWindowBase* proxyWindow() const override;
 | 
				
			||||||
	[[nodiscard]] QQuickItem* contentItem() const override;
 | 
						[[nodiscard]] QQuickItem* contentItem() const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// NOLINTBEGIN
 | 
						// NOLINTBEGIN
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,5 +12,6 @@ headers = [
 | 
				
			||||||
	"windowinterface.hpp",
 | 
						"windowinterface.hpp",
 | 
				
			||||||
	"panelinterface.hpp",
 | 
						"panelinterface.hpp",
 | 
				
			||||||
	"floatingwindow.hpp",
 | 
						"floatingwindow.hpp",
 | 
				
			||||||
 | 
						"popupwindow.hpp",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
-----
 | 
					-----
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										151
									
								
								src/core/popupwindow.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/core/popupwindow.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,151 @@
 | 
				
			||||||
 | 
					#include "popupwindow.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qlogging.h>
 | 
				
			||||||
 | 
					#include <qnamespace.h>
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qquickwindow.h>
 | 
				
			||||||
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
 | 
					#include <qtypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "proxywindow.hpp"
 | 
				
			||||||
 | 
					#include "qmlscreen.hpp"
 | 
				
			||||||
 | 
					#include "windowinterface.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ProxyPopupWindow::ProxyPopupWindow(QObject* parent): ProxyWindowBase(parent) {
 | 
				
			||||||
 | 
						this->mVisible = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::setupWindow() {
 | 
				
			||||||
 | 
						this->ProxyWindowBase::setupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->window->setFlag(Qt::ToolTip);
 | 
				
			||||||
 | 
						this->updateTransientParent();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qint32 ProxyPopupWindow::x() const {
 | 
				
			||||||
 | 
						return this->ProxyWindowBase::x() + 1; // QTBUG-121550
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::setParentWindow(QObject* parent) {
 | 
				
			||||||
 | 
						if (parent == this->mParentWindow) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (this->mParentWindow != nullptr) {
 | 
				
			||||||
 | 
							QObject::disconnect(this->mParentWindow, nullptr, this, nullptr);
 | 
				
			||||||
 | 
							QObject::disconnect(this->mParentProxyWindow, nullptr, this, nullptr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (parent == nullptr) {
 | 
				
			||||||
 | 
							this->mParentWindow = nullptr;
 | 
				
			||||||
 | 
							this->mParentProxyWindow = nullptr;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (auto* proxy = qobject_cast<ProxyWindowBase*>(parent)) {
 | 
				
			||||||
 | 
								this->mParentProxyWindow = proxy;
 | 
				
			||||||
 | 
							} else if (auto* interface = qobject_cast<WindowInterface*>(parent)) {
 | 
				
			||||||
 | 
								this->mParentProxyWindow = interface->proxyWindow();
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								qWarning() << "Tried to set popup parent window to something that is not a quickshell window:"
 | 
				
			||||||
 | 
								           << parent;
 | 
				
			||||||
 | 
								this->mParentWindow = nullptr;
 | 
				
			||||||
 | 
								this->mParentProxyWindow = nullptr;
 | 
				
			||||||
 | 
								this->updateTransientParent();
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->mParentWindow = parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// clang-format off
 | 
				
			||||||
 | 
							QObject::connect(this->mParentWindow, &QObject::destroyed, this, &ProxyPopupWindow::onParentDestroyed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							QObject::connect(this->mParentProxyWindow, &ProxyWindowBase::xChanged, this, &ProxyPopupWindow::updateX);
 | 
				
			||||||
 | 
							QObject::connect(this->mParentProxyWindow, &ProxyWindowBase::yChanged, this, &ProxyPopupWindow::updateY);
 | 
				
			||||||
 | 
							QObject::connect(this->mParentProxyWindow, &ProxyWindowBase::windowConnected, this, &ProxyPopupWindow::onParentConnected);
 | 
				
			||||||
 | 
							// clang-format on
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->updateTransientParent();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QObject* ProxyPopupWindow::parentWindow() const { return this->mParentWindow; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::updateTransientParent() {
 | 
				
			||||||
 | 
						if (this->window == nullptr) return;
 | 
				
			||||||
 | 
						this->updateX();
 | 
				
			||||||
 | 
						this->updateY();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->window->setTransientParent(
 | 
				
			||||||
 | 
						    this->mParentProxyWindow == nullptr ? nullptr : this->mParentProxyWindow->backingWindow()
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->updateVisible();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::onParentConnected() { this->updateTransientParent(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::onParentDestroyed() {
 | 
				
			||||||
 | 
						this->mParentWindow = nullptr;
 | 
				
			||||||
 | 
						this->mParentProxyWindow = nullptr;
 | 
				
			||||||
 | 
						this->updateVisible();
 | 
				
			||||||
 | 
						emit this->parentWindowChanged();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::setScreen(QuickshellScreenInfo* /*unused*/) {
 | 
				
			||||||
 | 
						qWarning() << "Cannot set screen of popup window, as that is controlled by the parent window";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::setVisible(bool visible) {
 | 
				
			||||||
 | 
						if (visible == this->wantsVisible) return;
 | 
				
			||||||
 | 
						this->wantsVisible = visible;
 | 
				
			||||||
 | 
						this->updateVisible();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::updateVisible() {
 | 
				
			||||||
 | 
						auto target = this->wantsVisible && this->mParentWindow != nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (target && this->window != nullptr && !this->window->isVisible()) {
 | 
				
			||||||
 | 
							this->updateX(); // QTBUG-121550
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->ProxyWindowBase::setVisible(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::setRelativeX(qint32 x) {
 | 
				
			||||||
 | 
						if (x == this->mRelativeX) return;
 | 
				
			||||||
 | 
						this->mRelativeX = x;
 | 
				
			||||||
 | 
						this->updateX();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qint32 ProxyPopupWindow::relativeX() const { return this->mRelativeX; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::setRelativeY(qint32 y) {
 | 
				
			||||||
 | 
						if (y == this->mRelativeY) return;
 | 
				
			||||||
 | 
						this->mRelativeY = y;
 | 
				
			||||||
 | 
						this->updateY();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qint32 ProxyPopupWindow::relativeY() const { return this->mRelativeY; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::updateX() {
 | 
				
			||||||
 | 
						if (this->mParentWindow == nullptr || this->window == nullptr) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// use the backing window's x to account for popups in popups with overridden x positions
 | 
				
			||||||
 | 
						auto target = this->mParentProxyWindow->backingWindow()->x() + this->relativeX();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto reshow = this->window->isVisible() && (this->window->x() != target && this->x() != target);
 | 
				
			||||||
 | 
						if (reshow) this->window->setVisible(false);
 | 
				
			||||||
 | 
						this->window->setX(target - 1); // -1 due to QTBUG-121550
 | 
				
			||||||
 | 
						if (reshow && this->wantsVisible) this->window->setVisible(true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyPopupWindow::updateY() {
 | 
				
			||||||
 | 
						if (this->mParentWindow == nullptr || this->window == nullptr) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto target = this->mParentProxyWindow->y() + this->relativeY();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto reshow = this->window->isVisible() && this->window->y() != target;
 | 
				
			||||||
 | 
						if (reshow) {
 | 
				
			||||||
 | 
							this->window->setVisible(false);
 | 
				
			||||||
 | 
							this->updateX(); // QTBUG-121550
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this->window->setY(target);
 | 
				
			||||||
 | 
						if (reshow && this->wantsVisible) this->window->setVisible(true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										102
									
								
								src/core/popupwindow.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/core/popupwindow.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,102 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qqmlintegration.h>
 | 
				
			||||||
 | 
					#include <qquickwindow.h>
 | 
				
			||||||
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
 | 
					#include <qtypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "doc.hpp"
 | 
				
			||||||
 | 
					#include "proxywindow.hpp"
 | 
				
			||||||
 | 
					#include "qmlscreen.hpp"
 | 
				
			||||||
 | 
					#include "windowinterface.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///! Popup window.
 | 
				
			||||||
 | 
					/// Popup window that can display in a position relative to a floating
 | 
				
			||||||
 | 
					/// or panel window.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// #### Example
 | 
				
			||||||
 | 
					/// The following snippet creates a panel with a popup centered over it.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ```qml
 | 
				
			||||||
 | 
					/// PanelWindow {
 | 
				
			||||||
 | 
					///   id: toplevel
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					///   anchors {
 | 
				
			||||||
 | 
					///     bottom: true
 | 
				
			||||||
 | 
					///     left: true
 | 
				
			||||||
 | 
					///     right: true
 | 
				
			||||||
 | 
					///   }
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					///   PopupWindow {
 | 
				
			||||||
 | 
					///     parentWindow: toplevel
 | 
				
			||||||
 | 
					///     relativeX: parentWindow.width / 2 - width / 2
 | 
				
			||||||
 | 
					///     relativeY: parentWindow.height
 | 
				
			||||||
 | 
					///     width: 500
 | 
				
			||||||
 | 
					///     height: 500
 | 
				
			||||||
 | 
					///     visible: true
 | 
				
			||||||
 | 
					///   }
 | 
				
			||||||
 | 
					/// }
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					class ProxyPopupWindow: public ProxyWindowBase {
 | 
				
			||||||
 | 
						QSDOC_BASECLASS(WindowInterface);
 | 
				
			||||||
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
						// clang-format off
 | 
				
			||||||
 | 
						/// The parent window of this popup.
 | 
				
			||||||
 | 
						///
 | 
				
			||||||
 | 
						/// Changing this property reparents the popup.
 | 
				
			||||||
 | 
						Q_PROPERTY(QObject* parentWindow READ parentWindow WRITE setParentWindow NOTIFY parentWindowChanged);
 | 
				
			||||||
 | 
						/// The X position of the popup relative to the parent window.
 | 
				
			||||||
 | 
						Q_PROPERTY(qint32 relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged);
 | 
				
			||||||
 | 
						/// The Y position of the popup relative to the parent window.
 | 
				
			||||||
 | 
						Q_PROPERTY(qint32 relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged);
 | 
				
			||||||
 | 
						/// If the window is shown or hidden. Defaults to false.
 | 
				
			||||||
 | 
						QSDOC_PROPERTY_OVERRIDE(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged);
 | 
				
			||||||
 | 
						/// The screen that the window currently occupies.
 | 
				
			||||||
 | 
						///
 | 
				
			||||||
 | 
						/// This may be modified to move the window to the given screen.
 | 
				
			||||||
 | 
						QSDOC_PROPERTY_OVERRIDE(QuickshellScreenInfo* screen READ screen NOTIFY screenChanged);
 | 
				
			||||||
 | 
						// clang-format on
 | 
				
			||||||
 | 
						QML_NAMED_ELEMENT(PopupWindow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						explicit ProxyPopupWindow(QObject* parent = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void setupWindow() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void setScreen(QuickshellScreenInfo* screen) override;
 | 
				
			||||||
 | 
						void setVisible(bool visible) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] qint32 x() const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] QObject* parentWindow() const;
 | 
				
			||||||
 | 
						void setParentWindow(QObject* parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] qint32 relativeX() const;
 | 
				
			||||||
 | 
						void setRelativeX(qint32 x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] qint32 relativeY() const;
 | 
				
			||||||
 | 
						void setRelativeY(qint32 y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signals:
 | 
				
			||||||
 | 
						void parentWindowChanged();
 | 
				
			||||||
 | 
						void relativeXChanged();
 | 
				
			||||||
 | 
						void relativeYChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private slots:
 | 
				
			||||||
 | 
						void onParentConnected();
 | 
				
			||||||
 | 
						void onParentDestroyed();
 | 
				
			||||||
 | 
						void updateX();
 | 
				
			||||||
 | 
						void updateY();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						QQuickWindow* parentBackingWindow();
 | 
				
			||||||
 | 
						void updateTransientParent();
 | 
				
			||||||
 | 
						void updateVisible();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QObject* mParentWindow = nullptr;
 | 
				
			||||||
 | 
						ProxyWindowBase* mParentProxyWindow = nullptr;
 | 
				
			||||||
 | 
						qint32 mRelativeX = 0;
 | 
				
			||||||
 | 
						qint32 mRelativeY = 0;
 | 
				
			||||||
 | 
						bool wantsVisible = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,8 @@ QQuickWindow* ProxyWindowBase::createWindow(QObject* oldInstance) {
 | 
				
			||||||
void ProxyWindowBase::setupWindow() {
 | 
					void ProxyWindowBase::setupWindow() {
 | 
				
			||||||
	// clang-format off
 | 
						// clang-format off
 | 
				
			||||||
	QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged);
 | 
						QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged);
 | 
				
			||||||
 | 
						QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged);
 | 
				
			||||||
 | 
						QObject::connect(this->window, &QWindow::yChanged, this, &ProxyWindowBase::yChanged);
 | 
				
			||||||
	QObject::connect(this->window, &QWindow::widthChanged, this, &ProxyWindowBase::widthChanged);
 | 
						QObject::connect(this->window, &QWindow::widthChanged, this, &ProxyWindowBase::widthChanged);
 | 
				
			||||||
	QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyWindowBase::heightChanged);
 | 
						QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyWindowBase::heightChanged);
 | 
				
			||||||
	QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyWindowBase::screenChanged);
 | 
						QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyWindowBase::screenChanged);
 | 
				
			||||||
| 
						 | 
					@ -76,6 +78,10 @@ void ProxyWindowBase::setupWindow() {
 | 
				
			||||||
	this->setHeight(this->mHeight);
 | 
						this->setHeight(this->mHeight);
 | 
				
			||||||
	this->setColor(this->mColor);
 | 
						this->setColor(this->mColor);
 | 
				
			||||||
	this->updateMask();
 | 
						this->updateMask();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// notify initial x and y positions
 | 
				
			||||||
 | 
						emit this->xChanged();
 | 
				
			||||||
 | 
						emit this->yChanged();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QQuickWindow* ProxyWindowBase::disownWindow() {
 | 
					QQuickWindow* ProxyWindowBase::disownWindow() {
 | 
				
			||||||
| 
						 | 
					@ -103,6 +109,16 @@ void ProxyWindowBase::setVisible(bool visible) {
 | 
				
			||||||
	} else this->window->setVisible(visible);
 | 
						} else this->window->setVisible(visible);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qint32 ProxyWindowBase::x() const {
 | 
				
			||||||
 | 
						if (this->window == nullptr) return 0;
 | 
				
			||||||
 | 
						else return this->window->x();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qint32 ProxyWindowBase::y() const {
 | 
				
			||||||
 | 
						if (this->window == nullptr) return 0;
 | 
				
			||||||
 | 
						else return this->window->y();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qint32 ProxyWindowBase::width() const {
 | 
					qint32 ProxyWindowBase::width() const {
 | 
				
			||||||
	if (this->window == nullptr) return this->mWidth;
 | 
						if (this->window == nullptr) return this->mWidth;
 | 
				
			||||||
	else return this->window->width();
 | 
						else return this->window->width();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ class ProxyWindowBase: public Reloadable {
 | 
				
			||||||
	/// >
 | 
						/// >
 | 
				
			||||||
	/// > Use **only** if you know what you are doing.
 | 
						/// > Use **only** if you know what you are doing.
 | 
				
			||||||
	Q_PROPERTY(QQuickWindow* _backingWindow READ backingWindow);
 | 
						Q_PROPERTY(QQuickWindow* _backingWindow READ backingWindow);
 | 
				
			||||||
	Q_PROPERTY(QQuickItem* contentItem READ contentItem);
 | 
						Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT);
 | 
				
			||||||
	Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged);
 | 
						Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged);
 | 
				
			||||||
	Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged);
 | 
						Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged);
 | 
				
			||||||
	Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged);
 | 
						Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged);
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,9 @@ public:
 | 
				
			||||||
	[[nodiscard]] virtual bool isVisible() const;
 | 
						[[nodiscard]] virtual bool isVisible() const;
 | 
				
			||||||
	virtual void setVisible(bool visible);
 | 
						virtual void setVisible(bool visible);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] virtual qint32 x() const;
 | 
				
			||||||
 | 
						[[nodiscard]] virtual qint32 y() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] virtual qint32 width() const;
 | 
						[[nodiscard]] virtual qint32 width() const;
 | 
				
			||||||
	virtual void setWidth(qint32 width);
 | 
						virtual void setWidth(qint32 width);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,6 +90,8 @@ public:
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void windowConnected();
 | 
						void windowConnected();
 | 
				
			||||||
	void visibleChanged();
 | 
						void visibleChanged();
 | 
				
			||||||
 | 
						void xChanged();
 | 
				
			||||||
 | 
						void yChanged();
 | 
				
			||||||
	void widthChanged();
 | 
						void widthChanged();
 | 
				
			||||||
	void heightChanged();
 | 
						void heightChanged();
 | 
				
			||||||
	void screenChanged();
 | 
						void screenChanged();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/core/test/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/core/test/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					function (qs_test name)
 | 
				
			||||||
 | 
						add_executable(${name} ${ARGN})
 | 
				
			||||||
 | 
						target_link_libraries(${name} PRIVATE ${QT_DEPS} Qt6::Test)
 | 
				
			||||||
 | 
						add_test(NAME ${name} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND $<TARGET_FILE:${name}>)
 | 
				
			||||||
 | 
					endfunction()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qs_test(popupwindow
 | 
				
			||||||
 | 
						popupwindow.cpp
 | 
				
			||||||
 | 
						../popupwindow.cpp
 | 
				
			||||||
 | 
						../proxywindow.cpp
 | 
				
			||||||
 | 
						../qmlscreen.cpp
 | 
				
			||||||
 | 
						../region.cpp
 | 
				
			||||||
 | 
						../reload.cpp
 | 
				
			||||||
 | 
						../windowinterface.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										182
									
								
								src/core/test/popupwindow.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								src/core/test/popupwindow.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,182 @@
 | 
				
			||||||
 | 
					#include "popupwindow.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qlogging.h>
 | 
				
			||||||
 | 
					#include <qquickwindow.h>
 | 
				
			||||||
 | 
					#include <qsignalspy.h>
 | 
				
			||||||
 | 
					#include <qtest.h>
 | 
				
			||||||
 | 
					#include <qtestcase.h>
 | 
				
			||||||
 | 
					#include <qwindow.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../popupwindow.hpp"
 | 
				
			||||||
 | 
					#include "../proxywindow.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::initiallyVisible() { // NOLINT
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(popup.isVisible());
 | 
				
			||||||
 | 
						QVERIFY(popup.backingWindow()->isVisible());
 | 
				
			||||||
 | 
						QCOMPARE(popup.backingWindow()->transientParent(), parent.backingWindow());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::reloadReparent() { // NOLINT
 | 
				
			||||||
 | 
						// first generation
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto* win2 = new QQuickWindow();
 | 
				
			||||||
 | 
						win2->setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.setVisible(true);
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// second generation
 | 
				
			||||||
 | 
						auto newParent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto newPopup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						newPopup.setParentWindow(&newParent);
 | 
				
			||||||
 | 
						newPopup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto* oldWindow = popup.backingWindow();
 | 
				
			||||||
 | 
						auto* oldTransientParent = oldWindow->transientParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto spy = QSignalSpy(oldWindow, &QWindow::visibleChanged);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qDebug() << "reload";
 | 
				
			||||||
 | 
						newParent.onReload(&parent);
 | 
				
			||||||
 | 
						newPopup.onReload(&popup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(newPopup.isVisible());
 | 
				
			||||||
 | 
						QVERIFY(newPopup.backingWindow()->isVisible());
 | 
				
			||||||
 | 
						QCOMPARE(newPopup.backingWindow()->transientParent(), oldTransientParent);
 | 
				
			||||||
 | 
						QCOMPARE(newPopup.backingWindow()->transientParent(), newParent.backingWindow());
 | 
				
			||||||
 | 
						QCOMPARE(spy.length(), 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::reloadUnparent() { // NOLINT
 | 
				
			||||||
 | 
						// first generation
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// second generation
 | 
				
			||||||
 | 
						auto newPopup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// parent not set
 | 
				
			||||||
 | 
						newPopup.setVisible(true);
 | 
				
			||||||
 | 
						newPopup.onReload(&popup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(!newPopup.isVisible());
 | 
				
			||||||
 | 
						QVERIFY(!newPopup.backingWindow()->isVisible());
 | 
				
			||||||
 | 
						QCOMPARE(newPopup.backingWindow()->transientParent(), nullptr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::invisibleWithoutParent() { // NOLINT
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(!popup.isVisible());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::moveWithParent() { // NOLINT
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						popup.setRelativeX(10);
 | 
				
			||||||
 | 
						popup.setRelativeY(10);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QCOMPARE(popup.x(), parent.x() + 10);
 | 
				
			||||||
 | 
						QCOMPARE(popup.y(), parent.y() + 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.backingWindow()->setX(10);
 | 
				
			||||||
 | 
						parent.backingWindow()->setY(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QCOMPARE(popup.x(), parent.x() + 10);
 | 
				
			||||||
 | 
						QCOMPARE(popup.y(), parent.y() + 10);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::attachParentLate() { // NOLINT
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(!popup.isVisible());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						QVERIFY(popup.isVisible());
 | 
				
			||||||
 | 
						QVERIFY(popup.backingWindow()->isVisible());
 | 
				
			||||||
 | 
						QCOMPARE(popup.backingWindow()->transientParent(), parent.backingWindow());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::reparentLate() { // NOLINT
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QCOMPARE(popup.x(), parent.x());
 | 
				
			||||||
 | 
						QCOMPARE(popup.y(), parent.y());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto parent2 = ProxyWindowBase();
 | 
				
			||||||
 | 
						parent2.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent2.backingWindow()->setX(10);
 | 
				
			||||||
 | 
						parent2.backingWindow()->setY(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent2);
 | 
				
			||||||
 | 
						QVERIFY(popup.isVisible());
 | 
				
			||||||
 | 
						QVERIFY(popup.backingWindow()->isVisible());
 | 
				
			||||||
 | 
						QCOMPARE(popup.backingWindow()->transientParent(), parent2.backingWindow());
 | 
				
			||||||
 | 
						QCOMPARE(popup.x(), parent2.x());
 | 
				
			||||||
 | 
						QCOMPARE(popup.y(), parent2.y());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestPopupWindow::xMigrationFix() { // NOLINT
 | 
				
			||||||
 | 
						auto parent = ProxyWindowBase();
 | 
				
			||||||
 | 
						auto popup = ProxyPopupWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setParentWindow(&parent);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.onReload(nullptr);
 | 
				
			||||||
 | 
						popup.onReload(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QCOMPARE(popup.x(), parent.x());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup.setVisible(false);
 | 
				
			||||||
 | 
						popup.setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QCOMPARE(popup.x(), parent.x());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QTEST_MAIN(TestPopupWindow);
 | 
				
			||||||
							
								
								
									
										18
									
								
								src/core/test/popupwindow.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/core/test/popupwindow.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestPopupWindow: public QObject {
 | 
				
			||||||
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private slots:
 | 
				
			||||||
 | 
						void initiallyVisible();
 | 
				
			||||||
 | 
						void reloadReparent();
 | 
				
			||||||
 | 
						void reloadUnparent();
 | 
				
			||||||
 | 
						void invisibleWithoutParent();
 | 
				
			||||||
 | 
						void moveWithParent();
 | 
				
			||||||
 | 
						void attachParentLate();
 | 
				
			||||||
 | 
						void reparentLate();
 | 
				
			||||||
 | 
						void xMigrationFix();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -12,17 +12,19 @@
 | 
				
			||||||
#include "region.hpp"
 | 
					#include "region.hpp"
 | 
				
			||||||
#include "reload.hpp"
 | 
					#include "reload.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProxyWindowBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WindowInterface: public Reloadable {
 | 
					class WindowInterface: public Reloadable {
 | 
				
			||||||
	Q_OBJECT;
 | 
						Q_OBJECT;
 | 
				
			||||||
	// clang-format off
 | 
						// clang-format off
 | 
				
			||||||
	Q_PROPERTY(QQuickItem* contentItem READ contentItem);
 | 
						Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT);
 | 
				
			||||||
	/// If the window is shown or hidden. Defaults to true.
 | 
						/// If the window is shown or hidden. Defaults to true.
 | 
				
			||||||
	Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged);
 | 
						Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged);
 | 
				
			||||||
	Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged);
 | 
						Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged);
 | 
				
			||||||
	Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged);
 | 
						Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged);
 | 
				
			||||||
	/// The screen that the window currently occupies.
 | 
						/// The screen that the window currently occupies.
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	/// > [!INFO] This cannot be changed after windowConnected.
 | 
						/// This may be modified to move the window to the given screen.
 | 
				
			||||||
	Q_PROPERTY(QuickshellScreenInfo* screen READ screen WRITE setScreen NOTIFY screenChanged);
 | 
						Q_PROPERTY(QuickshellScreenInfo* screen READ screen WRITE setScreen NOTIFY screenChanged);
 | 
				
			||||||
	/// The background color of the window. Defaults to white.
 | 
						/// The background color of the window. Defaults to white.
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
| 
						 | 
					@ -92,6 +94,7 @@ class WindowInterface: public Reloadable {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	explicit WindowInterface(QObject* parent = nullptr): Reloadable(parent) {}
 | 
						explicit WindowInterface(QObject* parent = nullptr): Reloadable(parent) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] virtual ProxyWindowBase* proxyWindow() const = 0;
 | 
				
			||||||
	[[nodiscard]] virtual QQuickItem* contentItem() const = 0;
 | 
						[[nodiscard]] virtual QQuickItem* contentItem() const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] virtual bool isVisible() const = 0;
 | 
						[[nodiscard]] virtual bool isVisible() const = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
#include "../datastream.hpp"
 | 
					#include "datastream.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <qbytearray.h>
 | 
					#include <qbytearray.h>
 | 
				
			||||||
#include <qlist.h>
 | 
					#include <qlist.h>
 | 
				
			||||||
| 
						 | 
					@ -7,12 +7,10 @@
 | 
				
			||||||
#include <qsignalspy.h>
 | 
					#include <qsignalspy.h>
 | 
				
			||||||
#include <qtest.h>
 | 
					#include <qtest.h>
 | 
				
			||||||
#include <qtestcase.h>
 | 
					#include <qtestcase.h>
 | 
				
			||||||
#include <qtmetamacros.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestSplitParser: public QObject {
 | 
					#include "../datastream.hpp"
 | 
				
			||||||
	Q_OBJECT;
 | 
					
 | 
				
			||||||
private slots:
 | 
					void TestSplitParser::splits_data() { // NOLINT
 | 
				
			||||||
	void splits_data() { // NOLINT
 | 
					 | 
				
			||||||
	QTest::addColumn<QString>("mark");
 | 
						QTest::addColumn<QString>("mark");
 | 
				
			||||||
	QTest::addColumn<QString>("buffer");   // max that can go in the buffer
 | 
						QTest::addColumn<QString>("buffer");   // max that can go in the buffer
 | 
				
			||||||
	QTest::addColumn<QString>("incoming"); // data that has to be tested on the end in one go
 | 
						QTest::addColumn<QString>("incoming"); // data that has to be tested on the end in one go
 | 
				
			||||||
| 
						 | 
					@ -42,9 +40,9 @@ private slots:
 | 
				
			||||||
			<< QList<QString>({ "foo", "bar" }) << "baz";
 | 
								<< QList<QString>({ "foo", "bar" }) << "baz";
 | 
				
			||||||
	// clang-format on
 | 
						// clang-format on
 | 
				
			||||||
	// NOLINTEND
 | 
						// NOLINTEND
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void splits() { // NOLINT
 | 
					void TestSplitParser::splits() { // NOLINT
 | 
				
			||||||
	// NOLINTBEGIN
 | 
						// NOLINTBEGIN
 | 
				
			||||||
	QFETCH(QString, mark);
 | 
						QFETCH(QString, mark);
 | 
				
			||||||
	QFETCH(QString, buffer);
 | 
						QFETCH(QString, buffer);
 | 
				
			||||||
| 
						 | 
					@ -82,9 +80,9 @@ private slots:
 | 
				
			||||||
		QCOMPARE(actualResults, results);
 | 
							QCOMPARE(actualResults, results);
 | 
				
			||||||
		QCOMPARE(buffer, remainder);
 | 
							QCOMPARE(buffer, remainder);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void initBuffer() { // NOLINT
 | 
					void TestSplitParser::initBuffer() { // NOLINT
 | 
				
			||||||
	auto parser = SplitParser();
 | 
						auto parser = SplitParser();
 | 
				
			||||||
	auto spy = QSignalSpy(&parser, &DataStreamParser::read);
 | 
						auto spy = QSignalSpy(&parser, &DataStreamParser::read);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,8 +101,6 @@ private slots:
 | 
				
			||||||
	qInfo() << "ACTUAL RESULTS" << actualResults;
 | 
						qInfo() << "ACTUAL RESULTS" << actualResults;
 | 
				
			||||||
	QCOMPARE(actualResults, expected);
 | 
						QCOMPARE(actualResults, expected);
 | 
				
			||||||
	QCOMPARE(buf, "baz");
 | 
						QCOMPARE(buf, "baz");
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
QTEST_MAIN(TestSplitParser)
 | 
					QTEST_MAIN(TestSplitParser);
 | 
				
			||||||
#include "datastream.moc"
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/io/test/datastream.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/io/test/datastream.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestSplitParser: public QObject {
 | 
				
			||||||
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private slots:
 | 
				
			||||||
 | 
						void splits_data(); // NOLINT
 | 
				
			||||||
 | 
						void splits();
 | 
				
			||||||
 | 
						void initBuffer();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -187,6 +187,7 @@ void WaylandPanelInterface::onReload(QObject* oldInstance) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QQmlListProperty<QObject> WaylandPanelInterface::data() { return this->layer->data(); }
 | 
					QQmlListProperty<QObject> WaylandPanelInterface::data() { return this->layer->data(); }
 | 
				
			||||||
 | 
					ProxyWindowBase* WaylandPanelInterface::proxyWindow() const { return this->layer; }
 | 
				
			||||||
QQuickItem* WaylandPanelInterface::contentItem() const { return this->layer->contentItem(); }
 | 
					QQuickItem* WaylandPanelInterface::contentItem() const { return this->layer->contentItem(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NOLINTBEGIN
 | 
					// NOLINTBEGIN
 | 
				
			||||||
| 
						 | 
					@ -206,4 +207,6 @@ proxyPair(Anchors, anchors, setAnchors);
 | 
				
			||||||
proxyPair(Margins, margins, setMargins);
 | 
					proxyPair(Margins, margins, setMargins);
 | 
				
			||||||
proxyPair(qint32, exclusiveZone, setExclusiveZone);
 | 
					proxyPair(qint32, exclusiveZone, setExclusiveZone);
 | 
				
			||||||
proxyPair(ExclusionMode::Enum, exclusionMode, setExclusionMode);
 | 
					proxyPair(ExclusionMode::Enum, exclusionMode, setExclusionMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef proxyPair
 | 
				
			||||||
// NOLINTEND
 | 
					// NOLINTEND
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,6 +121,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onReload(QObject* oldInstance) override;
 | 
						void onReload(QObject* oldInstance) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] ProxyWindowBase* proxyWindow() const override;
 | 
				
			||||||
	[[nodiscard]] QQuickItem* contentItem() const override;
 | 
						[[nodiscard]] QQuickItem* contentItem() const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// NOLINTBEGIN
 | 
						// NOLINTBEGIN
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue