Add focused window controls to top bar
Introduces a new `WindowControls` component in the desktop top bar with minimize, maximize/restore, and close actions for the focused window. `WindowService` now exposes focused-window presence/maximized state plus focused-window convenience actions to support this UI. Also extends Nebula UI with a reusable `NebulaToolTip`, keyboard/pressed-state support in `NebulaIconButton`, new window-control glyphs in `NebulaIcon`, and theme tokens for pressed/danger hover states, with CMake and README updates to register/document the new components.
This commit is contained in:
@@ -67,6 +67,11 @@ int WindowService::windowCount() const
|
||||
return m_model->count();
|
||||
}
|
||||
|
||||
bool WindowService::hasFocusedWindow() const
|
||||
{
|
||||
return !m_focusedWindowId.isEmpty();
|
||||
}
|
||||
|
||||
QString WindowService::focusedWindowId() const
|
||||
{
|
||||
return m_focusedWindowId;
|
||||
@@ -87,6 +92,11 @@ QString WindowService::focusedApplicationName() const
|
||||
return m_focusedApplicationName;
|
||||
}
|
||||
|
||||
bool WindowService::focusedWindowMaximized() const
|
||||
{
|
||||
return m_focusedWindowMaximized;
|
||||
}
|
||||
|
||||
bool WindowService::focusWindow(const QString &windowId)
|
||||
{
|
||||
return m_backend->focusWindow(parseWindowId(windowId));
|
||||
@@ -112,6 +122,38 @@ bool WindowService::minimizeWindow(const QString &windowId)
|
||||
return m_backend->minimizeWindow(parseWindowId(windowId));
|
||||
}
|
||||
|
||||
bool WindowService::minimizeFocusedWindow()
|
||||
{
|
||||
if (m_focusedWindowId.isEmpty())
|
||||
return false;
|
||||
return minimizeWindow(m_focusedWindowId);
|
||||
}
|
||||
|
||||
bool WindowService::toggleMaximizeFocusedWindow()
|
||||
{
|
||||
if (m_focusedWindowId.isEmpty())
|
||||
return false;
|
||||
|
||||
const bool restore = m_focusedWindowMaximized;
|
||||
const bool ok = restore ? restoreWindow(m_focusedWindowId)
|
||||
: maximizeWindow(m_focusedWindowId);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (m_focusedWindowMaximized == restore) {
|
||||
m_focusedWindowMaximized = !restore;
|
||||
emit focusChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowService::closeFocusedWindow()
|
||||
{
|
||||
if (m_focusedWindowId.isEmpty())
|
||||
return false;
|
||||
return closeWindow(m_focusedWindowId);
|
||||
}
|
||||
|
||||
bool WindowService::setWindowFloating(const QString &windowId, bool floating)
|
||||
{
|
||||
return m_backend->setWindowFloating(parseWindowId(windowId), floating);
|
||||
@@ -154,6 +196,7 @@ void WindowService::syncFromBackend()
|
||||
QString title;
|
||||
QString appId;
|
||||
QString appName;
|
||||
bool maximized = false;
|
||||
|
||||
if (const WindowInfo *focused = m_model->windowById(focusedId)) {
|
||||
if (!focused->minimized) {
|
||||
@@ -161,17 +204,20 @@ void WindowService::syncFromBackend()
|
||||
title = focused->title;
|
||||
appId = focused->appId.isEmpty() ? focused->windowClass : focused->appId;
|
||||
appName = focused->displayName;
|
||||
maximized = focused->maximized;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_focusedWindowId != windowId
|
||||
|| m_focusedWindowTitle != title
|
||||
|| m_focusedApplicationId != appId
|
||||
|| m_focusedApplicationName != appName) {
|
||||
|| m_focusedApplicationName != appName
|
||||
|| m_focusedWindowMaximized != maximized) {
|
||||
m_focusedWindowId = windowId;
|
||||
m_focusedWindowTitle = title;
|
||||
m_focusedApplicationId = appId;
|
||||
m_focusedApplicationName = appName;
|
||||
m_focusedWindowMaximized = maximized;
|
||||
emit focusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,12 @@ class WindowService : public QObject
|
||||
Q_PROPERTY(WindowModel *model READ model CONSTANT)
|
||||
Q_PROPERTY(WorkspaceModel *workspaceModel READ workspaceModel CONSTANT)
|
||||
Q_PROPERTY(int windowCount READ windowCount NOTIFY windowCountChanged)
|
||||
Q_PROPERTY(bool hasFocusedWindow READ hasFocusedWindow NOTIFY focusChanged)
|
||||
Q_PROPERTY(QString focusedWindowId READ focusedWindowId NOTIFY focusChanged)
|
||||
Q_PROPERTY(QString focusedWindowTitle READ focusedWindowTitle NOTIFY focusChanged)
|
||||
Q_PROPERTY(QString focusedApplicationId READ focusedApplicationId NOTIFY focusChanged)
|
||||
Q_PROPERTY(QString focusedApplicationName READ focusedApplicationName NOTIFY focusChanged)
|
||||
Q_PROPERTY(bool focusedWindowMaximized READ focusedWindowMaximized NOTIFY focusChanged)
|
||||
|
||||
public:
|
||||
enum SnapEdge {
|
||||
@@ -42,16 +44,21 @@ public:
|
||||
WorkspaceModel *workspaceModel() const;
|
||||
int windowCount() const;
|
||||
|
||||
bool hasFocusedWindow() const;
|
||||
QString focusedWindowId() const;
|
||||
QString focusedWindowTitle() const;
|
||||
QString focusedApplicationId() const;
|
||||
QString focusedApplicationName() const;
|
||||
bool focusedWindowMaximized() const;
|
||||
|
||||
Q_INVOKABLE bool focusWindow(const QString &windowId);
|
||||
Q_INVOKABLE bool closeWindow(const QString &windowId);
|
||||
Q_INVOKABLE bool maximizeWindow(const QString &windowId);
|
||||
Q_INVOKABLE bool restoreWindow(const QString &windowId);
|
||||
Q_INVOKABLE bool minimizeWindow(const QString &windowId);
|
||||
Q_INVOKABLE bool minimizeFocusedWindow();
|
||||
Q_INVOKABLE bool toggleMaximizeFocusedWindow();
|
||||
Q_INVOKABLE bool closeFocusedWindow();
|
||||
Q_INVOKABLE bool setWindowFloating(const QString &windowId, bool floating);
|
||||
Q_INVOKABLE bool moveWindow(const QString &windowId, int x, int y);
|
||||
Q_INVOKABLE bool resizeWindow(const QString &windowId, int width, int height);
|
||||
@@ -79,4 +86,5 @@ private:
|
||||
QString m_focusedWindowTitle;
|
||||
QString m_focusedApplicationId;
|
||||
QString m_focusedApplicationName;
|
||||
bool m_focusedWindowMaximized = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user