Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qsizegrip.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
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 "qsizegrip.h"
5
6#include "qapplication.h"
7#include "qevent.h"
8#include "qstylepainter.h"
9#include "qwindow.h"
10#include <qpa/qplatformwindow.h>
11#include "qstyle.h"
12#include "qstyleoption.h"
13#include "qlayout.h"
14#include "qdebug.h"
15
16#include <private/qwidget_p.h>
17#include "private/qapplication_p.h"
18#include <qpa/qplatformtheme.h>
19#include <QtWidgets/qabstractscrollarea.h>
20
22
24{
25 while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
26 w = w->parentWidget();
27 return w;
28}
29
31{
32 Q_DECLARE_PUBLIC(QSizeGrip)
33public:
35 void init();
38 int d;
39 int dxMax;
40 int dyMax;
44
45 Qt::Corner corner() const;
46 inline bool atBottom() const
47 {
49 }
50
51 inline bool atLeft() const
52 {
54 }
55
57 {
58 Q_Q(QSizeGrip);
60 if (tlw == w)
61 return;
62 if (tlw)
64 tlw = w;
65 if (tlw)
67 }
68
69 // This slot is invoked by QLayout when the size grip is added to
70 // a layout or reparented after the tlw is shown. This re-implementation is basically
71 // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
72 // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
74 {
75 Q_Q(QSizeGrip);
76 bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
78 if (tlw && showSizeGrip) {
79 Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
80 sizeGripNotVisibleState |= Qt::WindowMaximized;
81 // Don't show the size grip if the tlw is maximized or in full screen mode.
82 showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
83 }
84 if (showSizeGrip)
85 q->setVisible(true);
86 }
87
89};
90
92 : dxMax(0)
93 , dyMax(0)
94 , gotMousePress(false)
95 , tlw(nullptr)
96 , m_platformSizeGrip(false)
97{
98}
99
101{
102 Q_Q(const QSizeGrip);
104 const QPoint sizeGripPos = q->mapTo(tlw, QPoint(0, 0));
105 bool isAtBottom = sizeGripPos.y() >= tlw->height() / 2;
106 bool isAtLeft = sizeGripPos.x() <= tlw->width() / 2;
107 if (isAtLeft)
108 return isAtBottom ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
109 else
110 return isAtBottom ? Qt::BottomRightCorner : Qt::TopRightCorner;
111}
112
166 : QWidget(*new QSizeGripPrivate, parent, { })
167{
168 Q_D(QSizeGrip);
169 d->init();
170}
171
172
174{
175 Q_Q(QSizeGrip);
177
178#if !defined(QT_NO_CURSOR)
181#endif
184}
185
186
191{
192}
193
198{
199 QStyleOption opt(0);
200 opt.initFrom(this);
201 return style()->sizeFromContents(QStyle::CT_SizeGrip, &opt, QSize(13, 13), this);
202}
203
212{
214 Q_D(QSizeGrip);
217 opt.initFrom(this);
218 opt.corner = d->m_corner;
219 painter.drawControl(QStyle::CE_SizeGrip, opt);
220}
221
230static Qt::Edges edgesFromCorner(Qt::Corner corner)
231{
232 switch (corner) {
237 }
238 return Qt::Edges{};
239}
240
241static bool usePlatformSizeGrip(const QWidget *tlw)
242{
243 const QString &platformName = QGuiApplication::platformName();
244 if (platformName.contains(u"xcb")) // ### FIXME QTBUG-69716
245 return false;
247 && platformName == u"windows") {
248 return false; // QTBUG-90628, flicker when using translucency
249 }
250 return true;
251}
252
254{
255 if (e->button() != Qt::LeftButton) {
257 return;
258 }
259
260 Q_D(QSizeGrip);
262 d->p = e->globalPosition().toPoint();
263 d->gotMousePress = true;
264 d->r = tlw->geometry();
265
266 // Does the platform provide size grip support?
267 d->m_platformSizeGrip = false;
268 if (tlw->isWindow()
269 && tlw->windowHandle()
272 && !tlw->hasHeightForWidth()
273 && usePlatformSizeGrip(tlw)) {
274 QPlatformWindow *platformWindow = tlw->windowHandle()->handle();
275 const Qt::Edges edges = edgesFromCorner(d->m_corner);
276 d->m_platformSizeGrip = platformWindow->startSystemResize(edges);
277 }
278
279 if (d->m_platformSizeGrip)
280 return;
281
282 // Find available desktop/workspace geometry.
283 QRect availableGeometry;
284 bool hasVerticalSizeConstraint = true;
285 bool hasHorizontalSizeConstraint = true;
286 if (tlw->isWindow()) {
288 availableGeometry = tlw->screen()->availableVirtualGeometry();
289 else
290 availableGeometry = QWidgetPrivate::availableScreenGeometry(tlw);
291 }
292 else {
293 const QWidget *tlwParent = tlw->parentWidget();
294 // Check if tlw is inside QAbstractScrollArea/QScrollArea.
295 // If that's the case tlw->parentWidget() will return the viewport
296 // and tlw->parentWidget()->parentWidget() will return the scroll area.
297#if QT_CONFIG(scrollarea)
298 QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(tlwParent->parentWidget());
299 if (scrollArea) {
300 hasHorizontalSizeConstraint = scrollArea->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
301 hasVerticalSizeConstraint = scrollArea->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
302 }
303#endif // QT_CONFIG(scrollarea)
304 availableGeometry = tlwParent->contentsRect();
305 }
306
307 // Find frame geometries, title bar height, and decoration sizes.
308 const QRect frameGeometry = tlw->frameGeometry();
309 const int titleBarHeight = qMax(tlw->geometry().y() - frameGeometry.y(), 0);
310 const int bottomDecoration = qMax(frameGeometry.height() - tlw->height() - titleBarHeight, 0);
311 const int leftRightDecoration = qMax((frameGeometry.width() - tlw->width()) / 2, 0);
312
313 // Determine dyMax depending on whether the sizegrip is at the bottom
314 // of the widget or not.
315 if (d->atBottom()) {
316 if (hasVerticalSizeConstraint)
317 d->dyMax = availableGeometry.bottom() - d->r.bottom() - bottomDecoration;
318 else
319 d->dyMax = INT_MAX;
320 } else {
321 if (hasVerticalSizeConstraint)
322 d->dyMax = availableGeometry.y() - d->r.y() + titleBarHeight;
323 else
324 d->dyMax = -INT_MAX;
325 }
326
327 // In RTL mode, the size grip is to the left; find dxMax from the desktop/workspace
328 // geometry, the size grip geometry and the width of the decoration.
329 if (d->atLeft()) {
330 if (hasHorizontalSizeConstraint)
331 d->dxMax = availableGeometry.x() - d->r.x() + leftRightDecoration;
332 else
333 d->dxMax = -INT_MAX;
334 } else {
335 if (hasHorizontalSizeConstraint)
336 d->dxMax = availableGeometry.right() - d->r.right() - leftRightDecoration;
337 else
338 d->dxMax = INT_MAX;
339 }
340}
341
342
349{
350 Q_D(QSizeGrip);
351 if (e->buttons() != Qt::LeftButton || d->m_platformSizeGrip) {
353 return;
354 }
355
357 if (!d->gotMousePress || tlw->testAttribute(Qt::WA_WState_ConfigPending))
358 return;
359
360 QPoint np(e->globalPosition().toPoint());
361
362 // Don't extend beyond the available geometry; bound to dyMax and dxMax.
363 QSize ns;
364 if (d->atBottom())
365 ns.rheight() = d->r.height() + qMin(np.y() - d->p.y(), d->dyMax);
366 else
367 ns.rheight() = d->r.height() - qMax(np.y() - d->p.y(), d->dyMax);
368
369 if (d->atLeft())
370 ns.rwidth() = d->r.width() - qMax(np.x() - d->p.x(), d->dxMax);
371 else
372 ns.rwidth() = d->r.width() + qMin(np.x() - d->p.x(), d->dxMax);
373
375
376 QPoint p;
377 QRect nr(p, ns);
378 if (d->atBottom()) {
379 if (d->atLeft())
380 nr.moveTopRight(d->r.topRight());
381 else
382 nr.moveTopLeft(d->r.topLeft());
383 } else {
384 if (d->atLeft())
385 nr.moveBottomRight(d->r.bottomRight());
386 else
387 nr.moveBottomLeft(d->r.bottomLeft());
388 }
389
390 tlw->setGeometry(nr);
391}
392
397{
398 if (mouseEvent->button() == Qt::LeftButton) {
399 Q_D(QSizeGrip);
400 d->gotMousePress = false;
401 d->p = QPoint();
402 } else {
403 QWidget::mouseReleaseEvent(mouseEvent);
404 }
405}
406
410void QSizeGrip::moveEvent(QMoveEvent * /*moveEvent*/)
411{
412 Q_D(QSizeGrip);
413 // We're inside a resize operation; no update necessary.
414 if (!d->p.isNull())
415 return;
416
417 d->m_corner = d->corner();
418#if !defined(QT_NO_CURSOR)
419 setCursor(d->m_corner == Qt::TopLeftCorner || d->m_corner == Qt::BottomRightCorner
421#endif
422}
423
428{
430}
431
436{
438}
439
443void QSizeGrip::setVisible(bool visible)
444{
446}
447
450{
451 Q_D(QSizeGrip);
453 || e->type() != QEvent::WindowStateChange
454 || o != d->tlw) {
455 return QWidget::eventFilter(o, e);
456 }
457 Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
458 sizeGripNotVisibleState |= Qt::WindowMaximized;
459 // Don't show the size grip if the tlw is maximized or in full screen mode.
460 setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
462 return QWidget::eventFilter(o, e);
463}
464
469{
470 return QWidget::event(event);
471}
472
474
475#include "moc_qsizegrip.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
@ WindowStateChange
Definition qcoreevent.h:143
static QPlatformTheme * platformTheme()
QString platformName
The name of the underlying platform plugin.
The QHideEvent class provides an event which is sent after a widget is hidden.
Definition qevent.h:585
static QSize closestAcceptableSize(const QWidget *w, const QSize &s)
Returns a size that satisfies all size constraints on widget, including heightForWidth() and that is ...
Definition qlayout.cpp:1397
\inmodule QtGui
Definition qevent.h:195
The QMoveEvent class contains event parameters for move events.
Definition qevent.h:501
\inmodule QtCore
Definition qobject.h:90
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2269
virtual bool eventFilter(QObject *watched, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object.
Definition qobject.cpp:1518
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2300
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:485
The QPlatformWindow class provides an abstraction for top-level windows.
virtual bool startSystemResize(Qt::Edges edges)
Reimplement this method to start a system resize operation if the system supports it and return true ...
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
\inmodule QtCore
Definition qpointer.h:18
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr void moveBottomRight(const QPoint &p) noexcept
Moves the rectangle, leaving the bottom-right corner at the given position.
Definition qrect.h:309
constexpr void moveTopLeft(const QPoint &p) noexcept
Moves the rectangle, leaving the top-left corner at the given position.
Definition qrect.h:303
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:181
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:184
constexpr void moveBottomLeft(const QPoint &p) noexcept
Moves the rectangle, leaving the bottom-left corner at the given position.
Definition qrect.h:321
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:187
constexpr void moveTopRight(const QPoint &p) noexcept
Moves the rectangle, leaving the top-right corner at the given position.
Definition qrect.h:315
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:178
QRect availableVirtualGeometry
the available geometry of the virtual desktop to which this screen belongs
Definition qscreen.h:49
The QShowEvent class provides an event that is sent when a widget is shown.
Definition qevent.h:577
Qt::MouseButton button() const
Returns the button that caused the event.
Definition qevent.h:115
QPointer< QWidget > tlw
Definition qsizegrip.cpp:43
void _q_showIfNotHidden()
Definition qsizegrip.cpp:73
bool atBottom() const
Definition qsizegrip.cpp:46
void updateTopLevelWidget()
Definition qsizegrip.cpp:56
Qt::Corner m_corner
Definition qsizegrip.cpp:41
bool atLeft() const
Definition qsizegrip.cpp:51
Qt::Corner corner() const
The QSizeGrip class provides a resize handle for resizing top-level windows.
Definition qsizegrip.h:16
QSize sizeHint() const override
\reimp
void mousePressEvent(QMouseEvent *) override
Receives the mouse press events for the widget, and primes the resize operation.
bool eventFilter(QObject *, QEvent *) override
\reimp
void showEvent(QShowEvent *showEvent) override
\reimp
void hideEvent(QHideEvent *hideEvent) override
\reimp
void paintEvent(QPaintEvent *) override
Paints the resize grip.
void mouseReleaseEvent(QMouseEvent *mouseEvent) override
\reimp
void moveEvent(QMoveEvent *moveEvent) override
\reimp
QSizeGrip(QWidget *parent)
Constructs a resize corner as a child widget of the given parent.
bool event(QEvent *) override
\reimp
void mouseMoveEvent(QMouseEvent *) override
Resizes the top-level widget containing this widget.
~QSizeGrip()
Destroys this size grip.
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition qsizepolicy.h:18
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1217
The QStyleOption class stores the parameters used by QStyle functions.
void initFrom(const QWidget *w)
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
@ CT_SizeGrip
Definition qstyle.h:561
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=nullptr) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
@ CE_SizeGrip
Definition qstyle.h:207
static QRect availableScreenGeometry(const QWidget *widget)
Definition qwidget_p.h:468
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
virtual bool hasHeightForWidth() const
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:886
Qt::WindowFlags windowFlags() const
Window flags are a combination of a type (e.g.
Definition qwidget.h:803
virtual void hideEvent(QHideEvent *event)
This event handler can be reimplemented in a subclass to receive widget hide events.
virtual void mouseMoveEvent(QMouseEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
Definition qwidget.cpp:9507
bool isHidden() const
Returns true if the widget is hidden, otherwise returns false.
Definition qwidget.h:877
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition qwidget.h:106
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
virtual void mousePressEvent(QMouseEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
Definition qwidget.cpp:9529
QRect contentsRect() const
Returns the area inside the widget's margins.
Definition qwidget.cpp:7753
virtual void mouseReleaseEvent(QMouseEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive mouse release even...
Definition qwidget.cpp:9554
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
virtual void setVisible(bool visible)
Definition qwidget.cpp:8329
QWindow * windowHandle() const
If this is a native widget, return the associated QWindow.
Definition qwidget.cpp:2490
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8912
QStyle * style() const
Definition qwidget.cpp:2607
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition qwidget.h:811
Qt::WindowStates windowState() const
Returns the current window state.
Definition qwidget.cpp:2895
QRect frameGeometry
geometry of the widget relative to its parent including any window frame
Definition qwidget.h:107
QScreen * screen() const
Returns the screen the widget is on.
Definition qwidget.cpp:2503
virtual void showEvent(QShowEvent *event)
This event handler can be reimplemented in a subclass to receive widget show events which are passed ...
void setCursor(const QCursor &)
Definition qwidget.cpp:4967
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition qwidget.h:910
bool visible
whether the widget is visible
Definition qwidget.h:144
double e
QStyleOptionButton opt
Combined button and popup list for selecting options.
@ WindowFullScreen
Definition qnamespace.h:254
@ WindowMaximized
Definition qnamespace.h:253
@ BottomLeftCorner
@ TopRightCorner
@ TopLeftCorner
@ BottomRightCorner
@ LeftButton
Definition qnamespace.h:57
@ WA_WState_ExplicitShowHide
Definition qnamespace.h:334
@ WA_TranslucentBackground
Definition qnamespace.h:401
@ WA_DontShowOnScreen
Definition qnamespace.h:382
@ WA_WState_ConfigPending
Definition qnamespace.h:330
@ SizeFDiagCursor
@ SizeBDiagCursor
@ ScrollBarAlwaysOff
@ RightEdge
@ TopEdge
@ BottomEdge
@ LeftEdge
@ SubWindow
Definition qnamespace.h:215
@ X11BypassWindowManagerHint
Definition qnamespace.h:223
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLfloat GLfloat GLfloat w
[0]
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
static Qt::Edges edgesFromCorner(Qt::Corner corner)
static bool usePlatformSizeGrip(const QWidget *tlw)
static QT_BEGIN_NAMESPACE QWidget * qt_sizegrip_topLevelWidget(QWidget *w)
Definition qsizegrip.cpp:23
#define Q_UNUSED(x)
QObject::connect nullptr
QPainter painter(this)
[7]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent
QT_BEGIN_NAMESPACE bool toBool(const QString &str)
Definition utils.h:14