1 | // Copyright (C) 2016 Dmitry Shachnev <mitya57@gmail.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 "qdbusmenubar_p.h" |
5 | #include "qdbusmenuregistrarproxy_p.h" |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | using namespace Qt::StringLiterals; |
10 | |
11 | /* note: do not change these to QStringLiteral; |
12 | we are unloaded before QtDBus is done using the strings. |
13 | */ |
14 | #define REGISTRAR_SERVICE "com.canonical.AppMenu.Registrar"_L1 |
15 | #define REGISTRAR_PATH "/com/canonical/AppMenu/Registrar"_L1 |
16 | |
17 | QDBusMenuBar::() |
18 | : QPlatformMenuBar() |
19 | , m_menu(new QDBusPlatformMenu()) |
20 | , m_menuAdaptor(new QDBusMenuAdaptor(m_menu)) |
21 | , m_windowId(0) |
22 | { |
23 | QDBusMenuItem::registerDBusTypes(); |
24 | connect(sender: m_menu, signal: &QDBusPlatformMenu::propertiesUpdated, |
25 | context: m_menuAdaptor, slot: &QDBusMenuAdaptor::ItemsPropertiesUpdated); |
26 | connect(sender: m_menu, signal: &QDBusPlatformMenu::updated, |
27 | context: m_menuAdaptor, slot: &QDBusMenuAdaptor::LayoutUpdated); |
28 | connect(sender: m_menu, signal: &QDBusPlatformMenu::popupRequested, |
29 | context: m_menuAdaptor, slot: &QDBusMenuAdaptor::ItemActivationRequested); |
30 | } |
31 | |
32 | QDBusMenuBar::() |
33 | { |
34 | unregisterMenuBar(); |
35 | delete m_menuAdaptor; |
36 | delete m_menu; |
37 | qDeleteAll(c: m_menuItems); |
38 | } |
39 | |
40 | QDBusPlatformMenuItem *QDBusMenuBar::(QPlatformMenu *) |
41 | { |
42 | if (!menu) |
43 | return nullptr; |
44 | quintptr tag = menu->tag(); |
45 | const auto it = m_menuItems.constFind(key: tag); |
46 | if (it != m_menuItems.cend()) { |
47 | return *it; |
48 | } else { |
49 | QDBusPlatformMenuItem *item = new QDBusPlatformMenuItem; |
50 | updateMenuItem(item, menu); |
51 | m_menuItems.insert(key: tag, value: item); |
52 | return item; |
53 | } |
54 | } |
55 | |
56 | void QDBusMenuBar::(QDBusPlatformMenuItem *item, QPlatformMenu *) |
57 | { |
58 | const QDBusPlatformMenu * = qobject_cast<const QDBusPlatformMenu *>(object: menu); |
59 | item->setText(ourMenu->text()); |
60 | item->setIcon(ourMenu->icon()); |
61 | item->setEnabled(ourMenu->isEnabled()); |
62 | item->setVisible(ourMenu->isVisible()); |
63 | item->setMenu(menu); |
64 | } |
65 | |
66 | void QDBusMenuBar::(QPlatformMenu *, QPlatformMenu *before) |
67 | { |
68 | QDBusPlatformMenuItem * = menuItemForMenu(menu); |
69 | QDBusPlatformMenuItem *beforeItem = menuItemForMenu(menu: before); |
70 | m_menu->insertMenuItem(menuItem, before: beforeItem); |
71 | m_menu->emitUpdated(); |
72 | } |
73 | |
74 | void QDBusMenuBar::(QPlatformMenu *) |
75 | { |
76 | QDBusPlatformMenuItem * = menuItemForMenu(menu); |
77 | m_menu->removeMenuItem(menuItem); |
78 | m_menu->emitUpdated(); |
79 | } |
80 | |
81 | void QDBusMenuBar::(QPlatformMenu *) |
82 | { |
83 | QDBusPlatformMenuItem * = menuItemForMenu(menu); |
84 | updateMenuItem(item: menuItem, menu); |
85 | } |
86 | |
87 | void QDBusMenuBar::handleReparent(QWindow *newParentWindow) |
88 | { |
89 | if (newParentWindow) { |
90 | unregisterMenuBar(); |
91 | m_windowId = newParentWindow->winId(); |
92 | registerMenuBar(); |
93 | } |
94 | } |
95 | |
96 | QPlatformMenu *QDBusMenuBar::(quintptr tag) const |
97 | { |
98 | QDBusPlatformMenuItem * = m_menuItems.value(key: tag); |
99 | if (menuItem) |
100 | return const_cast<QPlatformMenu *>(menuItem->menu()); |
101 | return nullptr; |
102 | } |
103 | |
104 | QPlatformMenu *QDBusMenuBar::() const |
105 | { |
106 | return new QDBusPlatformMenu; |
107 | } |
108 | |
109 | void QDBusMenuBar::() |
110 | { |
111 | static uint = 0; |
112 | |
113 | QDBusConnection connection = QDBusConnection::sessionBus(); |
114 | m_objectPath = QStringLiteral("/MenuBar/%1" ).arg(a: ++menuBarId); |
115 | if (!connection.registerObject(path: m_objectPath, object: m_menu)) |
116 | return; |
117 | |
118 | QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); |
119 | QDBusPendingReply<> r = registrar.RegisterWindow(windowId: m_windowId, menuObjectPath: QDBusObjectPath(m_objectPath)); |
120 | r.waitForFinished(); |
121 | if (r.isError()) { |
122 | qWarning(msg: "Failed to register window menu, reason: %s (\"%s\")" , |
123 | qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); |
124 | connection.unregisterObject(path: m_objectPath); |
125 | } |
126 | } |
127 | |
128 | void QDBusMenuBar::() |
129 | { |
130 | QDBusConnection connection = QDBusConnection::sessionBus(); |
131 | |
132 | if (m_windowId) { |
133 | QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); |
134 | QDBusPendingReply<> r = registrar.UnregisterWindow(windowId: m_windowId); |
135 | r.waitForFinished(); |
136 | if (r.isError()) |
137 | qWarning(msg: "Failed to unregister window menu, reason: %s (\"%s\")" , |
138 | qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); |
139 | } |
140 | |
141 | if (!m_objectPath.isEmpty()) |
142 | connection.unregisterObject(path: m_objectPath); |
143 | } |
144 | |
145 | QT_END_NAMESPACE |
146 | |
147 | #include "moc_qdbusmenubar_p.cpp" |
148 | |