diff --git a/shell/macapplication.h b/shell/macapplication.h --- a/shell/macapplication.h +++ b/shell/macapplication.h @@ -11,6 +11,7 @@ #define _OKULAR_MACAPPLICATION_H_ #include +#include #include "shell.h" @@ -39,9 +40,15 @@ */ void setLastActiveShell(QWidget *, QWidget *widgetInFocus); + /** + * Updates the Dock menu with the list of currently opened windows. + */ + void updateDockMenu(); + private: QString m_serializedOptions; Shell *m_lastActiveShell; + QMenu *m_dockMenu; }; diff --git a/shell/macapplication.cpp b/shell/macapplication.cpp --- a/shell/macapplication.cpp +++ b/shell/macapplication.cpp @@ -13,6 +13,12 @@ MacApplication::MacApplication(int &argc, char **argv) : QApplication(argc, argv), m_lastActiveShell(nullptr) { + m_dockMenu = new QMenu(); + m_dockMenu -> setAsDockMenu(); + + // Update the Dock menu before showing it. + connect(m_dockMenu, &QMenu::aboutToShow, this, &MacApplication::updateDockMenu); + // Keep track of the last active Shell. connect(this, &QApplication::focusChanged, this, &MacApplication::setLastActiveShell); } @@ -44,3 +50,52 @@ } } } + +void MacApplication::updateDockMenu() { + + QWidgetList widgetList = allWidgets(); + QList actionList; + + for (auto it = widgetList.constBegin(), end = widgetList.constEnd(); it != end; ++it) { + QWidget *widget = *it; + if (widget -> isWindow() && widget -> windowType() != Qt::Desktop && widget -> isVisible()) { + QString title = widget -> windowTitle(); + + // Remove the " [*]" placeholder in Shell's title. + auto shell = dynamic_cast(widget); + if (shell) { + title.chop(4); + } + + // Create a new action and add it to the list. + auto action = new QAction(title, m_dockMenu); + if (widget -> isActiveWindow()) { + action -> setCheckable(true); + action -> setChecked(true); + } + connect(action, &QAction::triggered, + [=] { + if (widget -> isMinimized()) { + widget -> isMaximized() ? widget -> showMaximized() : widget -> showNormal(); + } + widget -> activateWindow(); + widget -> raise(); + }); + actionList.append(action); + } + } + + // Sort the titles in alphabetical order. + if (!actionList.isEmpty()) { + QCollator collator; + collator.setNumericMode(true); + std::stable_sort(actionList.begin(), actionList.end(), + [=] (const QAction *left, const QAction *right) { + return collator.compare(left->text(), right->text()) < 0; + }); + } + + // Replace the Dock list of windows with the new one. + m_dockMenu -> clear(); + m_dockMenu -> addActions(actionList); +}