Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
21#include <QtCore/qpointer.h>
22
24
26{
27 while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
28 w = w->parentWidget();
29 return w;
30}
31
33{
34 Q_DECLARE_PUBLIC(QSizeGrip)
35public:
37 void init();
40 int d;
41 int dxMax;
42 int dyMax;
45 QPointer<QWidget> tlw;
46
47 Qt::Corner corner() const;
48 inline bool atBottom() const
49 {
51 }
52
53 inline bool atLeft() const
54 {
56 }
57
59 {
60 Q_Q(QSizeGrip);
62 if (tlw == w)
63 return;
64 if (tlw)
66 tlw = w;
67 if (tlw)
69 }
70
71 // This slot is invoked by QLayout when the size grip is added to
72 // a layout or reparented after the tlw is shown. This re-implementation is basically
73 // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
74 // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
76 {
77 Q_Q(QSizeGrip);
78 bool showSizeGrip = !isExplicitlyHidden();
80 if (tlw && showSizeGrip) {
81 Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
82 sizeGripNotVisibleState |= Qt::WindowMaximized;
83 // Don't show the size grip if the tlw is maximized or in full screen mode.
84 showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
85 }
86 if (showSizeGrip)
87 q->setVisible(true);
88 }
89
91};
92
94 : dxMax(0)
95 , dyMax(0)
96 , gotMousePress(false)
97 , tlw(nullptr)
98 , m_platformSizeGrip(false)
99{
100}
101
103{
104 Q_Q(const QSizeGrip);
106 const QPoint sizeGripPos = q->mapTo(tlw, QPoint(0, 0));
107 bool isAtBottom = sizeGripPos.y() >= tlw->height() / 2;
108 bool isAtLeft = sizeGripPos.x() <= tlw->width() / 2;
109 if (isAtLeft)
110 return isAtBottom ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
111 else
112 return isAtBottom ? Qt::BottomRightCorner : Qt::TopRightCorner;
113}
114
168 : QWidget(*new QSizeGripPrivate, parent, { })
169{
170 Q_D(QSizeGrip);
171 d->init();
172}
173
174
176{
177 Q_Q(QSizeGrip);
179
180#if !defined(QT_NO_CURSOR)
183#endif
186}
187
188
195
200{
201 QStyleOption opt(0);
202 opt.initFrom(this);
203 return style()->sizeFromContents(QStyle::CT_SizeGrip, &opt, QSize(13, 13), this);
204}
205
214{
216 Q_D(QSizeGrip);
219 opt.initFrom(this);
220 opt.corner = d->m_corner;
221 painter.drawControl(QStyle::CE_SizeGrip, opt);
222}
223
232static Qt::Edges edgesFromCorner(Qt::Corner corner)
233{
234 switch (corner) {
239 }
240 return Qt::Edges{};
241}
242
243static bool usePlatformSizeGrip(const QWidget *tlw)
244{
245 const QString &platformName = QGuiApplication::platformName();
246 if (platformName.contains(u"xcb")) // ### FIXME QTBUG-69716
247 return false;
249 && platformName == u"windows") {
250 return false; // QTBUG-90628, flicker when using translucency
251 }
252 return true;
253}
254
256{
257 if (e->button() != Qt::LeftButton) {
259 return;
260 }
261
262 Q_D(QSizeGrip);
264 d->p = e->globalPosition().toPoint();
265 d->gotMousePress = true;
266 d->r = tlw->geometry();
267
268 // Does the platform provide size grip support?
269 d->m_platformSizeGrip = false;
270 if (tlw->isWindow()
271 && tlw->windowHandle()
274 && !tlw->hasHeightForWidth()
275 && usePlatformSizeGrip(tlw)) {
276 QPlatformWindow *platformWindow = tlw->windowHandle()->handle();
277 const Qt::Edges edges = edgesFromCorner(d->m_corner);
278 d->m_platformSizeGrip = platformWindow->startSystemResize(edges);
279 }
280
281 if (d->m_platformSizeGrip)
282 return;
283
284 // Find available desktop/workspace geometry.
285 QRect availableGeometry;
286 bool hasVerticalSizeConstraint = true;
287 bool hasHorizontalSizeConstraint = true;
288 if (tlw->isWindow()) {
290 availableGeometry = tlw->screen()->availableVirtualGeometry();
291 else
292 availableGeometry = QWidgetPrivate::availableScreenGeometry(tlw);
293 }
294 else {
295 const QWidget *tlwParent = tlw->parentWidget();
296 // Check if tlw is inside QAbstractScrollArea/QScrollArea.
297 // If that's the case tlw->parentWidget() will return the viewport
298 // and tlw->parentWidget()->parentWidget() will return the scroll area.
299#if QT_CONFIG(scrollarea)
300 QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(tlwParent->parentWidget());
301 if (scrollArea) {
302 hasHorizontalSizeConstraint = scrollArea->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
303 hasVerticalSizeConstraint = scrollArea->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
304 }
305#endif // QT_CONFIG(scrollarea)
306 availableGeometry = tlwParent->contentsRect();
307 }
308
309 // Find frame geometries, title bar height, and decoration sizes.
310 const QRect frameGeometry = tlw->frameGeometry();
311 const int titleBarHeight = qMax(tlw->geometry().y() - frameGeometry.y(), 0);
312 const int bottomDecoration = qMax(frameGeometry.height() - tlw->height() - titleBarHeight, 0);
313 const int leftRightDecoration = qMax((frameGeometry.width() - tlw->width()) / 2, 0);
314
315 // Determine dyMax depending on whether the sizegrip is at the bottom
316 // of the widget or not.
317 if (d->atBottom()) {
318 if (hasVerticalSizeConstraint)
319 d->dyMax = availableGeometry.bottom() - d->r.bottom() - bottomDecoration;
320 else
321 d->dyMax = INT_MAX;
322 } else {
323 if (hasVerticalSizeConstraint)
324 d->dyMax = availableGeometry.y() - d->r.y() + titleBarHeight;
325 else
326 d->dyMax = -INT_MAX;
327 }
328
329 // In RTL mode, the size grip is to the left; find dxMax from the desktop/workspace
330 // geometry, the size grip geometry and the width of the decoration.
331 if (d->atLeft()) {
332 if (hasHorizontalSizeConstraint)
333 d->dxMax = availableGeometry.x() - d->r.x() + leftRightDecoration;
334 else
335 d->dxMax = -INT_MAX;
336 } else {
337 if (hasHorizontalSizeConstraint)
338 d->dxMax = availableGeometry.right() - d->r.right() - leftRightDecoration;
339 else
340 d->dxMax = INT_MAX;
341 }
342}
343
344
351{
352 Q_D(QSizeGrip);
353 if (e->buttons() != Qt::LeftButton || d->m_platformSizeGrip) {
355 return;
356 }
357
359 if (!d->gotMousePress || tlw->testAttribute(Qt::WA_WState_ConfigPending))
360 return;
361
362 QPoint np(e->globalPosition().toPoint());
363
364 // Don't extend beyond the available geometry; bound to dyMax and dxMax.
365 QSize ns;
366 if (d->atBottom())
367 ns.rheight() = d->r.height() + qMin(np.y() - d->p.y(), d->dyMax);
368 else
369 ns.rheight() = d->r.height() - qMax(np.y() - d->p.y(), d->dyMax);
370
371 if (d->atLeft())
372 ns.rwidth() = d->r.width() - qMax(np.x() - d->p.x(), d->dxMax);
373 else
374 ns.rwidth() = d->r.width() + qMin(np.x() - d->p.x(), d->dxMax);
375
377
378 QPoint p;
379 QRect nr(p, ns);
380 if (d->atBottom()) {
381 if (d->atLeft())
382 nr.moveTopRight(d->r.topRight());
383 else
384 nr.moveTopLeft(d->r.topLeft());
385 } else {
386 if (d->atLeft())
387 nr.moveBottomRight(d->r.bottomRight());
388 else
389 nr.moveBottomLeft(d->r.bottomLeft());
390 }
391
392 tlw->setGeometry(nr);
393}
394
399{
400 if (mouseEvent->button() == Qt::LeftButton) {
401 Q_D(QSizeGrip);
402 d->gotMousePress = false;
403 d->p = QPoint();
404 } else {
405 QWidget::mouseReleaseEvent(mouseEvent);
406 }
407}
408
412void QSizeGrip::moveEvent(QMoveEvent * /*moveEvent*/)
413{
414 Q_D(QSizeGrip);
415 // We're inside a resize operation; no update necessary.
416 if (!d->p.isNull())
417 return;
418
419 d->m_corner = d->corner();
420#if !defined(QT_NO_CURSOR)
421 setCursor(d->m_corner == Qt::TopLeftCorner || d->m_corner == Qt::BottomRightCorner
423#endif
424}
425
433
441
445void QSizeGrip::setVisible(bool visible)
446{
448}
449
452{
453 Q_D(QSizeGrip);
454 if (d->isExplicitlyHidden()
456 || o != d->tlw) {
457 return QWidget::eventFilter(o, e);
458 }
459 Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
460 sizeGripNotVisibleState |= Qt::WindowMaximized;
461 // Don't show the size grip if the tlw is maximized or in full screen mode.
462 setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
464 return QWidget::eventFilter(o, e);
465}
466
471{
472 return QWidget::event(event);
473}
474
476
477#include "moc_qsizegrip.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
@ WindowStateChange
Definition qcoreevent.h:143
Type type() const
Returns the event type.
Definition qcoreevent.h:304
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:586
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:1398
\inmodule QtGui
Definition qevent.h:196
The QMoveEvent class contains event parameters for move events.
Definition qevent.h:502
\inmodule QtCore
Definition qobject.h:103
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
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:1555
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2370
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
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 ...
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:404
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:135
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
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:578
QPointF globalPosition() const
Returns the position of the point in this event on the screen or virtual desktop.
Definition qevent.h:123
Qt::MouseButton button() const
Returns the button that caused the event.
Definition qevent.h:116
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
Definition qevent.h:117
QPointer< QWidget > tlw
Definition qsizegrip.cpp:45
void _q_showIfNotHidden()
Definition qsizegrip.cpp:75
bool atBottom() const
Definition qsizegrip.cpp:48
void updateTopLevelWidget()
Definition qsizegrip.cpp:58
Qt::Corner m_corner
Definition qsizegrip.cpp:43
bool atLeft() const
Definition qsizegrip.cpp:53
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.
void setVisible(bool) override
\reimp
~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:129
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
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:563
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
bool isExplicitlyHidden() const
Definition qwidget.cpp:8384
static QRect availableScreenGeometry(const QWidget *widget)
Definition qwidget_p.h:474
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:9461
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:9483
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:9508
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
virtual void setVisible(bool visible)
Definition qwidget.cpp:8255
QWindow * windowHandle() const
If this is a native widget, return the associated QWindow.
Definition qwidget.cpp:2483
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
QStyle * style() const
Definition qwidget.cpp:2600
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:2888
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:2496
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:4960
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
QStyleOptionButton opt
Combined button and popup list for selecting options.
@ WindowFullScreen
Definition qnamespace.h:255
@ WindowMaximized
Definition qnamespace.h:254
@ BottomLeftCorner
@ TopRightCorner
@ TopLeftCorner
@ BottomRightCorner
@ LeftButton
Definition qnamespace.h:58
@ WA_WState_ExplicitShowHide
Definition qnamespace.h:335
@ WA_TranslucentBackground
Definition qnamespace.h:402
@ WA_DontShowOnScreen
Definition qnamespace.h:383
@ WA_WState_ConfigPending
Definition qnamespace.h:331
@ SizeFDiagCursor
@ SizeBDiagCursor
@ ScrollBarAlwaysOff
@ RightEdge
@ TopEdge
@ BottomEdge
@ LeftEdge
@ SubWindow
Definition qnamespace.h:216
@ X11BypassWindowManagerHint
Definition qnamespace.h:224
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:25
#define Q_UNUSED(x)
QObject::connect nullptr
QPainter painter(this)
[7]
QT_BEGIN_NAMESPACE bool toBool(const QString &str)
Definition utils.h:14