QWindowKit  1.5.1.0
Cross-platform window customization framework
Loading...
Searching...
No Matches
systemwindow_p.h
1// Copyright (C) 2023-present Stdware Collections (https://www.github.com/stdware)
2// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef SYSTEMWINDOW_P_H
6#define SYSTEMWINDOW_P_H
7
8//
9// W A R N I N G !!!
10// -----------------
11//
12// This file is not part of the QWindowKit API. It is used purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or may even be removed.
15//
16
17#include <QtGui/QWindow>
18#include <QtGui/QMouseEvent>
19
20#include <QWKCore/private/qwkglobal_p.h>
21
22namespace QWK {
23
24 class WindowMoveManipulator : public QObject {
25 public:
26 explicit WindowMoveManipulator(QWindow *targetWindow)
27 : QObject(targetWindow), target(targetWindow), operationComplete(false),
28 initialMousePosition(QCursor::pos()),
29 initialWindowPosition(targetWindow->position()) {
30 target->installEventFilter(this);
31 }
32
33 protected:
34 bool eventFilter(QObject *obj, QEvent *event) override {
35 if (operationComplete) {
36 return false;
37 }
38 switch (event->type()) {
39 case QEvent::MouseMove: {
40 auto mouseEvent = static_cast<QMouseEvent *>(event);
41 QPoint delta = getMouseEventGlobalPos(mouseEvent) - initialMousePosition;
42 target->setPosition(initialWindowPosition + delta);
43 return true;
44 }
45
46 case QEvent::MouseButtonRelease: {
47 if (target->y() < 0) {
48 target->setPosition(target->x(), 0);
49 }
50 operationComplete = true;
51 deleteLater();
52 break;
53 }
54
55 default:
56 break;
57 }
58 return false;
59 }
60
61 private:
62 QWindow *target;
63 bool operationComplete;
64 QPoint initialMousePosition;
65 QPoint initialWindowPosition;
66 };
67
68 class WindowResizeManipulator : public QObject {
69 public:
70 WindowResizeManipulator(QWindow *targetWindow, Qt::Edges edges)
71 : QObject(targetWindow), target(targetWindow), operationComplete(false),
72 initialMousePosition(QCursor::pos()), initialWindowRect(target->geometry()),
73 resizeEdges(edges) {
74 target->installEventFilter(this);
75 }
76
77 protected:
78 bool eventFilter(QObject *obj, QEvent *event) override {
79 if (operationComplete) {
80 return false;
81 }
82 switch (event->type()) {
83 case QEvent::MouseMove: {
84 auto mouseEvent = static_cast<QMouseEvent *>(event);
85 QPoint globalMousePos = getMouseEventGlobalPos(mouseEvent);
86 QRect windowRect = initialWindowRect;
87
88 if (resizeEdges & Qt::LeftEdge) {
89 int delta = globalMousePos.x() - initialMousePosition.x();
90 windowRect.setLeft(initialWindowRect.left() + delta);
91 }
92 if (resizeEdges & Qt::RightEdge) {
93 int delta = globalMousePos.x() - initialMousePosition.x();
94 windowRect.setRight(initialWindowRect.right() + delta);
95 }
96 if (resizeEdges & Qt::TopEdge) {
97 int delta = globalMousePos.y() - initialMousePosition.y();
98 windowRect.setTop(initialWindowRect.top() + delta);
99 }
100 if (resizeEdges & Qt::BottomEdge) {
101 int delta = globalMousePos.y() - initialMousePosition.y();
102 windowRect.setBottom(initialWindowRect.bottom() + delta);
103 }
104
105 target->setGeometry(windowRect);
106 return true;
107 }
108
109 case QEvent::MouseButtonRelease: {
110 operationComplete = true;
111 deleteLater();
112 break;
113 }
114
115 default:
116 break;
117 }
118 return false;
119 }
120
121 private:
122 QWindow *target;
123 bool operationComplete;
124 QPoint initialMousePosition;
125 QRect initialWindowRect;
126 Qt::Edges resizeEdges;
127 };
128
129 // QWindow::startSystemMove() and QWindow::startSystemResize() is first supported at Qt 5.15
130 // QWindow::startSystemResize() returns false on macOS
131 // QWindow::startSystemMove() and QWindow::startSystemResize() returns false on Linux Unity DE
132
133 // When the new API fails, we emulate the window actions using the classical API.
134
135 inline void startSystemMove(QWindow *window) {
136 Q_ASSERT(window);
137#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
138 std::ignore = new WindowMoveManipulator(window);
139#elif defined(Q_OS_LINUX)
140 if (window->startSystemMove()) {
141 return;
142 }
143 std::ignore = new WindowMoveManipulator(window);
144#else
145 window->startSystemMove();
146#endif
147 }
148
149 inline void startSystemResize(QWindow *window, Qt::Edges edges) {
150 Q_ASSERT(window);
151#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
152 std::ignore = new WindowResizeManipulator(window, edges);
153#elif defined(Q_OS_MAC) || defined(Q_OS_LINUX)
154 if (window->startSystemResize(edges)) {
155 return;
156 }
157 std::ignore = new WindowResizeManipulator(window, edges);
158#else
159 window->startSystemResize(edges);
160#endif
161 }
162
163}
164
165#endif // SYSTEMWINDOW_P_H
QWindowKit namespace.
Definition abstractwindowcontext.cpp:13