Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qhaikuwindow.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias Koenig <tobias.koenig@kdab.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qhaikuwindow.h"
5
6#include "private/qguiapplication_p.h"
7
8#include <QCoreApplication>
9#include <QThread>
10#include <QWindow>
11#include <qpa/qwindowsysteminterface.h>
12
13#include <Rect.h>
14#include <Window.h>
15
17
18enum {
21};
22
23HaikuWindowProxy::HaikuWindowProxy(QWindow *window, const QRect &rect, QObject *parent)
24 : QObject(parent)
25 , BWindow(BRect(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1),
26 window->title().toUtf8(), B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 0)
27 , m_qtCalledZoom(false)
28 , m_zoomInProgress(false)
29{
30}
31
33{
34 Q_EMIT moved(QPoint(pos.x, pos.y));
35}
36
37void HaikuWindowProxy::FrameResized(float width, float height)
38{
39 Q_EMIT resized(QSize(static_cast<int>(width), static_cast<int>(height)), m_zoomInProgress);
40
41 m_zoomInProgress = false;
42}
43
44void HaikuWindowProxy::WindowActivated(bool activated)
45{
46 Q_EMIT windowActivated(activated);
47}
48
49void HaikuWindowProxy::Minimize(bool minimize)
50{
51 BWindow::Minimize(minimize);
52
53 Q_EMIT minimized(minimize);
54}
55
56void HaikuWindowProxy::Zoom(BPoint pos, float width, float height)
57{
58 m_zoomInProgress = true;
59 BWindow::Zoom(pos, width, height);
60
61 // Only notify about Zoom invocations from the Haiku windowing system
62 if (!m_qtCalledZoom)
63 Q_EMIT zoomed();
64}
65
67{
68 Q_EMIT quitRequested();
69
70 // Return false to prevent Haiku windowing system to clean up
71 // the BWindow and BView instances. We will do that ourself when
72 // Qt invokes the dtor of QHaikuWindow
73 return false;
74}
75
77{
78 m_qtCalledZoom = true;
79 BWindow::Zoom();
80 m_qtCalledZoom = false;
81}
82
83QHaikuWindow::QHaikuWindow(QWindow *window)
84 : QPlatformWindow(window)
85 , m_window(nullptr)
86 , m_windowState(Qt::WindowNoState)
87{
88 const QRect rect = initialGeometry(window, window->geometry(), DefaultWindowWidth, DefaultWindowHeight);
89
90 HaikuWindowProxy *haikuWindow = new HaikuWindowProxy(window, rect, nullptr);
91 connect(haikuWindow, SIGNAL(moved(QPoint)), SLOT(haikuWindowMoved(QPoint)));
92 connect(haikuWindow, SIGNAL(resized(QSize,bool)), SLOT(haikuWindowResized(QSize,bool)));
93 connect(haikuWindow, SIGNAL(windowActivated(bool)), SLOT(haikuWindowActivated(bool)));
94 connect(haikuWindow, SIGNAL(minimized(bool)), SLOT(haikuWindowMinimized(bool)));
95 connect(haikuWindow, SIGNAL(zoomed()), SLOT(haikuWindowZoomed()));
96 connect(haikuWindow, SIGNAL(quitRequested()), SLOT(haikuWindowQuitRequested()), Qt::BlockingQueuedConnection);
97
98 m_window = haikuWindow;
99
100 if (Q_UNLIKELY(!m_window))
101 qFatal("QHaikuWindow: failed to create window");
102
103 setGeometry(rect);
104 setWindowFlags(window->flags());
105}
106
108{
109 m_window->LockLooper();
110 m_window->Quit();
111
112 m_window = nullptr;
113}
114
115void QHaikuWindow::setGeometry(const QRect &rect)
116{
117 QPlatformWindow::setGeometry(rect);
118
119 m_window->MoveTo(rect.x(), rect.y());
120 m_window->ResizeTo(rect.width(), rect.height());
121}
122
124{
125 const BRect decoratorFrame = m_window->DecoratorFrame();
126 const BRect frame = m_window->Frame();
127
128 return QMargins(frame.left - decoratorFrame.left,
129 frame.top - decoratorFrame.top,
130 decoratorFrame.right - frame.right,
131 decoratorFrame.bottom - frame.bottom);
132}
133
134void QHaikuWindow::setVisible(bool visible)
135{
136 if (visible) {
137 m_window->Show();
138
139 window()->requestActivate();
140
141 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size()));
142 } else {
143 m_window->Hide();
144 }
145}
146
148{
149 return !m_window->IsHidden();
150}
151
153{
154 return m_window->IsActive();
155}
156
158{
159 return (WId)static_cast<BWindow*>(m_window);
160}
161
163{
164 return m_window;
165}
166
168{
169 m_window->Activate(true);
170}
171
172void QHaikuWindow::setWindowState(Qt::WindowStates state)
173{
174 if (m_windowState == state)
175 return;
176
177 const Qt::WindowStates oldState = m_windowState;
178
179 m_windowState = state;
180
181 if (m_windowState & Qt::WindowMinimized)
183 else if (m_windowState & Qt::WindowMaximized)
185 else if (oldState & Qt::WindowMinimized)
186 m_window->Minimize(false); // undo minimize
187 else if (oldState & Qt::WindowMaximized)
188 m_window->zoomByQt(); // undo zoom
189}
190
191void QHaikuWindow::setWindowFlags(Qt::WindowFlags flags)
192{
193 const Qt::WindowType type = static_cast<Qt::WindowType>(static_cast<int>(flags & Qt::WindowType_Mask));
194
195 const bool isPopup = (type == Qt::Popup);
196 const bool isSplashScreen = (type == Qt::SplashScreen);
197 const bool isDialog = ((type == Qt::Dialog) || (type == Qt::Sheet) || (type == Qt::MSWindowsFixedSizeDialogHint));
198 const bool isTool = ((type == Qt::Tool) || (type == Qt::Drawer));
199 const bool isToolTip = (type == Qt::ToolTip);
200
201 window_look wlook = B_TITLED_WINDOW_LOOK;
202 window_feel wfeel = B_NORMAL_WINDOW_FEEL;
203 uint32 wflag = (B_NO_WORKSPACE_ACTIVATION | B_NOT_ANCHORED_ON_ACTIVATE);
204
205 if (isTool) {
206 wlook = B_FLOATING_WINDOW_LOOK;
207 wflag |= B_WILL_ACCEPT_FIRST_CLICK;
208 }
209
210 if (isSplashScreen) {
211 wlook = B_NO_BORDER_WINDOW_LOOK;
212 }
213
214 if (isPopup) {
215 wlook = B_NO_BORDER_WINDOW_LOOK;
216 wflag |= (B_WILL_ACCEPT_FIRST_CLICK | B_AVOID_FRONT | B_AVOID_FOCUS);
217 flags |= Qt::WindowStaysOnTopHint;
218 }
219
220 if (isDialog) {
221 if (window()->modality() == Qt::WindowModal)
222 wfeel = B_MODAL_SUBSET_WINDOW_FEEL;
223 else if (window()->modality() == Qt::ApplicationModal)
224 wfeel = B_MODAL_APP_WINDOW_FEEL;
225 }
226
227 if (isToolTip) {
228 wlook = B_NO_BORDER_WINDOW_LOOK;
229 wflag |= (B_WILL_ACCEPT_FIRST_CLICK | B_AVOID_FOCUS);
230 flags |= Qt::WindowStaysOnTopHint;
231 }
232
233 if (flags & Qt::FramelessWindowHint)
234 wlook = B_NO_BORDER_WINDOW_LOOK;
235
236 if (flags & Qt::MSWindowsFixedSizeDialogHint)
237 wflag |= (B_NOT_RESIZABLE | B_NOT_ZOOMABLE);
238
239 if (flags & Qt::CustomizeWindowHint) {
240 if (!(flags & Qt::WindowMinimizeButtonHint))
241 wflag |= B_NOT_MINIMIZABLE;
242 if (!(flags & Qt::WindowMaximizeButtonHint))
243 wflag |= B_NOT_ZOOMABLE;
244 if (!(flags & Qt::WindowCloseButtonHint))
245 wflag |= B_NOT_CLOSABLE;
246 }
247
248 if (flags & Qt::WindowStaysOnTopHint)
249 wfeel = B_FLOATING_ALL_WINDOW_FEEL;
250
251 m_window->SetLook(wlook);
252 m_window->SetFeel(wfeel);
253 m_window->SetFlags(wflag);
254}
255
256void QHaikuWindow::setWindowTitle(const QString &title)
257{
258 m_window->SetTitle(title.toLocal8Bit().constData());
259}
260
262{
263 m_window->SetSizeLimits(window()->minimumSize().width(),
264 window()->maximumSize().width(),
265 window()->minimumSize().height(),
266 window()->maximumSize().height());
267
268 m_window->SetZoomLimits(window()->maximumSize().width(),
269 window()->maximumSize().height());
270}
271
272void QHaikuWindow::haikuWindowMoved(const QPoint &pos)
273{
274 const QRect newGeometry(pos, geometry().size());
275
276 QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
277 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
278}
279
280void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress)
281{
282 const QRect newGeometry(geometry().topLeft(), size);
283
284 QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
285 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
286
287 if ((m_windowState == Qt::WindowMaximized) && !zoomInProgress) {
288 // the user has resized the window while maximized -> reset maximized flag
289 m_windowState = Qt::WindowNoState;
290
291 QWindowSystemInterface::handleWindowStateChanged(window(), m_windowState);
292 }
293}
294
295void QHaikuWindow::haikuWindowActivated(bool activated)
296{
297 QWindowSystemInterface::handleFocusWindowChanged(activated ? window() : nullptr);
298}
299
300void QHaikuWindow::haikuWindowMinimized(bool minimize)
301{
302 m_windowState = (minimize ? Qt::WindowMinimized : Qt::WindowNoState);
303
304 QWindowSystemInterface::handleWindowStateChanged(window(), m_windowState);
305}
306
307void QHaikuWindow::haikuWindowZoomed()
308{
309 m_windowState = (m_windowState == Qt::WindowMaximized ? Qt::WindowNoState : Qt::WindowMaximized);
310
311 QWindowSystemInterface::handleWindowStateChanged(window(), m_windowState);
312}
313
314void QHaikuWindow::haikuWindowQuitRequested()
315{
317}
318
319void QHaikuWindow::haikuMouseEvent(const QPoint &localPosition, const QPoint &globalPosition, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
320{
321 QWindowSystemInterface::handleMouseEvent(window(), localPosition, globalPosition,
322 buttons, modifiers, source);
323}
324
325void QHaikuWindow::haikuWheelEvent(const QPoint &localPosition, const QPoint &globalPosition, int delta, Qt::Orientation orientation, Qt::KeyboardModifiers modifiers)
326{
327 QWindowSystemInterface::handleWheelEvent(window(), localPosition, globalPosition, delta, orientation, modifiers);
328}
329
330void QHaikuWindow::haikuKeyEvent(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text)
331{
332 QWindowSystemInterface::handleKeyEvent(window(), type, key, modifiers, text);
333}
334
335void QHaikuWindow::haikuEnteredView()
336{
338}
339
340void QHaikuWindow::haikuExitedView()
341{
343}
344
345void QHaikuWindow::haikuDrawRequest(const QRect &rect)
346{
347 QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect));
348}
349
350QT_END_NAMESPACE
bool QuitRequested() override
void Zoom(BPoint pos, float width, float height) override
void Minimize(bool minimize) override
void FrameMoved(BPoint pos) override
void WindowActivated(bool activated) override
void FrameResized(float width, float height) override
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
bool isExposed() const override
Returns if this window is exposed in the windowing system.
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
BWindow * nativeHandle() const
void propagateSizeHints() override
Reimplement to propagate the size hints of the QWindow.
void setWindowTitle(const QString &title) override
Reimplement to set the window title to title.
virtual ~QHaikuWindow()
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
void setWindowState(Qt::WindowStates state) override
Requests setting the window state of this surface to type.
HaikuWindowProxy * m_window
bool isActive() const override
Returns true if the window should appear active from a style perspective.
WId winId() const override
Reimplement in subclasses to return a handle to the native window.
QMargins frameMargins() const override
void setWindowFlags(Qt::WindowFlags flags) override
Requests setting the window flags of this surface to flags.
QRect window() const
Returns the window rectangle.
@ DefaultWindowHeight
@ DefaultWindowWidth