6#include "private/qshortcut_p.h"
8#include "private/qwidget_p.h"
11#if QT_CONFIG(whatsthis)
12#include <qwhatsthis.h>
20#include <qapplication.h>
21#include <private/qapplication_p.h>
22#include <private/qshortcutmap_p.h>
24# include <private/qaction_p.h>
26#include <private/qwidgetwindow_p.h>
27#include <qpa/qplatformmenu.h>
31static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window);
32#if QT_CONFIG(graphicsview)
33static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window);
36static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window);
41
42
43
46 Q_ASSERT_X(object,
"QShortcutMap",
"Shortcut has no owner. Illegal map state!");
48 QWidget *active_window = QApplication::activeWindow();
53 if (QApplication::activePopupWidget())
54 active_window = QApplication::activePopupWidget();
57 QWindow *qwindow = QGuiApplication::focusWindow();
58 if (qwindow && qwindow->isActive()) {
60 if (
auto widgetWindow = qobject_cast<QWidgetWindow *>(qwindow)) {
61 active_window = widgetWindow->widget();
64 qwindow = qwindow->parent();
70 if (
auto a = qobject_cast<QAction *>(object))
71 return correctActionContext(context, a, active_window);
74#if QT_CONFIG(graphicsview)
75 if (
auto gw = qobject_cast<QGraphicsWidget *>(object))
76 return correctGraphicsWidgetContext(context, gw, active_window);
79 auto w = qobject_cast<QWidget *>(object);
81 if (
auto s = qobject_cast<QShortcut *>(object))
82 w = qobject_cast<QWidget *>(s->parent());
86 auto qwindow = qobject_cast<QWindow *>(object);
88 if (
auto widget_window = qobject_cast<QWidgetWindow *>(qwindow)) {
89 w = widget_window->widget();
92 qwindow = qwindow->parent();
97 return correctWidgetContext(context, w, active_window);
99 return QShortcutPrivate::simpleContextMatcher(object, context);
107 bool visible = w->isVisible();
108#if QT_CONFIG(menubar)
109 if (
auto menuBar = qobject_cast<QMenuBar *>(w)) {
110 if (
auto *pmb = menuBar->platformMenuBar()) {
111 if (menuBar->parentWidget()) {
114 if (
auto *ww = qobject_cast<QWidgetWindow *>(pmb->parentWindow()))
123 if (!visible || !w->isEnabled())
126 if (context == Qt::ApplicationShortcut)
127 return QApplicationPrivate::tryModalHelper(w,
nullptr);
129 if (context == Qt::WidgetShortcut)
130 return w == QApplication::focusWidget();
132 if (context == Qt::WidgetWithChildrenShortcut) {
133 const QWidget *tw = QApplication::focusWidget();
134 while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup || tw->windowType() == Qt::SubWindow))
135 tw = tw->parentWidget();
140 QWidget *tlw = w->window();
141#if QT_CONFIG(graphicsview)
142 if (
auto topData =
static_cast<QWidgetPrivate *>(QObjectPrivate::get(tlw))->extra.get()) {
143 if (topData->proxyWidget) {
144 bool res = correctGraphicsWidgetContext(context, topData->proxyWidget, active_window);
150 if (active_window && active_window != tlw) {
152
153
154 if (active_window->windowType() == Qt::Tool && active_window->parentWidget()) {
155 active_window = active_window->parentWidget()->window();
156 }
else if (active_window->windowType() == Qt::Popup && active_window->focusProxy()) {
157 active_window = active_window->focusProxy()->window();
161 if (active_window != tlw) {
162#if QT_CONFIG(menubar)
166 if (!qobject_cast<QMenuBar *>(tlw))
172
173 const QWidget* sw = w;
174 while (sw && !(sw->windowType() == Qt::SubWindow) && !sw->isWindow())
175 sw = sw->parentWidget();
176 if (sw && (sw->windowType() == Qt::SubWindow)) {
177 QWidget *focus_widget = QApplication::focusWidget();
178 while (focus_widget && focus_widget != sw)
179 focus_widget = focus_widget->parentWidget();
180 return sw == focus_widget;
183#if defined(DEBUG_QSHORTCUTMAP)
184 qDebug().nospace() <<
"..true [Pass-through]";
186 return QApplicationPrivate::tryModalHelper(w,
nullptr);
189#if QT_CONFIG(graphicsview)
190static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window)
195 bool visible = w->isVisible();
196#if defined(Q_OS_DARWIN) && QT_CONFIG(menubar)
197 if (!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
201 if (!visible || !w->isEnabled() || !w->scene())
204 if (context == Qt::ApplicationShortcut) {
208 const auto &views = w->scene()->views();
209 for (
auto view : views) {
210 if (QApplicationPrivate::tryModalHelper(view,
nullptr))
216 if (context == Qt::WidgetShortcut)
217 return static_cast<QGraphicsItem *>(w) == w->scene()->focusItem();
219 if (context == Qt::WidgetWithChildrenShortcut) {
220 const QGraphicsItem *ti = w->scene()->focusItem();
221 if (ti && ti->isWidget()) {
222 const auto *tw =
static_cast<
const QGraphicsWidget *>(ti);
223 while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup))
224 tw = tw->parentWidget();
233 const auto &views = w->scene()->views();
234 QGraphicsView *activeView =
nullptr;
235 for (
auto view : views) {
236 if (view->window() == active_window) {
246 QGraphicsWidget *a = w->scene()->activeWindow();
247 return !w->window() || a == w->window();
252static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window)
257 const QObjectList associatedObjects = a->associatedObjects();
258#if defined(DEBUG_QSHORTCUTMAP)
259 if (associatedObjects.isEmpty())
260 qDebug() << a <<
"not connected to any widgets; won't trigger";
262 for (
auto object : associatedObjects) {
264 if (
auto menu = qobject_cast<QMenu *>(object)) {
276 QPlatformMenu *pm = menu->platformMenu();
277 if (pm && !pm->isEnabled())
280 QAction *a = menu->menuAction();
281 if (a->isVisible() && a->isEnabled() && correctActionContext(context, a, active_window))
285 if (
auto widget = qobject_cast<QWidget*>(object)) {
286 if (correctWidgetContext(context, widget, active_window))
289#if QT_CONFIG(graphicsview)
290 else if (
auto graphicsWidget = qobject_cast<QGraphicsWidget*>(object)) {
291 if (correctGraphicsWidgetContext(context, graphicsWidget, active_window))
303 Q_DECLARE_PUBLIC(QShortcut)
308 {
return qWidgetShortcutContextMatcher; }
315#if QT_CONFIG(whatsthis)
316 if (QWhatsThis::inWhatsThisMode()) {
317 QWhatsThis::showText(QCursor::pos(), sc_whatsthis);
324QShortcutPrivate *QApplicationPrivate::createShortcutPrivate()
const
326 return new QtWidgetsShortcutPrivate;