KDDockWidgets API Documentation  1.5
WidgetResizeHandler.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5  Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6 
7  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8 
9  Contact KDAB at <info@kdab.com> for commercial licensing options.
10 */
11 
12 #include "WidgetResizeHandler_p.h"
13 #include "FloatingWindow_p.h"
14 #include "TitleBar_p.h"
15 #include "DragController_p.h"
16 #include "Config.h"
17 #include "Qt5Qt6Compat_p.h"
18 #include "Utils_p.h"
19 #include "DockRegistry_p.h"
20 #include "MDILayoutWidget_p.h"
21 
22 #include <QEvent>
23 #include <QMouseEvent>
24 #include <QDebug>
25 #include <QGuiApplication>
26 #include <QScreen>
27 #include <QWindow>
28 #include <QScopedValueRollback>
29 
30 #if defined(Q_OS_WIN)
31 #include <QtGui/private/qhighdpiscaling_p.h>
32 #include <windowsx.h>
33 #include <windows.h>
34 #include <dwmapi.h>
35 #if defined(Q_CC_MSVC)
36 #pragma comment(lib, "Dwmapi.lib")
37 #pragma comment(lib, "User32.lib")
38 #endif
39 #endif
40 
41 using namespace KDDockWidgets;
42 
43 bool WidgetResizeHandler::s_disableAllHandlers = false;
44 WidgetResizeHandler::WidgetResizeHandler(bool isTopLevelResizer, QWidgetOrQuick *target)
45  : QObject(target)
46  , m_isTopLevelWindowResizer(isTopLevelResizer)
47 {
48  setTarget(target);
49 }
50 
51 WidgetResizeHandler::~WidgetResizeHandler()
52 {
53 }
54 
55 void WidgetResizeHandler::setAllowedResizeSides(CursorPositions sides)
56 {
57  mAllowedResizeSides = sides;
58 }
59 
60 void WidgetResizeHandler::setResizeGap(int gap)
61 {
62  m_resizeGap = gap;
63 }
64 
65 bool WidgetResizeHandler::isMDI() const
66 {
67  auto frame = qobject_cast<Frame *>(mTarget);
68  return frame && frame->isMDI();
69 }
70 
71 bool WidgetResizeHandler::isResizing() const
72 {
73  return m_resizingInProgress;
74 }
75 
76 int WidgetResizeHandler::widgetResizeHandlerMargin()
77 {
78  return 4; // pixels
79 }
80 
81 bool WidgetResizeHandler::eventFilter(QObject *o, QEvent *e)
82 {
83  if (s_disableAllHandlers)
84  return false;
85 
86  auto widget = qobject_cast<QWidgetOrQuick *>(o);
87  if (!widget)
88  return false;
89 
90  if (m_isTopLevelWindowResizer && (!widget->isTopLevel() || o != mTarget))
91  return false;
92 
93  switch (e->type()) {
95  if (mTarget->isMaximized())
96  break;
97 
98  auto mouseEvent = static_cast<QMouseEvent *>(e);
99  auto cursorPos = cursorPosition(Qt5Qt6Compat::eventGlobalPos(mouseEvent));
100  updateCursor(cursorPos);
101  if (cursorPos == CursorPosition_Undefined)
102  return false;
103 
104  const int m = widgetResizeHandlerMargin();
105  const QRect widgetRect = mTarget->rect().marginsAdded(QMargins(m, m, m, m));
106  const QPoint cursorPoint = mTarget->mapFromGlobal(Qt5Qt6Compat::eventGlobalPos(mouseEvent));
107  if (!widgetRect.contains(cursorPoint) || mouseEvent->button() != Qt::LeftButton)
108  return false;
109 
110  m_resizingInProgress = true;
111  if (isMDI())
112  Q_EMIT DockRegistry::self()->frameInMDIResizeChanged();
113  mNewPosition = Qt5Qt6Compat::eventGlobalPos(mouseEvent);
114  mCursorPos = cursorPos;
115 
116  return true;
117  }
119  m_resizingInProgress = false;
120  if (isMDI()) {
121  Q_EMIT DockRegistry::self()->frameInMDIResizeChanged();
122  auto frame = static_cast<Frame *>(mTarget);
123  // Usually in KDDW all geometry changes are done in the layout items, which propagate to the widgets
124  // When resizing a MDI however, we're resizing the widget directly. So update the corresponding layout
125  // item when we're finished.
126  frame->mdiLayoutWidget()->setDockWidgetGeometry(frame, frame->QWidgetAdapter::geometry());
127  }
128  updateCursor(CursorPosition_Undefined);
129  auto mouseEvent = static_cast<QMouseEvent *>(e);
130 
131  if (mTarget->isMaximized() || !m_resizingInProgress || mouseEvent->button() != Qt::LeftButton)
132  break;
133 
134  mTarget->releaseMouse();
135  mTarget->releaseKeyboard();
136  return true;
137 
138  break;
139  }
140  case QEvent::MouseMove: {
141  if (mTarget->isMaximized())
142  break;
143 
144  if (isMDI()) {
145  const Frame *frameBeingResized = DockRegistry::self()->frameInMDIResize();
146  const bool otherFrameBeingResized = frameBeingResized && frameBeingResized != mTarget;
147  if (otherFrameBeingResized) {
148  // only one at a time!
149  return false;
150  }
151  }
152 
153  auto mouseEvent = static_cast<QMouseEvent *>(e);
154  m_resizingInProgress = m_resizingInProgress && (mouseEvent->buttons() & Qt::LeftButton);
155  const bool state = m_resizingInProgress;
156  if (m_isTopLevelWindowResizer)
157  m_resizingInProgress = ((o == mTarget) && m_resizingInProgress);
158  const bool consumed = mouseMoveEvent(mouseEvent);
159  m_resizingInProgress = state;
160  return consumed;
161  }
162  default:
163  break;
164  }
165  return false;
166 }
167 
168 bool WidgetResizeHandler::mouseMoveEvent(QMouseEvent *e)
169 {
170  const QPoint globalPos = Qt5Qt6Compat::eventGlobalPos(e);
171  if (!m_resizingInProgress) {
172  const CursorPosition pos = cursorPosition(globalPos);
173  updateCursor(pos);
174  return pos != CursorPosition_Undefined;
175  }
176 
177  const QRect oldGeometry = KDDockWidgets::globalGeometry(mTarget);
178  QRect newGeometry = oldGeometry;
179 
180  QRect parentGeometry;
181  if (!mTarget->isTopLevel()) {
182  auto parent = KDDockWidgets::Private::parentWidget(mTarget);
183  parentGeometry = KDDockWidgets::globalGeometry(parent);
184  }
185 
186  {
187  int deltaWidth = 0;
188  int newWidth = 0;
189  const int maxWidth = Layouting::Widget::widgetMaxSize(mTarget).width();
190  const int minWidth = Layouting::Widget::widgetMinSize(mTarget).width();
191 
192  switch (mCursorPos) {
194  case CursorPosition_Left:
196  parentGeometry = parentGeometry.adjusted(0, m_resizeGap, 0, 0);
197  deltaWidth = oldGeometry.left() - globalPos.x();
198  newWidth = qBound(minWidth, mTarget->width() + deltaWidth, maxWidth);
199  deltaWidth = newWidth - mTarget->width();
200  if (deltaWidth != 0) {
201  newGeometry.setLeft(newGeometry.left() - deltaWidth);
202  }
203 
204  break;
205  }
206 
210  parentGeometry = parentGeometry.adjusted(0, 0, -m_resizeGap, 0);
211  deltaWidth = globalPos.x() - newGeometry.right();
212  newWidth = qBound(minWidth, mTarget->width() + deltaWidth, maxWidth);
213  deltaWidth = newWidth - mTarget->width();
214  if (deltaWidth != 0) {
215  newGeometry.setRight(oldGeometry.right() + deltaWidth);
216  }
217  break;
218  }
219  default:
220  break;
221  }
222  }
223 
224  {
225  const int maxHeight = Layouting::Widget::widgetMaxSize(mTarget).height();
226  const int minHeight = Layouting::Widget::widgetMinSize(mTarget).height();
227  int deltaHeight = 0;
228  int newHeight = 0;
229  switch (mCursorPos) {
231  case CursorPosition_Top:
233  parentGeometry = parentGeometry.adjusted(0, m_resizeGap, 0, 0);
234  deltaHeight = oldGeometry.top() - globalPos.y();
235  newHeight = qBound(minHeight, mTarget->height() + deltaHeight, maxHeight);
236  deltaHeight = newHeight - mTarget->height();
237  if (deltaHeight != 0) {
238  newGeometry.setTop(newGeometry.top() - deltaHeight);
239  }
240 
241  break;
242  }
243 
247  parentGeometry = parentGeometry.adjusted(0, 0, 0, -m_resizeGap);
248  deltaHeight = globalPos.y() - newGeometry.bottom();
249  newHeight = qBound(minHeight, mTarget->height() + deltaHeight, maxHeight);
250  deltaHeight = newHeight - mTarget->height();
251  if (deltaHeight != 0) {
252  newGeometry.setBottom(oldGeometry.bottom() + deltaHeight);
253  }
254  break;
255  }
256  default:
257  break;
258  }
259  }
260 
261  if (newGeometry == mTarget->geometry()) {
262  // Nothing to do.
263  return true;
264  }
265 
266  if (!mTarget->isTopLevel()) {
267 
268  // Clip to parent's geometry.
269  newGeometry = newGeometry.intersected(parentGeometry);
270 
271  // Back to local.
272  newGeometry.moveTopLeft(mTarget->mapFromGlobal(newGeometry.topLeft()) + mTarget->pos());
273  }
274 
275  mTarget->setGeometry(newGeometry);
276  return true;
277 }
278 
279 #ifdef Q_OS_WIN
280 
282 bool WidgetResizeHandler::handleWindowsNativeEvent(FloatingWindow *fw, const QByteArray &eventType,
283  void *message, Qt5Qt6Compat::qintptr *result)
284 {
285  if (eventType != "windows_generic_MSG")
286  return false;
287 
288  auto msg = static_cast<MSG *>(message);
289  if (msg->message == WM_NCHITTEST) {
290  if (DragController::instance()->isInClientDrag()) {
291  // There's a non-native drag going on.
292  *result = 0;
293  return false;
294  }
295 
296  const QRect htCaptionRect = fw->dragRect();
297  const bool ret = handleWindowsNativeEvent(fw->windowHandle(), msg, result, htCaptionRect);
298 
299  fw->setLastHitTest(*result);
300  return ret;
301  } else if (msg->message == WM_NCLBUTTONDBLCLK) {
302  if ((Config::self().flags() & Config::Flag_DoubleClickMaximizes)) {
303  return handleWindowsNativeEvent(fw->windowHandle(), msg, result, {});
304  } else {
305  // Let the title bar handle it. It will re-dock the window.
306  if (TitleBar *titleBar = fw->titleBar()) {
307  if (titleBar->isVisible()) { // can't be invisible afaik
308  titleBar->onDoubleClicked();
309  }
310  }
311 
312  return true;
313  }
314  }
315 
316  return handleWindowsNativeEvent(fw->windowHandle(), msg, result, {});
317 }
318 
319 bool WidgetResizeHandler::handleWindowsNativeEvent(QWindow *w, MSG *msg,
320  Qt5Qt6Compat::qintptr *result,
321  const NativeFeatures &features)
322 {
323  if (msg->message == WM_NCCALCSIZE && features.hasShadow()) {
324  *result = 0;
325  return true;
326  } else if (msg->message == WM_NCHITTEST && (features.hasResize() || features.hasDrag())) {
327  const int borderWidth = 8;
328  const bool hasFixedWidth = w->minimumWidth() == w->maximumWidth();
329  const bool hasFixedHeight = w->minimumHeight() == w->maximumHeight();
330 
331  *result = 0;
332  const int xPos = GET_X_LPARAM(msg->lParam);
333  const int yPos = GET_Y_LPARAM(msg->lParam);
334  RECT rect;
335  GetWindowRect(reinterpret_cast<HWND>(w->winId()), &rect);
336 
337  if (xPos >= rect.left && xPos <= rect.left + borderWidth && yPos <= rect.bottom && yPos >= rect.bottom - borderWidth && features.hasResize()) {
338  *result = HTBOTTOMLEFT;
339  } else if (xPos < rect.right && xPos >= rect.right - borderWidth && yPos <= rect.bottom && yPos >= rect.bottom - borderWidth && features.hasResize()) {
340  *result = HTBOTTOMRIGHT;
341  } else if (xPos >= rect.left && xPos <= rect.left + borderWidth && yPos >= rect.top && yPos <= rect.top + borderWidth && features.hasResize()) {
342  *result = HTTOPLEFT;
343  } else if (xPos <= rect.right && xPos >= rect.right - borderWidth && yPos >= rect.top && yPos < rect.top + borderWidth && features.hasResize()) {
344  *result = HTTOPRIGHT;
345  } else if (!hasFixedWidth && xPos >= rect.left && xPos <= rect.left + borderWidth && features.hasResize()) {
346  *result = HTLEFT;
347  } else if (!hasFixedHeight && yPos >= rect.top && yPos <= rect.top + borderWidth && features.hasResize()) {
348  *result = HTTOP;
349  } else if (!hasFixedHeight && yPos <= rect.bottom && yPos >= rect.bottom - borderWidth && features.hasResize()) {
350  *result = HTBOTTOM;
351  } else if (!hasFixedWidth && xPos <= rect.right && xPos >= rect.right - borderWidth && features.hasResize()) {
352  *result = HTRIGHT;
353  } else if (features.hasDrag()) {
354  const QPoint globalPosQt = QHighDpi::fromNativePixels(QPoint(xPos, yPos), w);
355  // htCaptionRect is the rect on which we allow for Windows to do a native drag
356  const QRect htCaptionRect = features.htCaptionRect;
357  if (globalPosQt.y() >= htCaptionRect.top() && globalPosQt.y() <= htCaptionRect.bottom() && globalPosQt.x() >= htCaptionRect.left() && globalPosQt.x() <= htCaptionRect.right()) {
358  if (!KDDockWidgets::inDisallowDragWidget(globalPosQt)) { // Just makes sure the mouse isn't over the close button, we don't allow drag in that case.
359  *result = HTCAPTION;
360  }
361  }
362  }
363 
364  return *result != 0;
365  } else if (msg->message == WM_NCLBUTTONDBLCLK && features.hasMaximize()) {
366  // By returning false we accept Windows native action, a maximize.
367  // We could also call titleBar->onDoubleClicked(); here which will maximize if Flag_DoubleClickMaximizes is set,
368  // but there's a bug in QWidget::showMaximized() on Windows when we're covering the native title bar, the window is maximized with an offset.
369  // So instead, use a native maximize which works well
370  return false;
371  } else if (msg->message == WM_GETMINMAXINFO) {
372  // Qt doesn't work well with windows that don't have title bar but have native frames.
373  // When maximized they go out of bounds and the title bar is clipped, so catch WM_GETMINMAXINFO
374  // and patch the size
375 
376  // According to microsoft docs it only works for the primary screen, but extrapolates for the others
378  if (!screen || w->screen() != screen) {
379  return false;
380  }
381 
382  DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
383 
384  const QRect availableGeometry = screen->availableGeometry();
385 
386  auto mmi = reinterpret_cast<MINMAXINFO *>(msg->lParam);
387  const qreal dpr = screen->devicePixelRatio();
388 
389  mmi->ptMaxSize.y = int(availableGeometry.height() * dpr);
390  mmi->ptMaxSize.x = int(availableGeometry.width() * dpr) - 1; // -1 otherwise it gets bogus size
391  mmi->ptMaxPosition.x = availableGeometry.x();
392  mmi->ptMaxPosition.y = availableGeometry.y();
393 
394  mmi->ptMinTrackSize.x = int(w->minimumWidth() * dpr);
395  mmi->ptMinTrackSize.y = int(w->minimumHeight() * dpr);
396 
397  *result = 0;
398  return true;
399  }
400 
401  return false;
402 }
403 
404 #endif
405 
406 void WidgetResizeHandler::setTarget(QWidgetOrQuick *w)
407 {
408  if (w) {
409  mTarget = w;
410  mTarget->setMouseTracking(true);
411  if (m_isTopLevelWindowResizer) {
412  mTarget->installEventFilter(this);
413  } else {
414  qApp->installEventFilter(this);
415  }
416  } else {
417  qWarning() << "Target widget is null!";
418  }
419 }
420 
421 void WidgetResizeHandler::updateCursor(CursorPosition m)
422 {
423 #ifdef KDDOCKWIDGETS_QTWIDGETS
424  //Need for updating cursor when we change child widget
425  const QObjectList children = mTarget->children();
426  for (int i = 0, total = children.size(); i < total; ++i) {
427  if (auto child = qobject_cast<WidgetType *>(children.at(i))) {
428 
429  if (!child->testAttribute(Qt::WA_SetCursor)) {
430  child->setCursor(Qt::ArrowCursor);
431  }
432  }
433  }
434 #endif
435 
436  switch (m) {
439  setMouseCursor(Qt::SizeFDiagCursor);
440  break;
443  setMouseCursor(Qt::SizeBDiagCursor);
444  break;
445  case CursorPosition_Top:
447  setMouseCursor(Qt::SizeVerCursor);
448  break;
449  case CursorPosition_Left:
451  setMouseCursor(Qt::SizeHorCursor);
452  break;
454  restoreMouseCursor();
455  break;
456  case CursorPosition_All:
459  // Doesn't happen
460  break;
461  }
462 }
463 
464 void WidgetResizeHandler::setMouseCursor(Qt::CursorShape cursor)
465 {
466  if (m_isTopLevelWindowResizer)
467  mTarget->setCursor(cursor);
468  else
469  qApp->setOverrideCursor(cursor);
470 }
471 
472 void WidgetResizeHandler::restoreMouseCursor()
473 {
474  if (m_isTopLevelWindowResizer)
475  mTarget->setCursor(Qt::ArrowCursor);
476  else
477  qApp->restoreOverrideCursor();
478 }
479 
480 CursorPosition WidgetResizeHandler::cursorPosition(QPoint globalPos) const
481 {
482  if (!mTarget)
484 
485 #ifdef KDDOCKWIDGETS_QTQUICK
486  if (isMDI()) {
487  // Special case for QtQuick. The MouseAreas are driving it and know better what's the
488  // cursor position
489  return CursorPosition(mTarget->property("cursorPosition").toInt());
490  }
491 #endif
492 
493  QPoint pos = mTarget->mapFromGlobal(globalPos);
494 
495  const int x = pos.x();
496  const int y = pos.y();
497  const int margin = widgetResizeHandlerMargin();
498 
500  if (qAbs(x) <= margin)
501  result |= CursorPosition_Left;
502  else if (qAbs(x - (mTarget->width() - margin)) <= margin)
503  result |= CursorPosition_Right;
504 
505  if (qAbs(y) <= margin)
506  result |= CursorPosition_Top;
507  else if (qAbs(y - (mTarget->height() - margin)) <= margin)
508  result |= CursorPosition_Bottom;
509 
510  // Filter out sides we don't allow
511  result = result & mAllowedResizeSides;
512 
513  return static_cast<CursorPosition>(result);
514 }
515 
517 void WidgetResizeHandler::setupWindow(QWindow *window)
518 {
519  // Does some minor setup on our QWindow.
520  // Like adding the drop shadow on Windows and two other workarounds.
521 
522 #if defined(Q_OS_WIN)
523  if (KDDockWidgets::usesAeroSnapWithCustomDecos()) {
524  const auto wid = HWND(window->winId());
525  connect(window, &QWindow::screenChanged, window, [wid] {
526  // Qt honors our frame hijacking usually... but when screen changes we must give it a
527  // nudge. Otherwise what Qt thinks is the client area is not what Windows knows it is.
528  // SetWindowPos() will trigger an NCCALCSIZE message, which Qt will intercept and take
529  // note of the margins we're using.
530  SetWindowPos(wid, 0, 0, 0, 0, 0,
531  SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
532  });
533 
534  const bool usesTransparentFloatingWindow =
535  Config::self().internalFlags() & Config::InternalFlag_UseTransparentFloatingWindow;
536  if (!usesTransparentFloatingWindow) {
537  // This enables the native drop shadow.
538  // Doesn't work well if the floating window has transparent round corners (shows weird white line).
539 
540  MARGINS margins = { 0, 0, 0, 1 }; // arbitrary, just needs to be > 0 it seems
541  DwmExtendFrameIntoClientArea(wid, &margins);
542  }
543  }
544 #else
545  Q_UNUSED(window);
546 #endif // Q_OS_WIN
547 }
548 
549 #ifdef Q_OS_WIN
550 bool WidgetResizeHandler::isInterestingNativeEvent(unsigned int nativeEvent)
551 {
552  switch (nativeEvent) {
553  case WM_NCHITTEST:
554  case WM_NCCALCSIZE:
555  case WM_NCLBUTTONDBLCLK:
556  case WM_GETMINMAXINFO:
557  return true;
558  default:
559  return false;
560  }
561 }
562 #endif
563 
564 #if defined(Q_OS_WIN) && defined(KDDOCKWIDGETS_QTWIDGETS)
565 bool NCHITTESTEventFilter::nativeEventFilter(const QByteArray &eventType, void *message,
566  Qt5Qt6Compat::qintptr *result)
567 
568 {
569  if (eventType != "windows_generic_MSG" || !m_floatingWindow)
570  return false;
571 
572  auto msg = static_cast<MSG *>(message);
573  if (msg->message != WM_NCHITTEST)
574  return false;
575  const WId wid = WId(msg->hwnd);
576 
577  QWidget *child = QWidget::find(wid);
578  if (!child || child->window() != m_floatingWindow)
579  return false;
580  const bool isThisWindow = child == m_floatingWindow;
581 
582  if (!isThisWindow) {
583  *result = HTTRANSPARENT;
584  return true;
585  }
586 
587  return false;
588 }
589 #endif
590 
591 
592 CustomFrameHelper::CustomFrameHelper(ShouldUseCustomFrame func, QObject *parent)
593  : QObject(parent)
595  , m_shouldUseCustomFrameFunc(func)
596 {
597 #ifdef Q_OS_WIN
598  qApp->installNativeEventFilter(this);
599 #endif
600 }
601 
602 CustomFrameHelper::~CustomFrameHelper()
603 {
604  m_inDtor = true;
605 }
606 
607 void CustomFrameHelper::applyCustomFrame(QWindow *window)
608 {
609 #ifdef Q_OS_WIN
610  WidgetResizeHandler::setupWindow(window);
611 #else
612  Q_UNUSED(window);
613  qWarning() << Q_FUNC_INFO << "Not implemented on this platform";
614 #endif
615 }
616 
617 bool CustomFrameHelper::nativeEventFilter(const QByteArray &eventType, void *message,
618  Qt5Qt6Compat::qintptr *result)
619 {
620  if (m_shouldUseCustomFrameFunc == nullptr || m_recursionGuard)
621  return false;
622 
623  QScopedValueRollback<bool> guard(m_recursionGuard, true);
624 
625 #ifdef Q_OS_WIN
626  if (m_inDtor || !KDDockWidgets::usesAeroSnapWithCustomDecos())
627  return false;
628 
629  if (eventType != "windows_generic_MSG")
630  return false;
631 
632  auto msg = static_cast<MSG *>(message);
633  if (!WidgetResizeHandler::isInterestingNativeEvent(msg->message)) {
634  // Save some CPU cycles
635  return false;
636  }
637 
638  QWindow *window = DockRegistry::self()->windowForHandle(WId(msg->hwnd));
639  if (!window)
640  return false;
641 
642  const WidgetResizeHandler::NativeFeatures features = m_shouldUseCustomFrameFunc(window);
643  if (!features.hasFeatures()) {
644  // No native support for is desired for this window
645  return false;
646  }
647 
648  const char *propertyName = "kddw_customframe_setup_ran";
649  const bool setupRan = window->property(propertyName).toBool();
650  if (!setupRan) {
651  // Add drop shadow
652  WidgetResizeHandler::setupWindow(window);
653  window->setProperty(propertyName, true);
654  }
655 
656  return WidgetResizeHandler::handleWindowsNativeEvent(window, msg, result, features);
657 #else
658  Q_UNUSED(eventType);
659  Q_UNUSED(message);
660  Q_UNUSED(result);
661  return false;
662 #endif
663 }
Layouting::Widget::widgetMaxSize
static QSize widgetMaxSize(const T *w)
Definition: Widget.h:164
QRect::moveTopLeft
void moveTopLeft(const QPoint &position)
QWidget::window
QWidget * window() const const
Layouting::Widget::widgetMinSize
static QSize widgetMinSize(const T *w)
Definition: Widget.h:152
QEvent::MouseButtonPress
MouseButtonPress
KDDockWidgets::CursorPosition_All
@ CursorPosition_All
Definition: KDDockWidgets.h:252
QRect::topLeft
QPoint topLeft() const const
QScreen::availableGeometry
availableGeometry
QRect
QRect::right
int right() const const
QGuiApplication::primaryScreen
primaryScreen
KDDockWidgets::CursorPosition_TopRight
@ CursorPosition_TopRight
Definition: KDDockWidgets.h:247
Layouting::Config::self
static Config & self()
returns the singleton Config instance
Definition: MultiSplitterConfig.cpp:44
QWindow
QWidget
KDDockWidgets::CursorPosition
CursorPosition
Definition: KDDockWidgets.h:240
QRect::width
int width() const const
QRect::x
int x() const const
QRect::y
int y() const const
QWindow::maximumWidth
maximumWidth
QPoint::x
int x() const const
QPoint::y
int y() const const
QSize::width
int width() const const
QRect::intersected
QRect intersected(const QRect &rectangle) const const
KDDockWidgets::CursorPosition_Left
@ CursorPosition_Left
Definition: KDDockWidgets.h:242
QRect::contains
bool contains(const QRect &rectangle, bool proper) const const
KDDockWidgets::CursorPosition_Bottom
@ CursorPosition_Bottom
Definition: KDDockWidgets.h:245
Qt::LeftButton
LeftButton
KDDockWidgets::CursorPosition_Undefined
@ CursorPosition_Undefined
Definition: KDDockWidgets.h:241
QMouseEvent
QRect::left
int left() const const
QFlags
QScreen
KDDockWidgets::CursorPosition_Vertical
@ CursorPosition_Vertical
Definition: KDDockWidgets.h:251
QRect::setRight
void setRight(int x)
KDDockWidgets::CursorPosition_TopLeft
@ CursorPosition_TopLeft
Definition: KDDockWidgets.h:246
QRect::bottom
int bottom() const const
QRect::top
int top() const const
QWindow::minimumHeight
minimumHeight
QObject
QSize::height
int height() const const
QRect::setBottom
void setBottom(int y)
KDDockWidgets::CursorPosition_Horizontal
@ CursorPosition_Horizontal
Definition: KDDockWidgets.h:250
Qt::ArrowCursor
ArrowCursor
QWindow::winId
WId winId() const const
QWidget::find
QWidget * find(WId id)
QMargins
QVariant::toBool
bool toBool() const const
QWindow::screen
QScreen * screen() const const
QWidget::setMouseTracking
void setMouseTracking(bool enable)
QScreen::devicePixelRatio
devicePixelRatio
Config.h
Application-wide config to tune certain behaviours of the framework.
QObject::setProperty
bool setProperty(const char *name, const QVariant &value)
QWindow::screenChanged
void screenChanged(QScreen *screen)
QRect::setTop
void setTop(int y)
QRect::height
int height() const const
QEvent::type
QEvent::Type type() const const
QEvent
KDDockWidgets::CursorPosition_Right
@ CursorPosition_Right
Definition: KDDockWidgets.h:243
QRect::adjusted
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const const
KDDockWidgets
Definition: Config.cpp:36
QScopedValueRollback
QWindow::maximumHeight
maximumHeight
KDDockWidgets::CursorPosition_BottomRight
@ CursorPosition_BottomRight
Definition: KDDockWidgets.h:248
QAbstractNativeEventFilter
QRect::marginsAdded
QRect marginsAdded(const QMargins &margins) const const
QRect::setLeft
void setLeft(int x)
QWindow::minimumWidth
minimumWidth
Qt::WA_SetCursor
WA_SetCursor
KDDockWidgets::CursorPosition_BottomLeft
@ CursorPosition_BottomLeft
Definition: KDDockWidgets.h:249
QPoint
QByteArray
KDDockWidgets::CursorPosition_Top
@ CursorPosition_Top
Definition: KDDockWidgets.h:244
QObject::property
QVariant property(const char *name) const const

© 2019-2022 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated on Mon Mar 7 2022 02:01:21 for KDDockWidgets API Documentation by doxygen 1.8.20