Skip to content

Commit

Permalink
make WindowInfo a QObject
Browse files Browse the repository at this point in the history
add a pixmapSerial property so hopefully damage events will be properly tracked
  • Loading branch information
rburchell committed Sep 17, 2011
1 parent a785bb9 commit 37aea3a
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 89 deletions.
14 changes: 7 additions & 7 deletions src/homewindowmonitor.cpp
Expand Up @@ -71,9 +71,9 @@ bool HomeWindowMonitor::handleXEvent(const XEvent& event)
QList<Window> windowOrder = windowStackingOrder();

if (numWindowStackingOrderReceivers > 0) {
QList<WindowInfo> windowStackingList;
foreach (Window window, windowOrder) {
windowStackingList.append(WindowInfo(window));
QList<WindowInfo *> windowStackingList;
foreach (Window wid, windowOrder) {
windowStackingList.append(WindowInfo::windowFor(wid));
}

emit windowStackingOrderChanged(windowStackingList);
Expand All @@ -85,8 +85,8 @@ bool HomeWindowMonitor::handleXEvent(const XEvent& event)
iter.toBack();
bool anyWindowSignalEmitted = false;
while (iter.hasPrevious()) {
WindowInfo windowInfo(iter.previous());
if (isOwnWindow(windowInfo.window())) {
WindowInfo *windowInfo = WindowInfo::windowFor(iter.previous());
if (isOwnWindow(windowInfo->window())) {
break;
}
if (numAnyWindowReceivers > 0 && !anyWindowSignalEmitted) {
Expand All @@ -98,7 +98,7 @@ bool HomeWindowMonitor::handleXEvent(const XEvent& event)
break;
}
}
if (windowInfo.types().toSet().intersect(nonFullscreenApplicationWindowTypes).isEmpty()) {
if (windowInfo->types().toSet().intersect(nonFullscreenApplicationWindowTypes).isEmpty()) {
emit fullscreenWindowOnTopOfOwnWindow();
break;
}
Expand Down Expand Up @@ -149,7 +149,7 @@ bool HomeWindowMonitor::isHomeWindowOnTop(QSet<Atom> ignoredWindows) const
if (isOwnWindow(windowOrder[i])) {
return true;
}
QSet<Atom> windowTypes = WindowInfo(windowOrder[i]).types().toSet();
QSet<Atom> windowTypes = WindowInfo::windowFor(windowOrder[i])->types().toSet();
if (windowTypes.intersect(ignoredWindows).isEmpty()) {
break;
}
Expand Down
17 changes: 10 additions & 7 deletions src/qml/Launcher.qml
Expand Up @@ -5,30 +5,33 @@ GridView {
id: launcherRoot
height: root.height
width: root.width
cellWidth: 130
cellHeight: 140
model: MenuModel {
}

delegate: Item {
width: 100
height: 110
width: launcherRoot.cellWidth
height: launcherRoot.cellHeight

Image {
id: launcherIcon
source: model.icon
anchors.centerIn: parent
height: 64
width: 64
sourceSize.height: 64
sourceSize.width: 64
height: 100
width: 100
sourceSize.height: 100
sourceSize.width: 100
asynchronous: true
}

Text {
text: model.name
horizontalAlignment: Text.AlignHCenter
anchors.top: launcherIcon.bottom
anchors.topMargin: 10
anchors.horizontalCenter: launcherIcon.horizontalCenter
width: 80
width: 100
elide: Text.ElideRight
}

Expand Down
2 changes: 1 addition & 1 deletion src/qml/Switcher.qml
Expand Up @@ -19,7 +19,7 @@ GridView {

Image {
id: launcherIcon
source: "image://windows/" + model.windowId + "/" + Math.random()
source: "image://windows/" + model.windowId + "/" + model.object.pixmapSerial
cache: false
anchors.centerIn: parent
height: 180
Expand Down
20 changes: 11 additions & 9 deletions src/switchermodel.cpp
Expand Up @@ -206,7 +206,7 @@ void SwitcherModel::updateWindowList()

qDebug() << "Read list of " << numWindowItems << " windows";
QList<Window> windowsStillBeingClosed;
QList<WindowInfo> windowList;
QList<WindowInfo *> windowList;
Window *wins = (Window *)windowData;

for (unsigned int i = 0; i < numWindowItems; i++)
Expand Down Expand Up @@ -321,7 +321,7 @@ void SwitcherModel::updateWindowList()
PropModeReplace,
(unsigned char *)&geom, 4);

WindowInfo wi(wins[i]);
WindowInfo *wi = WindowInfo::windowFor(wins[i]);
windowList.append(wi);
}
else
Expand Down Expand Up @@ -382,15 +382,17 @@ QVariant SwitcherModel::data(const QModelIndex& index, int role) const
if (!index.isValid())
return QVariant();

WindowInfo i = m_windows.at(index.row());
WindowInfo *i = m_windows.at(index.row());

switch (role) {
case name:
return i.title();
return i->title();
case windowId: {
qulonglong wid = i.window();
qulonglong wid = i->window();
return wid;
}
case object:
return QVariant::fromValue<QObject *>(i);
default:
break;
}
Expand Down Expand Up @@ -434,10 +436,10 @@ void SwitcherModel::closeWindow(qulonglong window)
qDebug() << Q_FUNC_INFO << "Closed " << window;

// Close also the window this one is transient for, if any
WindowInfo windowInfo = WindowInfo(window);
if (windowInfo.transientFor() != 0 && windowInfo.transientFor() != window) {
qDebug() << Q_FUNC_INFO << "Closing transient " << windowInfo.transientFor();
closeWindow(windowInfo.transientFor());
WindowInfo *windowInfo = WindowInfo::windowFor(window);
if (windowInfo->transientFor() != 0 && windowInfo->transientFor() != window) {
qDebug() << Q_FUNC_INFO << "Closing transient " << windowInfo->transientFor();
closeWindow(windowInfo->transientFor());
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/switchermodel.h
Expand Up @@ -59,7 +59,7 @@ class SwitcherModel : public QAbstractItemModel, XEventListener
Q_INVOKABLE void windowToFront(qulonglong window);
private:
QList<Window> windowsBeingClosed;
QList<WindowInfo> m_windows;
QList<WindowInfo *> m_windows;

Q_DISABLE_COPY(SwitcherModel)
};
Expand Down
71 changes: 32 additions & 39 deletions src/windowinfo.cpp
Expand Up @@ -18,15 +18,13 @@
****************************************************************************/

#include <QHash>
#include <QDebug>

#include "windowinfo.h"
#include "x11wrapper.h"
#include <QX11Info>


/*!
The window data is explicitly shared between window info objects through this class
*/
class WindowData : public QSharedData
class WindowInfo::WindowData
{

public:
Expand All @@ -37,16 +35,8 @@ class WindowData : public QSharedData
title(),
types(),
states(),
pid(0)
{
}

//! Copy constructor
WindowData(const WindowData& source) : QSharedData(source),
window(source.window),
transientFor(source.transientFor),
types(source.types),
states(source.states)
pid(0),
pixmapSerial(0)
{
}

Expand All @@ -71,6 +61,8 @@ class WindowData : public QSharedData
QList<Atom> states;

int pid;

int pixmapSerial;
};


Expand Down Expand Up @@ -109,41 +101,30 @@ void WindowInfo::initializeAtoms()
}
}

QHash<Window, QExplicitlySharedDataPointer<WindowData> > WindowInfo::windowDatas;
//! Storage for the WindowInfo data objects. A central storage enables constructing
//! new WindowInfo objects with shared data.
static QHash<Window, WindowInfo * > windowDatas;

WindowInfo::WindowInfo(Window window)
WindowInfo *WindowInfo::windowFor(Window wid)
{
if (QExplicitlySharedDataPointer<WindowData> data = windowDatas.value(window)) {
d = data;
if (WindowInfo *wi = windowDatas.value(wid)) {
return wi;
} else {
d = new WindowData(window);
updateWindowTitle();
updateWindowProperties();
windowDatas[window] = d;
return new WindowInfo(wid);
}
}

WindowInfo::WindowInfo(const WindowInfo &other) :
d(other.d)
WindowInfo::WindowInfo(Window window)
: d(new WindowData(window))
{
updateWindowTitle();
updateWindowProperties();
windowDatas[window] = this;
}

WindowInfo::~WindowInfo()
{
// If the data object's reference count is two, it means that the only alive
// references are in this object and the global container. That means that this
// object is the last WindowInfo object containing a reference to the data object.
// We don't want to leave a dangling data object to the global container so we'll
// remove the data object here.
if (d->ref == 2) {
windowDatas.remove(d->window);
}
}

WindowInfo& WindowInfo::operator=(const WindowInfo &rhs)
{
d = rhs.d;
return *this;
windowDatas.remove(d->window);
}

const QString& WindowInfo::title() const
Expand Down Expand Up @@ -233,6 +214,18 @@ QList<Atom> WindowInfo::getWindowProperties(Window winId, Atom propertyAtom, lon
return properties;
}

int WindowInfo::pixmapSerial() const
{
return d->pixmapSerial;
}

void WindowInfo::setPixmapSerial(int pixmapSerial)
{
d->pixmapSerial = pixmapSerial;
qDebug() << Q_FUNC_INFO << "Changed pixmap serial on " << d->window << " to " << d->pixmapSerial;
emit pixmapSerialChanged();
}

uint qHash(WindowInfo wi) {
return static_cast<uint>(wi.window());
}
37 changes: 14 additions & 23 deletions src/windowinfo.h
Expand Up @@ -21,18 +21,18 @@
#define WINDOWINFO_H_

#include <QString>
#include <QObject>
#include <QHash>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <QExplicitlySharedDataPointer>

class WindowData;

/*!
* WindowInfo is a helper class for storing information about an open window.
*/
class WindowInfo
class WindowInfo : public QObject
{
Q_OBJECT
public:
// X11 atoms
static Atom TypeAtom;
Expand All @@ -48,28 +48,13 @@ class WindowInfo
static Atom InputWindowAtom;
static Atom NameAtom;

/*!
* Constructs a WindowInfo that contains information about an open window.
*
* \param window The X window id
*/
explicit WindowInfo(Window window);

/*!
* Copy constructor.
*/
WindowInfo(const WindowInfo &other);
static WindowInfo *windowFor(Window wid);

/*!
* Destroys a WindowInfo object.
*/
~WindowInfo();

/*!
* Assignment operator.
*/
WindowInfo& operator=(const WindowInfo &rhs);

/*!
* Initializes the X11 atoms
*/
Expand Down Expand Up @@ -127,18 +112,24 @@ class WindowInfo
*/
void setPid(int pid);

Q_PROPERTY(int pixmapSerial READ pixmapSerial WRITE setPixmapSerial NOTIFY pixmapSerialChanged);
int pixmapSerial() const;
void setPixmapSerial(int pixmapSerial);

signals:
void pixmapSerialChanged();

private:
//! Storage for the WindowInfo data objects. A central storage enables constructing
//! new WindowInfo objects with shared data.
static QHash<Window, QExplicitlySharedDataPointer<WindowData> > windowDatas;
WindowInfo(Window window);

/*!
* Gets the atoms and places them into the list
*/
QList<Atom> getWindowProperties(Window winId, Atom propertyAtom, long maxCount = 16L);

//! The explicitly shared data object \c WindowData
QExplicitlySharedDataPointer<WindowData> d;
class WindowData;
WindowData * const d;

};

Expand Down
4 changes: 2 additions & 2 deletions src/windowmonitor.h
Expand Up @@ -48,7 +48,7 @@ class WindowMonitor : public QObject {
* A signal that gets emitted when the stacking order of the windows changes.
* The topmost window is the last one in the argument list.
*/
void windowStackingOrderChanged(QList<WindowInfo>);
void windowStackingOrderChanged(QList<WindowInfo *>);

/*!
* A signal that gets emitted when a fullscreen window appears on top of application's
Expand All @@ -60,7 +60,7 @@ class WindowMonitor : public QObject {
* own window's.
* \param window the WindowInfo for the window that appeared.
*/
void anyWindowOnTopOfOwnWindow(WindowInfo windowInfo);
void anyWindowOnTopOfOwnWindow(WindowInfo *windowInfo);
};

#endif // WINDOWMONITOR_H
5 changes: 5 additions & 0 deletions src/windowpixmapprovider.cpp
Expand Up @@ -3,6 +3,7 @@
#include <QX11Info>

#include "windowpixmapprovider.h"
#include "windowinfo.h"

// TODO: handle damage events on mDamage. need to get it from MApplication...

Expand Down Expand Up @@ -121,6 +122,10 @@ void WindowPixmapProvider::refreshPixmapFor(const QString &windowId)
// Register the pixmap for XDamage events
// TODO: mhome-mtf only registered if onDisplay
mDamages.insert(windowId, X11Wrapper::XDamageCreate(QX11Info::display(), wid, XDamageReportNonEmpty));

// force reload from QML
WindowInfo *winInfo = WindowInfo::windowFor(wid);
winInfo->setPixmapSerial(winInfo->pixmapSerial() + 1);
}
}

0 comments on commit 37aea3a

Please sign in to comment.