Loading...
Searching...
No Matches
TopLevelWindowModel Class Reference

A model of top-level surfaces. More...

`#include <plugins/WindowManager/TopLevelWindowModel.h>`

## Public Types

enum | Roles { WindowRole = Qt::UserRole , ApplicationRole = Qt::UserRole + 1 }
| The Roles supported by the model. More...

## Signals

void | countChanged ()
void | inputMethodSurfaceChanged (lomiri::shell::application::MirSurfaceInterface *inputMethodSurface)
void | focusedWindowChanged (Window *focusedWindow)
void | listChanged ()
| Emitted when the list changes.
void | closedAllWindows ()
void | rootFocusChanged ()

## Public Member Functions

| TopLevelWindowModel (Workspace *workspace)
int | rowCount (const QModelIndex &parent=QModelIndex()) const override
QVariant | data (const QModelIndex &index, int role) const override
QHash< int, QByteArray > | roleNames () const override
lomiri::shell::application::MirSurfaceInterface * | inputMethodSurface () const
Window * | focusedWindow () const
int | nextId () const
Q_INVOKABLE lomiri::shell::application::MirSurfaceInterface * | surfaceAt (int index) const
| Returns the surface at the given index.
Q_INVOKABLE Window * | windowAt (int index) const
| Returns the window at the given index.
Q_INVOKABLE lomiri::shell::application::ApplicationInfoInterface * | applicationAt (int index) const
| Returns the application at the given index.
Q_INVOKABLE int | idAt (int index) const
| Returns the unique id of the element at the given index.
Q_INVOKABLE int | indexForId (int id) const
| Returns the index where the row with the given id is located.
Q_INVOKABLE void | raiseId (int id)
| Raises the row with the given id to the top of the window stack (index == count-1).
Q_INVOKABLE void | closeAllWindows ()
| Closes all windows, emits closedAllWindows when done.
Q_INVOKABLE void | pendingActivation ()
| Sets pending activation flag.
void | setApplicationManager (lomiri::shell::application::ApplicationManagerInterface *)
void | setSurfaceManager (lomiri::shell::application::SurfaceManagerInterface *)
void | setRootFocus (bool focus)
bool | rootFocus ()

## Properties

int | count
| Number of top-level surfaces in this model.
lomiri::shell::application::MirSurfaceInterface * | inputMethodSurface
| The input method surface, if any.
Window * | focusedWindow
| The currently focused window, if any.
int | nextId
bool | rootFocus
| Sets whether a user Window or "nothing" should be focused.

## Detailed Description

A model of top-level surfaces.

It's an abstraction of top-level application windows.

When an entry first appears, it normaly doesn't have a surface yet, meaning that the application is still starting up. A shell should then display a splash screen or saved screenshot of the application until its surface comes up.

As applications can have multiple surfaces and you can also have entries without surfaces at all, the only way to unambiguously refer to an entry in this model is through its id.

Definition at line 59 of file TopLevelWindowModel.h.

## Member Enumeration Documentation

## Roles

enum TopLevelWindowModel::Roles

The Roles supported by the model.

WindowRole - A Window. ApplicationRole - An ApplicationInfoInterface

Definition at line 116 of file TopLevelWindowModel.h.

{
WindowRole = Qt::UserRole,
ApplicationRole = Qt::UserRole + 1,
};

## Constructor & Destructor Documentation

## TopLevelWindowModel()

TopLevelWindowModel::TopLevelWindowModel | ( | Workspace * | workspace | ) |

Definition at line 43 of file TopLevelWindowModel.cpp.

: m_nullWindow(createWindow(nullptr)),
m_workspace(workspace),
m_surfaceManagerBusy(false)
{
connect(WindowManagerObjects::instance(), &WindowManagerObjects::applicationManagerChanged,
this, &TopLevelWindowModel::setApplicationManager);
connect(WindowManagerObjects::instance(), &WindowManagerObjects::surfaceManagerChanged,
this, &TopLevelWindowModel::setSurfaceManager);
setApplicationManager(WindowManagerObjects::instance()->applicationManager());
setSurfaceManager(WindowManagerObjects::instance()->surfaceManager());
connect(m_nullWindow, &Window::focusedChanged, this, [this] {
Q_EMIT rootFocusChanged();
});
}

## ~TopLevelWindowModel()

TopLevelWindowModel::~TopLevelWindowModel | ( |  | ) |

Definition at line 61 of file TopLevelWindowModel.cpp.

{
}

## Member Function Documentation

## applicationAt()

lomiriapi::ApplicationInfoInterface * TopLevelWindowModel::applicationAt | ( | int | index | ) | const

Returns the application at the given index.

Definition at line 703 of file TopLevelWindowModel.cpp.

{
if (index >=0 && index < m_windowModel.count()) {
return m_windowModel[index].application;
} else {
return nullptr;
}
}

## closeAllWindows()

void TopLevelWindowModel::closeAllWindows | ( |  | ) |

Closes all windows, emits closedAllWindows when done.

Definition at line 892 of file TopLevelWindowModel.cpp.

{
m_closingAllApps = true;
for (auto win : m_windowModel) {
win.window->close();
}
// This is done after the for loop in the unlikely event that
// an app starts in between this
if (m_windowModel.isEmpty()) {
Q_EMIT closedAllWindows();
}
}

## data()

QVariant TopLevelWindowModel::data | ( | const QModelIndex & | index,
|  | int | role ) const

override

Definition at line 630 of file TopLevelWindowModel.cpp.

{
if (index.row() < 0 || index.row() >= m_windowModel.size())
return QVariant();
if (role == WindowRole) {
Window *window = m_windowModel.at(index.row()).window;
return QVariant::fromValue(window);
} else if (role == ApplicationRole) {
return QVariant::fromValue(m_windowModel.at(index.row()).application);
} else {
return QVariant();
}
}

## focusedWindow()

Window * TopLevelWindowModel::focusedWindow | ( |  | ) | const

Definition at line 778 of file TopLevelWindowModel.cpp.

{
return m_focusedWindow;
}

## idAt()

int TopLevelWindowModel::idAt | ( | int | index | ) | const

Returns the unique id of the element at the given index.

Definition at line 712 of file TopLevelWindowModel.cpp.

{
if (index >=0 && index < m_windowModel.count()) {
return m_windowModel[index].window->id();
} else {
return 0;
}
}

## indexForId()

int TopLevelWindowModel::indexForId | ( | int | id | ) | const

Returns the index where the row with the given id is located.

Returns -1 if there's no row with the given id.

Definition at line 675 of file TopLevelWindowModel.cpp.

{
for (int i = 0; i < m_windowModel.count(); ++i) {
if (m_windowModel[i].window->id() == id) {
return i;
}
}
return -1;
}

## inputMethodSurface()

lomiriapi::MirSurfaceInterface * TopLevelWindowModel::inputMethodSurface | ( |  | ) | const

Definition at line 773 of file TopLevelWindowModel.cpp.

{
return m_inputMethodWindow ? m_inputMethodWindow->surface() : nullptr;
}

## listChanged

void TopLevelWindowModel::listChanged | ( |  | ) |

signal

Emitted when the list changes.

Emitted when model gains an element, loses an element or when elements exchange positions.

## nextId()

int TopLevelWindowModel::nextId | ( |  | ) | const

inline

Definition at line 139 of file TopLevelWindowModel.h.

{ return m_nextId.loadRelaxed(); }

## pendingActivation()

void TopLevelWindowModel::pendingActivation | ( |  | ) |

Sets pending activation flag.

Definition at line 944 of file TopLevelWindowModel.cpp.

{
m_pendingActivation = true;
}

## raiseId()

void TopLevelWindowModel::raiseId | ( | int | id | ) |

Raises the row with the given id to the top of the window stack (index == count-1).

Definition at line 721 of file TopLevelWindowModel.cpp.

{
if (m_modelState == IdleState) {
DEBUG_MSG << "(id=" << id << ") - do it now.";
doRaiseId(id);
} else {
DEBUG_MSG << "(id=" << id << ") - Model busy (modelState=" << m_modelState << "). Try again in the next event loop.";
// The model has just signalled some change. If we have a Repeater responding to this update, it will get nuts
// if we perform yet another model change straight away.
//
// A bad sympton of this problem is a Repeater.itemAt(index) call returning null event though Repeater.count says
// the index is definitely within bounds.
QMetaObject::invokeMethod(this, "raiseId", Qt::QueuedConnection, Q_ARG(int, id));
}
}

## roleNames()

QHash< int, QByteArray > TopLevelWindowModel::roleNames | ( |  | ) | const

inline override

Definition at line 127 of file TopLevelWindowModel.h.

{
QHash<int, QByteArray> roleNames { {WindowRole, "window"},
{ApplicationRole, "application"} };
return roleNames;
}

## rowCount()

int TopLevelWindowModel::rowCount | ( | const QModelIndex & | parent = QModelIndex() | ) | const

override

Definition at line 625 of file TopLevelWindowModel.cpp.

{
return m_windowModel.count();
}

## setApplicationManager()

void TopLevelWindowModel::setApplicationManager | ( | lomiri::shell::application::ApplicationManagerInterface * |  | ) |

Definition at line 65 of file TopLevelWindowModel.cpp.

{
if (m_applicationManager == value) {
return;
}
DEBUG_MSG << "(" << value << ")";
Q_ASSERT(m_modelState == IdleState);
m_modelState = ResettingState;
beginResetModel();
if (m_applicationManager) {
disconnect(m_applicationManager, 0, this, 0);
}
m_applicationManager = value;
if (m_applicationManager) {
connect(m_applicationManager, &QAbstractItemModel::rowsInserted,
this, [this](const QModelIndex &/*parent*/, int first, int last) {
if (!m_workspace || !m_workspace->isActive())
return;
for (int i = first; i <= last; ++i) {
auto application = m_applicationManager->get(i);
addApplication(application);
}
});
connect(m_applicationManager, &QAbstractItemModel::rowsAboutToBeRemoved,
this, [this](const QModelIndex &/*parent*/, int first, int last) {
for (int i = first; i <= last; ++i) {
auto application = m_applicationManager->get(i);
removeApplication(application);
}
});
}
refreshWindows();
endResetModel();
m_modelState = IdleState;
}

## setRootFocus()

void TopLevelWindowModel::setRootFocus | ( | bool | focus | ) |

Definition at line 911 of file TopLevelWindowModel.cpp.

{
DEBUG_MSG << "(" << focus << "), surfaceManagerBusy is " << m_surfaceManagerBusy;
if (m_surfaceManagerBusy) {
// Something else is probably being focused already, let's not add to
// the noise.
return;
}
if (focus) {
// Give focus back to previous focused window, only if null window is focused.
// If null window is not focused, a different app had taken the focus and we
// should repect that, or if a pendingActivation is going on.
if (m_previousWindow && !m_previousWindow->focused() && !m_pendingActivation &&
m_nullWindow == m_focusedWindow && m_previousWindow != m_nullWindow) {
m_previousWindow->activate();
} else if (!m_pendingActivation) {
// The previous window does not exist any more, focus top window.
activateTopMostWindowWithoutId(-1);
}
} else {
if (!m_nullWindow->focused()) {
m_nullWindow->activate();
}
}
}

## setSurfaceManager()

void TopLevelWindowModel::setSurfaceManager | ( | lomiri::shell::application::SurfaceManagerInterface * |  | ) |

Definition at line 111 of file TopLevelWindowModel.cpp.

{
if (surfaceManager == m_surfaceManager) {
return;
}
DEBUG_MSG << "(" << surfaceManager << ")";
Q_ASSERT(m_modelState == IdleState);
m_modelState = ResettingState;
beginResetModel();
if (m_surfaceManager) {
disconnect(m_surfaceManager, 0, this, 0);
}
m_surfaceManager = surfaceManager;
if (m_surfaceManager) {
connect(m_surfaceManager, &lomiriapi::SurfaceManagerInterface::surfacesAddedToWorkspace, this, &TopLevelWindowModel::onSurfacesAddedToWorkspace);
connect(m_surfaceManager, &lomiriapi::SurfaceManagerInterface::surfacesRaised, this, &TopLevelWindowModel::onSurfacesRaised);
connect(m_surfaceManager, &lomiriapi::SurfaceManagerInterface::surfaceRemoved, this, &TopLevelWindowModel::onSurfaceDestroyed);
connect(m_surfaceManager, &lomiriapi::SurfaceManagerInterface::modificationsStarted, this, &TopLevelWindowModel::onModificationsStarted);
connect(m_surfaceManager, &lomiriapi::SurfaceManagerInterface::modificationsEnded, this, &TopLevelWindowModel::onModificationsEnded);
}
refreshWindows();
endResetModel();
m_modelState = IdleState;
}

## surfaceAt()

lomiriapi::MirSurfaceInterface * TopLevelWindowModel::surfaceAt | ( | int | index | ) | const

Returns the surface at the given index.

It will be a nullptr if the application is still starting up and thus hasn't yet created and drawn into a surface.

Same as windowAt(index).surface()

Definition at line 694 of file TopLevelWindowModel.cpp.

{
if (index >=0 && index < m_windowModel.count()) {
return m_windowModel[index].window->surface();
} else {
return nullptr;
}
}

## windowAt()

Window * TopLevelWindowModel::windowAt | ( | int | index | ) | const

Returns the window at the given index.

Will always be valid

Definition at line 685 of file TopLevelWindowModel.cpp.

{
if (index >=0 && index < m_windowModel.count()) {
return m_windowModel[index].window;
} else {
return nullptr;
}
}

## Property Documentation

## count

int TopLevelWindowModel::count

read

Number of top-level surfaces in this model.

This is the same as rowCount, added in order to keep compatibility with QML ListModels.

Definition at line 68 of file TopLevelWindowModel.h.

## focusedWindow

Window* TopLevelWindowModel::focusedWindow

read

The currently focused window, if any.

Definition at line 80 of file TopLevelWindowModel.h.

## inputMethodSurface

lomiri::shell::application::MirSurfaceInterface* TopLevelWindowModel::inputMethodSurface

read

The input method surface, if any.

The surface of a onscreen keyboard (akak "virtual keyboard") would be kept here and not in the model itself.

Definition at line 75 of file TopLevelWindowModel.h.

## nextId

int TopLevelWindowModel::nextId

read

The id to be used on the next entry created Useful for tests

Definition at line 86 of file TopLevelWindowModel.h.

## rootFocus

bool TopLevelWindowModel::rootFocus

read write

Sets whether a user Window or "nothing" should be focused.

This implementation of TLWM must have something focused. However, the user may wish to have nothing in some cases - for example, when they minimize all their windows on the desktop or unfocus the app they're using by clicking the background or indicators.

Unsetting rootFocus effectively focuses "nothing" by setting up a Window that has no displayable Surfaces and bringing it into focus.

Setting rootFocus attempts to focus the Window which was focused last - unless another app is attempting to gain focus (as determined by pendingActivation) and that's why we got rootFocus.

If the previously-focused Window was closed before rootFocus was set, the next available window will be focused.

Definition at line 107 of file TopLevelWindowModel.h.

The documentation for this class was generated from the following files:

- plugins/WindowManager/TopLevelWindowModel.h
- plugins/WindowManager/TopLevelWindowModel.cpp