Understand more about edge-based clients and act appropriately, passing
info along to kdesktop too. This is funky now :) svn path=/trunk/kdebase/kwin/; revision=48377
This commit is contained in:
parent
d19c42bd26
commit
297651e2c3
10 changed files with 275 additions and 165 deletions
|
@ -6,10 +6,12 @@ SUBDIRS = pics clients
|
|||
bin_PROGRAMS = kwin
|
||||
lib_LTLIBRARIES = kwin.la
|
||||
|
||||
kwin_la_SOURCES = atoms.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp plugins.cpp
|
||||
kwin_la_SOURCES = atoms.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp plugins.cpp KWinInterface.skel
|
||||
kwin_la_LIBADD = $(LIB_KDEUI)
|
||||
kwin_la_LDFLAGS = $(all_libraries) -module -avoid-version
|
||||
|
||||
include_HEADERS = KWinInterface.h
|
||||
|
||||
kwin_SOURCES = dummy.cpp
|
||||
kwin_LDADD = kwin.la
|
||||
kwin_LDFLAGS = $(all_libraries) $(KDE_RPATH) -export-dynamic -rdynamic
|
||||
|
|
123
client.cpp
123
client.cpp
|
@ -361,65 +361,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
if ( mainClient()->isSticky() )
|
||||
setSticky( TRUE );
|
||||
|
||||
// Find out if we should be avoided.
|
||||
|
||||
// If this atom isn't set, set it now.
|
||||
Atom avoidAtom = XInternAtom(qt_xdisplay(), "_NET_AVOID_SPEC", False);
|
||||
|
||||
XTextProperty avoidProp;
|
||||
|
||||
Status avoidStatus =
|
||||
XGetTextProperty(qt_xdisplay(), w, &avoidProp, avoidAtom);
|
||||
|
||||
if (0 != avoidStatus) {
|
||||
|
||||
qDebug("XGetTextProperty worked for atom _NET_AVOID_SPEC");
|
||||
|
||||
char ** avoidList;
|
||||
int avoidListCount;
|
||||
|
||||
Status convertStatus =
|
||||
XTextPropertyToStringList(&avoidProp, &avoidList, &avoidListCount);
|
||||
|
||||
if (0 != convertStatus) {
|
||||
|
||||
qDebug("XTextPropertyToStringList succeded");
|
||||
|
||||
avoid_ = true;
|
||||
|
||||
if (avoidListCount != 1) {
|
||||
qDebug("Extra values in avoidance list. Ignoring.");
|
||||
}
|
||||
|
||||
char * itemZero = avoidList[0];
|
||||
|
||||
qDebug("Anchoring to border %s", itemZero);
|
||||
|
||||
switch (*itemZero) {
|
||||
|
||||
case 'N':
|
||||
anchorEdge_ = AnchorNorth;
|
||||
break;
|
||||
case 'S':
|
||||
anchorEdge_ = AnchorSouth;
|
||||
break;
|
||||
case 'E':
|
||||
anchorEdge_ = AnchorEast;
|
||||
break;
|
||||
case 'W':
|
||||
anchorEdge_ = AnchorWest;
|
||||
break;
|
||||
default:
|
||||
anchorEdge_ = AnchorNorth;
|
||||
break;
|
||||
}
|
||||
|
||||
XFreeStringList(avoidList);
|
||||
|
||||
} else
|
||||
qDebug("XTextPropertyToStringList failed");
|
||||
|
||||
}
|
||||
updateAvoidPolicy();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1950,6 +1892,69 @@ QCString Client::sessionId()
|
|||
return result;
|
||||
}
|
||||
|
||||
void Client::updateAvoidPolicy()
|
||||
{
|
||||
// Find out if we should be avoided.
|
||||
|
||||
// If this atom isn't set, set it now.
|
||||
Atom avoidAtom = XInternAtom(qt_xdisplay(), "_NET_AVOID_SPEC", False);
|
||||
|
||||
XTextProperty avoidProp;
|
||||
|
||||
Status avoidStatus =
|
||||
XGetTextProperty(qt_xdisplay(), win, &avoidProp, avoidAtom);
|
||||
|
||||
if (0 != avoidStatus) {
|
||||
|
||||
qDebug("XGetTextProperty worked for atom _NET_AVOID_SPEC");
|
||||
|
||||
char ** avoidList;
|
||||
int avoidListCount;
|
||||
|
||||
Status convertStatus =
|
||||
XTextPropertyToStringList(&avoidProp, &avoidList, &avoidListCount);
|
||||
|
||||
if (0 != convertStatus) {
|
||||
|
||||
qDebug("XTextPropertyToStringList succeded");
|
||||
|
||||
avoid_ = true;
|
||||
|
||||
if (avoidListCount != 1) {
|
||||
qDebug("Extra values in avoidance list. Ignoring.");
|
||||
}
|
||||
|
||||
char * itemZero = avoidList[0];
|
||||
|
||||
qDebug("Anchoring to border %s", itemZero);
|
||||
|
||||
switch (*itemZero) {
|
||||
|
||||
case 'N':
|
||||
anchorEdge_ = AnchorNorth;
|
||||
break;
|
||||
case 'S':
|
||||
anchorEdge_ = AnchorSouth;
|
||||
break;
|
||||
case 'E':
|
||||
anchorEdge_ = AnchorEast;
|
||||
break;
|
||||
case 'W':
|
||||
anchorEdge_ = AnchorWest;
|
||||
break;
|
||||
default:
|
||||
avoid_ = false;
|
||||
break;
|
||||
}
|
||||
|
||||
XFreeStringList(avoidList);
|
||||
|
||||
} else
|
||||
qDebug("XTextPropertyToStringList failed");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
NoBorderClient::NoBorderClient( Workspace *ws, WId w, QWidget *parent, const char *name )
|
||||
: Client( ws, w, parent, name )
|
||||
{
|
||||
|
|
1
client.h
1
client.h
|
@ -63,6 +63,7 @@ public:
|
|||
bool isTransient() const;
|
||||
Client* mainClient();
|
||||
|
||||
void updateAvoidPolicy();
|
||||
bool avoid() const { return avoid_; }
|
||||
int anchorEdge() const { return anchorEdge_; }
|
||||
|
||||
|
|
|
@ -152,16 +152,7 @@ Manager::updateDisplay()
|
|||
void
|
||||
Manager::setShade(bool)
|
||||
{
|
||||
#if 0
|
||||
// Hmm. This does screwy things to the layout.
|
||||
if (b)
|
||||
resizeBar_->hide();
|
||||
else
|
||||
resizeBar_->show();
|
||||
#endif
|
||||
|
||||
// And this is screwed. My window ends up the wrong size when unshaded.
|
||||
// Client::setShade(b);
|
||||
// Wait for parent class version to work.
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -178,7 +169,6 @@ Manager::paintEvent(QPaintEvent * e)
|
|||
if (intersectsLeft || intersectsRight) {
|
||||
|
||||
QPainter p(this);
|
||||
// ??? p.setPen(options->color(Options::Frame, isActive()));
|
||||
p.setPen(Qt::black);
|
||||
|
||||
if (intersectsLeft)
|
||||
|
|
|
@ -2,12 +2,10 @@ This theme emulates the look and feel of the RISC OS 'window manager'.
|
|||
Actually, RISC OS doesn't have a window manager in the same way X
|
||||
does, but if you imagine it does, this is an emulation of that ;)
|
||||
|
||||
I've optimised it for speed, so you should find it quite nippy.
|
||||
Particularly the fact that the left and right borders are single-pixel
|
||||
gives a large speedup on my Matrox card when dragging windows.
|
||||
|
||||
I've requested save-under in the window decorations for that extra
|
||||
speed kick, plus double-buffered the title bar and resize bar.
|
||||
The look is obviously quite different, but coming anywhere close to
|
||||
the unique look of RISC OS would be quite blatantly obvious, so to
|
||||
avoid copyright issues, the look of this theme is unique. You may
|
||||
consider it to be RISC OS grown up ;)
|
||||
|
||||
Functions that will be implemented but are currently missing:
|
||||
Transparent resize.
|
||||
|
@ -49,9 +47,11 @@ Titlebar:
|
|||
|
||||
Left button: Raise, focus and move window
|
||||
|
||||
Middle button: Menu
|
||||
Middle button: Move window
|
||||
|
||||
Right button: Move window
|
||||
Right button: Menu
|
||||
Note: Buttons are this way around for compatibility with
|
||||
other kwin themes.
|
||||
|
||||
Button Three:
|
||||
|
||||
|
|
|
@ -88,6 +88,50 @@ TitleBar::~TitleBar()
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
TitleBar::resizeEvent(QResizeEvent * e)
|
||||
{
|
||||
int sizeProblem = 0;
|
||||
|
||||
if (width() < 80) sizeProblem = 3;
|
||||
else if (width() < 100) sizeProblem = 2;
|
||||
else if (width() < 120) sizeProblem = 1;
|
||||
|
||||
switch (sizeProblem) {
|
||||
|
||||
case 1:
|
||||
lower_ ->hide();
|
||||
iconify_ ->show();
|
||||
maximise_ ->hide();
|
||||
close_ ->show();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
lower_ ->hide();
|
||||
iconify_ ->hide();
|
||||
maximise_ ->hide();
|
||||
close_ ->show();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
lower_ ->hide();
|
||||
iconify_ ->hide();
|
||||
maximise_ ->hide();
|
||||
close_ ->hide();
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
lower_ ->show();
|
||||
iconify_ ->show();
|
||||
maximise_ ->show();
|
||||
close_ ->show();
|
||||
break;
|
||||
}
|
||||
|
||||
QWidget::resizeEvent(e);
|
||||
}
|
||||
|
||||
} // End namespace
|
||||
|
||||
// vim:ts=2:sw=2:tw=78
|
||||
|
|
|
@ -46,6 +46,10 @@ class TitleBar : public QWidget
|
|||
void updateText();
|
||||
void updateMaximise(bool);
|
||||
|
||||
protected:
|
||||
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
private:
|
||||
|
||||
LowerButton * lower_;
|
||||
|
|
|
@ -63,16 +63,17 @@ TitleText::mousePressEvent(QMouseEvent * e)
|
|||
switch (e->button()) {
|
||||
|
||||
case MidButton:
|
||||
client_->workspace()->clientPopup(client_)->popup(e->globalPos());
|
||||
clientPosToMousePos_ = e->globalPos() - client_->pos();
|
||||
break;
|
||||
|
||||
case LeftButton:
|
||||
clientPosToMousePos_ = e->globalPos() - client_->pos();
|
||||
client_->workspace()->raiseClient(client_);
|
||||
client_->workspace()->requestFocus(client_);
|
||||
break;
|
||||
|
||||
case RightButton:
|
||||
|
||||
clientPosToMousePos_ = e->globalPos() - client_->pos();
|
||||
client_->workspace()->clientPopup(client_)->popup(e->globalPos());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
102
workspace.cpp
102
workspace.cpp
|
@ -9,7 +9,10 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <klocale.h>
|
||||
#include <stdlib.h>
|
||||
#include <qwhatsthis.h>
|
||||
#include <qdatastream.h>
|
||||
#include <kwin.h>
|
||||
#include <kapp.h>
|
||||
#include <dcopclient.h>
|
||||
|
||||
#include "workspace.h"
|
||||
#include "client.h"
|
||||
|
@ -142,16 +145,40 @@ Client* Workspace::clientFactory( Workspace *ws, WId w )
|
|||
return(mgr.allocateClient(ws, w));
|
||||
}
|
||||
|
||||
// Rikkus: This class is too complex. It needs splitting further.
|
||||
// It's a nightmare to understand, especially with so few comments :(
|
||||
Workspace::Workspace( bool restore )
|
||||
: QObject (0, "workspace"),
|
||||
DCOPObject ("KWinInterface"),
|
||||
current_desktop (0),
|
||||
number_of_desktops(0),
|
||||
desktop_widget (0),
|
||||
desktop_client (0),
|
||||
active_client (0),
|
||||
should_get_focus (0),
|
||||
control_grab (false),
|
||||
tab_grab (false),
|
||||
mouse_emulation (false),
|
||||
tab_box (0),
|
||||
popup (0),
|
||||
desk_popup (0),
|
||||
keys (0),
|
||||
root (0)
|
||||
{
|
||||
root = qt_xrootwin();
|
||||
session.setAutoDelete( TRUE );
|
||||
|
||||
if ( restore )
|
||||
loadSessionInfo();
|
||||
loadSessionInfo();
|
||||
|
||||
(void) QApplication::desktop(); // trigger creation of desktop widget
|
||||
desktop_widget = new QWidget(0, "desktop_widget", Qt::WType_Desktop | Qt::WPaintUnclipped );
|
||||
|
||||
desktop_widget =
|
||||
new QWidget(
|
||||
0,
|
||||
"desktop_widget",
|
||||
Qt::WType_Desktop | Qt::WPaintUnclipped
|
||||
);
|
||||
|
||||
// select windowmanager privileges
|
||||
XSelectInput(qt_xdisplay(), root,
|
||||
|
@ -163,14 +190,23 @@ Workspace::Workspace( bool restore )
|
|||
);
|
||||
|
||||
int dummy;
|
||||
kwin_has_shape = XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy);
|
||||
kwin_has_shape =
|
||||
XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy);
|
||||
|
||||
// compatibility
|
||||
long data = 1;
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(), atoms->kwm_running, atoms->kwm_running, 32,
|
||||
PropModeAppend, (unsigned char*) &data, 1);
|
||||
|
||||
keys = 0;
|
||||
XChangeProperty(
|
||||
qt_xdisplay(),
|
||||
qt_xrootwin(),
|
||||
atoms->kwm_running,
|
||||
atoms->kwm_running,
|
||||
32,
|
||||
PropModeAppend,
|
||||
(unsigned char*) &data,
|
||||
1
|
||||
);
|
||||
|
||||
grabKey(XK_Tab, Mod1Mask);
|
||||
grabKey(XK_Tab, Mod1Mask | ShiftMask);
|
||||
grabKey(XK_Tab, ControlMask);
|
||||
|
@ -179,23 +215,11 @@ Workspace::Workspace( bool restore )
|
|||
|
||||
init();
|
||||
|
||||
control_grab = FALSE;
|
||||
tab_grab = FALSE;
|
||||
mouse_emulation = FALSE;
|
||||
tab_box = new TabBox( this );
|
||||
}
|
||||
|
||||
void Workspace::init()
|
||||
{
|
||||
tab_box = 0;
|
||||
active_client = 0;
|
||||
should_get_focus = 0;
|
||||
desktop_client = 0;
|
||||
current_desktop = 0;
|
||||
number_of_desktops = 0;
|
||||
popup = 0;
|
||||
desk_popup = 0;
|
||||
popup_client = 0;
|
||||
KConfig* config = KGlobal::config();
|
||||
config->setGroup("Desktops");
|
||||
if (!config->hasKey("NumberOfDesktops"))
|
||||
|
@ -2218,6 +2242,8 @@ Workspace::updateClientArea()
|
|||
|
||||
for (ClientList::ConstIterator it(clients.begin()); it != clients.end(); ++it)
|
||||
{
|
||||
(*it)->updateAvoidPolicy();
|
||||
|
||||
if ((*it)->avoid()) {
|
||||
|
||||
switch (AnchorEdge((*it)->anchorEdge())) {
|
||||
|
@ -2252,8 +2278,46 @@ Workspace::updateClientArea()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DCOPClient * client = kapp->dcopClient();
|
||||
|
||||
if (!client->isAttached())
|
||||
client->attach();
|
||||
|
||||
QByteArray param;
|
||||
QDataStream str(param, IO_WriteOnly);
|
||||
|
||||
str << clientArea_;
|
||||
|
||||
client->send("kdesktop", "KDesktopIface", "clientAreaUpdated(QRect)", param);
|
||||
|
||||
// Useful when you want to see whether the client area has been
|
||||
// updated correctly...
|
||||
// qDebug("clientArea now == l: %d, r: %d, t: %d, b: %d", clientArea_.left(), clientArea_.right(), clientArea_.top(), clientArea_.bottom());
|
||||
qDebug("clientArea now == l: %d, r: %d, t: %d, b: %d", clientArea_.left(), clientArea_.top(), clientArea_.right(), clientArea_.bottom());
|
||||
}
|
||||
|
||||
WId Workspace::rootWin() const
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
Client* Workspace::activeClient() const
|
||||
{
|
||||
return active_client;
|
||||
}
|
||||
|
||||
int Workspace::currentDesktop() const
|
||||
{
|
||||
return current_desktop;
|
||||
}
|
||||
|
||||
int Workspace::numberOfDesktops() const
|
||||
{
|
||||
return number_of_desktops;
|
||||
}
|
||||
|
||||
const ClientList& Workspace::stackingOrder() const
|
||||
{
|
||||
return stacking_order;
|
||||
}
|
||||
|
||||
|
|
127
workspace.h
127
workspace.h
|
@ -15,6 +15,8 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <X11/Xlib.h>
|
||||
#include "options.h"
|
||||
#include "plugins.h"
|
||||
#include "KWinInterface.h"
|
||||
|
||||
class Client;
|
||||
class TabBox;
|
||||
|
||||
|
@ -74,7 +76,7 @@ public:
|
|||
static bool noBorder( WId w );
|
||||
};
|
||||
|
||||
class Workspace : public QObject
|
||||
class Workspace : public QObject, virtual public KWinInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -94,7 +96,12 @@ public:
|
|||
|
||||
WId rootWin() const;
|
||||
|
||||
/**
|
||||
* Returns the active client, i.e. the client that has the focus (or None
|
||||
* if no client has the focus)
|
||||
*/
|
||||
Client* activeClient() const;
|
||||
|
||||
void setActiveClient( Client* );
|
||||
void activateClient( Client* );
|
||||
void requestFocus( Client* c);
|
||||
|
@ -106,7 +113,14 @@ public:
|
|||
|
||||
void clientHidden( Client* );
|
||||
|
||||
/**
|
||||
* Returns the current virtual desktop of this workspace
|
||||
*/
|
||||
int currentDesktop() const;
|
||||
|
||||
/**
|
||||
* Returns the number of virtual desktops of this workspace
|
||||
*/
|
||||
int numberOfDesktops() const;
|
||||
void setNumberOfDesktops( int n );
|
||||
|
||||
|
@ -118,6 +132,11 @@ public:
|
|||
Client* previousClient(Client*) const;
|
||||
Client* nextStaticClient(Client*) const;
|
||||
Client* previousStaticClient(Client*) const;
|
||||
|
||||
/**
|
||||
* Returns the list of clients sorted in stacking order, with topmost client
|
||||
* at the last position
|
||||
*/
|
||||
const ClientList& stackingOrder() const;
|
||||
|
||||
//#### TODO right layers as default
|
||||
|
@ -142,7 +161,12 @@ public:
|
|||
|
||||
SessionInfo* takeSessionInfo( Client* );
|
||||
|
||||
void updateClientArea();
|
||||
/**
|
||||
* When the area that is available for clients (that which is not
|
||||
* taken by windows like panels, the top-of-screen menu etc) may
|
||||
* have changed, this will recalculate the available space.
|
||||
*/
|
||||
virtual void updateClientArea();
|
||||
|
||||
public slots:
|
||||
void setCurrentDesktop( int new_desktop );
|
||||
|
@ -185,22 +209,8 @@ protected:
|
|||
|
||||
private:
|
||||
void init();
|
||||
KGlobalAccel *keys;
|
||||
void createKeybindings();
|
||||
WId root;
|
||||
ClientList clients;
|
||||
ClientList stacking_order;
|
||||
ClientList focus_chain;
|
||||
Client* active_client;
|
||||
bool control_grab;
|
||||
bool tab_grab;
|
||||
bool mouse_emulation;
|
||||
TabBox* tab_box;
|
||||
void freeKeyboard(bool pass);
|
||||
QGuardedPtr<Client> popup_client;
|
||||
QPopupMenu *popup;
|
||||
QPopupMenu *desk_popup;
|
||||
Client* should_get_focus;
|
||||
|
||||
void raiseTransientsOf( ClientList& safeset, Client* c );
|
||||
void lowerTransientsOf( ClientList& safeset, Client* c );
|
||||
|
@ -212,31 +222,59 @@ private:
|
|||
void deskCleanup(CleanupType);
|
||||
|
||||
void focusToNull();
|
||||
Client* desktop_client;
|
||||
int current_desktop;
|
||||
int number_of_desktops;
|
||||
Client* findClientWidthId( WId w ) const;
|
||||
|
||||
QWidget* desktop_widget;
|
||||
Client* findClientWidthId( WId w ) const;
|
||||
|
||||
void propagateClients( bool onlyStacking = FALSE);
|
||||
|
||||
DockWindowList dockwins;
|
||||
bool addDockwin( WId w );
|
||||
bool removeDockwin( WId w );
|
||||
void propagateDockwins();
|
||||
DockWindow findDockwin( WId w );
|
||||
|
||||
QList<SessionInfo> session;
|
||||
void loadSessionInfo();
|
||||
|
||||
//CT needed for cascading+
|
||||
struct CascadingInfo {
|
||||
QPoint pos;
|
||||
int col;
|
||||
int row;
|
||||
};
|
||||
|
||||
// ------------------
|
||||
|
||||
DockWindowList dockwins;
|
||||
|
||||
int current_desktop;
|
||||
int number_of_desktops;
|
||||
|
||||
QGuardedPtr<Client> popup_client;
|
||||
|
||||
void loadSessionInfo();
|
||||
|
||||
QWidget* desktop_widget;
|
||||
|
||||
QList<SessionInfo> session;
|
||||
QValueList<CascadingInfo> cci;
|
||||
|
||||
Client* desktop_client;
|
||||
Client* active_client;
|
||||
Client* should_get_focus;
|
||||
|
||||
ClientList clients;
|
||||
ClientList stacking_order;
|
||||
ClientList focus_chain;
|
||||
|
||||
bool control_grab;
|
||||
bool tab_grab;
|
||||
bool mouse_emulation;
|
||||
|
||||
TabBox* tab_box;
|
||||
|
||||
QPopupMenu *popup;
|
||||
QPopupMenu *desk_popup;
|
||||
|
||||
KGlobalAccel *keys;
|
||||
WId root;
|
||||
|
||||
// -cascading
|
||||
Atom kwm_command;
|
||||
|
||||
|
@ -245,43 +283,4 @@ private:
|
|||
QRect clientArea_;
|
||||
};
|
||||
|
||||
inline WId Workspace::rootWin() const
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the active client, i.e. the client that has the focus (or None if no
|
||||
client has the focus)
|
||||
*/
|
||||
inline Client* Workspace::activeClient() const
|
||||
{
|
||||
return active_client;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the current virtual desktop of this workspace
|
||||
*/
|
||||
inline int Workspace::currentDesktop() const
|
||||
{
|
||||
return current_desktop;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the number of virtual desktops of this workspace
|
||||
*/
|
||||
inline int Workspace::numberOfDesktops() const
|
||||
{
|
||||
return number_of_desktops;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the list of clients sorted in stacking order, with topmost client
|
||||
at the last position
|
||||
*/
|
||||
inline const ClientList& Workspace::stackingOrder() const
|
||||
{
|
||||
return stacking_order;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue