Skip to content

Commit

Permalink
Refactor Window Manager interaction (#2041)
Browse files Browse the repository at this point in the history
* TaskBar: forward declare

* TaskBar: new ILXQtTaskbarAbstractBackend

This is an abstract interface to operate windows
and workspaces

* ILXQtTaskbarAbstractBackend: add supportsAction() method

- Move WindowProperty enum to lxqttaskbartypes.h

* TaskBar: add X11 backend

* TaskBar: new LXQtTaskBarProxyModel

This model will manage the tasks shown

* TaskBar: use backend in LXQtTaskBar

* TaskBar: initial use of backend in LXQtTaskButton

* TaskBar: use backend for urgency hint

* TaskBar: use backend to set window layer

* TaskBar: use backend to close and raise window

Also use it to get window icon

* TaskBar: use backend to roll up (shade) windows

* TaskBar: use backend to minimize window

* TaskBar: use backend to de-maximize window

* TaskBar: use backend to get window state

* TaskBar: use backend to set window state

* TaskBar: port workspace usage to backend

* TaskBar: remove X11 specific includes in lxqttaskbutton.cpp

* TaskBar: remove X11 code from LXQtTaskBar and LXQtTaskGroup

* TaskBar: LXQtTaskButton remove X11 specific code

* TaskBar: set context menu parent

* LXQtPanel: rework calculatePopupWindowPos()

- Don't rely on global screen coordinates

- This will be needed for future Wayland port,
  Where we don't have global screen coordinates

- Keep compatible behavior on X11

* LXQtPanel: avoid QCursor::pos() usage

* ILXQtTaskbarAbstractBackend: new Geometry window property

This new window propery flag is needed to notify geometry changes

* Move ILXQtTaskbarAbstractBackend to panel directory

- It is now a global instance

* ILXQtTaskbarAbstractBackend: new isAreaOverlapped() method

* LXQtPanel: use less KX11Extras and more ILXQtTaskbarAbstractBackend

* ILXQtTaskbarAbstractBackend: add dummy implementation

This will be used to avoid crashing panel in case no backend could be
created.
A warning message will be printed in this case.

* LXQtMainMenu: indent header include

* ILXQtTaskbarAbstractBackend: new showDesktop() function

* ShowDesktop: use ILXQtTaskbarAbstractBackend

* DesktopSwitch: port to ILXQtTaskbarAbstractBackend

- Clarify desktop index range

* LXQtTaskbarConfiguration: port to ILXQtTaskBarAbstractBackend

* DesktopSwitchConfiguration: port to ILXQtTaskBarAbstractBackend TODO

TODO: this will disable changing desktop names

* TaskBar: consider initial windows

* DesktopSwitch: remove unused isWindowHighlightable()

* DesktopSwitch: show unsupported widget if backend does not have switch
capability

* ILXQtTaskbarAbstractBackend: add setDesktopLayout() function

- Use it in DesktopSwitch::settingsChanged()

* LXQtTaskbarX11Backend: fix re-add window after property changes

* LXQtTaskBarDummyBackend: fix compilation

* LXQtTaskBarPlugin: fix headers path

* Revert "LXQtPanel: rework calculatePopupWindowPos()"

This reverts commit b0e54b8.

* Removed `mDesktops` after rebasing

* Reverted X11 codes of `DesktopSwitchConfiguration::loadDesktopsNames`

---------

Co-authored-by: Tsu Jan <[email protected]>
  • Loading branch information
gfgit and tsujan authored Jun 6, 2024
1 parent d38db5f commit 5def5ac
Show file tree
Hide file tree
Showing 34 changed files with 1,961 additions and 634 deletions.
17 changes: 17 additions & 0 deletions panel/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
set(PROJECT lxqt-panel)

# TODO
add_subdirectory(backends)

set(PRIV_HEADERS
panelpluginsmodel.h
windownotifier.h
Expand All @@ -18,6 +21,12 @@ set(PRIV_HEADERS
config/configstyling.h
config/configpluginswidget.h
config/addplugindialog.h

backends/ilxqttaskbarabstractbackend.h
backends/lxqttaskbartypes.h

backends/lxqttaskbardummybackend.h
backends/xcb/lxqttaskbarbackend_x11.h
)

# using LXQt namespace in the public headers.
Expand All @@ -26,6 +35,9 @@ set(PUB_HEADERS
pluginsettings.h
ilxqtpanelplugin.h
ilxqtpanel.h

backends/ilxqttaskbarabstractbackend.h
backends/lxqttaskbartypes.h
)

set(SOURCES
Expand All @@ -45,6 +57,11 @@ set(SOURCES
config/configstyling.cpp
config/configpluginswidget.cpp
config/addplugindialog.cpp

backends/ilxqttaskbarabstractbackend.cpp

backends/lxqttaskbardummybackend.cpp
backends/xcb/lxqttaskbarbackend_x11.cpp
)

set(UI
Expand Down
1 change: 1 addition & 0 deletions panel/backends/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(xcb)
25 changes: 25 additions & 0 deletions panel/backends/ilxqttaskbarabstractbackend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "../panel/backends/ilxqttaskbarabstractbackend.h"


ILXQtTaskbarAbstractBackend::ILXQtTaskbarAbstractBackend(QObject *parent)
: QObject(parent)
{

}

void ILXQtTaskbarAbstractBackend::moveApplicationToPrevNextDesktop(WId windowId, bool next)
{
int count = getWorkspacesCount();
if (count <= 1)
return;

int targetWorkspace = getWindowWorkspace(windowId) + (next ? 1 : -1);

// Wrap around
if (targetWorkspace > count)
targetWorkspace = 1; //Ids are 1-based
else if (targetWorkspace < 1)
targetWorkspace = count;

setWindowOnWorkspace(windowId, targetWorkspace);
}
99 changes: 99 additions & 0 deletions panel/backends/ilxqttaskbarabstractbackend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#ifndef ILXQTTASKBARABSTRACTBACKEND_H
#define ILXQTTASKBARABSTRACTBACKEND_H

#include <QObject>

#include "lxqttaskbartypes.h"

class QIcon;
class QScreen;

class ILXQtTaskbarAbstractBackend : public QObject
{
Q_OBJECT

public:
explicit ILXQtTaskbarAbstractBackend(QObject *parent = nullptr);

// Backend
virtual bool supportsAction(WId windowId, LXQtTaskBarBackendAction action) const = 0;

// Windows
virtual bool reloadWindows() = 0;

virtual QVector<WId> getCurrentWindows() const = 0;

virtual QString getWindowTitle(WId windowId) const = 0;

virtual bool applicationDemandsAttention(WId windowId) const = 0;

virtual QIcon getApplicationIcon(WId windowId, int fallbackDevicePixels) const = 0;

virtual QString getWindowClass(WId windowId) const = 0;

virtual LXQtTaskBarWindowLayer getWindowLayer(WId windowId) const = 0;
virtual bool setWindowLayer(WId windowId, LXQtTaskBarWindowLayer layer) = 0;

virtual LXQtTaskBarWindowState getWindowState(WId windowId) const = 0;
virtual bool setWindowState(WId windowId, LXQtTaskBarWindowState state, bool set = true) = 0;

virtual bool isWindowActive(WId windowId) const = 0;
virtual bool raiseWindow(WId windowId, bool onCurrentWorkSpace) = 0;

virtual bool closeWindow(WId windowId) = 0;

virtual WId getActiveWindow() const = 0;

// Workspaces
// NOTE: indexes are 1-based, 0 means "Show on All desktops"
virtual int getWorkspacesCount() const = 0;
virtual QString getWorkspaceName(int idx) const = 0;

virtual int getCurrentWorkspace() const = 0;
virtual bool setCurrentWorkspace(int idx) = 0;

virtual int getWindowWorkspace(WId windowId) const = 0;
virtual bool setWindowOnWorkspace(WId windowId, int idx) = 0;

virtual void moveApplicationToPrevNextDesktop(WId windowId, bool next); // Default implementation
virtual void moveApplicationToPrevNextMonitor(WId windowId, bool next, bool raiseOnCurrentDesktop) = 0;

virtual bool isWindowOnScreen(QScreen *screen, WId windowId) const = 0;

virtual bool setDesktopLayout(Qt::Orientation orientation, int rows, int columns, bool rightToLeft) = 0;

// X11 Specific
virtual void moveApplication(WId windowId) = 0;
virtual void resizeApplication(WId windowId) = 0;

virtual void refreshIconGeometry(WId windowId, const QRect &geom) = 0;

// Panel internal
virtual bool isAreaOverlapped(const QRect& area) const = 0;

// Show Destop TODO: split in multiple interfeces, this is becoming big
// NOTE: KWindowSystem already has these functions
// However on Wayland they are only compatible with KWin
// because internally it uses org_kde_plasma_window_management protocol
// We make this virtual so it can be implemented also for other compositors
virtual bool isShowingDesktop() const = 0;
virtual bool showDesktop(bool value) = 0;

signals:
void reloaded();

// Windows
void windowAdded(WId windowId);
void windowRemoved(WId windowId);
void windowPropertyChanged(WId windowId, int prop);

// Workspaces
void workspacesCountChanged();
void workspaceNameChanged(int idx);
void currentWorkspaceChanged(int idx);

// TODO: needed?
void activeWindowChanged(WId windowId);
};

#endif // ILXQTTASKBARABSTRACTBACKEND_H
171 changes: 171 additions & 0 deletions panel/backends/lxqttaskbardummybackend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#include "lxqttaskbardummybackend.h"

#include <QIcon>

LXQtTaskBarDummyBackend::LXQtTaskBarDummyBackend(QObject *parent)
: ILXQtTaskbarAbstractBackend(parent)
{

}


/************************************************
* Windows function
************************************************/
bool LXQtTaskBarDummyBackend::supportsAction(WId, LXQtTaskBarBackendAction) const
{
return false;
}

bool LXQtTaskBarDummyBackend::reloadWindows()
{
return false;
}

QVector<WId> LXQtTaskBarDummyBackend::getCurrentWindows() const
{
return {};
}

QString LXQtTaskBarDummyBackend::getWindowTitle(WId) const
{
return QString();
}

bool LXQtTaskBarDummyBackend::applicationDemandsAttention(WId) const
{
return false;
}

QIcon LXQtTaskBarDummyBackend::getApplicationIcon(WId, int) const
{
return QIcon();
}

QString LXQtTaskBarDummyBackend::getWindowClass(WId) const
{
return QString();
}

LXQtTaskBarWindowLayer LXQtTaskBarDummyBackend::getWindowLayer(WId) const
{
return LXQtTaskBarWindowLayer::Normal;
}

bool LXQtTaskBarDummyBackend::setWindowLayer(WId, LXQtTaskBarWindowLayer)
{
return false;
}

LXQtTaskBarWindowState LXQtTaskBarDummyBackend::getWindowState(WId) const
{
return LXQtTaskBarWindowState::Normal;
}

bool LXQtTaskBarDummyBackend::setWindowState(WId, LXQtTaskBarWindowState, bool)
{
return false;
}

bool LXQtTaskBarDummyBackend::isWindowActive(WId) const
{
return false;
}

bool LXQtTaskBarDummyBackend::raiseWindow(WId, bool)
{
return false;
}

bool LXQtTaskBarDummyBackend::closeWindow(WId)
{
return false;
}

WId LXQtTaskBarDummyBackend::getActiveWindow() const
{
return 0;
}


/************************************************
* Workspaces
************************************************/
int LXQtTaskBarDummyBackend::getWorkspacesCount() const
{
return 1; // Fake 1 workspace
}

QString LXQtTaskBarDummyBackend::getWorkspaceName(int) const
{
return QString();
}

int LXQtTaskBarDummyBackend::getCurrentWorkspace() const
{
return 0;
}

bool LXQtTaskBarDummyBackend::setCurrentWorkspace(int)
{
return false;
}

int LXQtTaskBarDummyBackend::getWindowWorkspace(WId) const
{
return 0;
}

bool LXQtTaskBarDummyBackend::setWindowOnWorkspace(WId, int)
{
return false;
}

void LXQtTaskBarDummyBackend::moveApplicationToPrevNextMonitor(WId, bool, bool)
{
//No-op
}

bool LXQtTaskBarDummyBackend::isWindowOnScreen(QScreen *, WId) const
{
return false;
}

bool LXQtTaskBarDummyBackend::setDesktopLayout(Qt::Orientation, int, int, bool)
{
return false;
}

/************************************************
* X11 Specific
************************************************/
void LXQtTaskBarDummyBackend::moveApplication(WId)
{
//No-op
}

void LXQtTaskBarDummyBackend::resizeApplication(WId)
{
//No-op
}

void LXQtTaskBarDummyBackend::refreshIconGeometry(WId, QRect const &)
{
//No-op
}

bool LXQtTaskBarDummyBackend::isAreaOverlapped(const QRect &) const
{
return false;
}

bool LXQtTaskBarDummyBackend::isShowingDesktop() const
{
return false;
}

bool LXQtTaskBarDummyBackend::showDesktop(bool)
{
return false;
}

Loading

0 comments on commit 5def5ac

Please sign in to comment.