KDE/kdebase/workspace/kwin
Chani Armitage
chanika at gmail.com
Fri Sep 24 14:03:23 CEST 2010
SVN commit 1179043 by chani:
Use an X property for activity associations
the new property name is "_KDE_NET_WM_ACTIVITIES", of type XA_STRING,
and it's a comma-separated list of activity UUIDs.
kwin should respond to other processes changing the activity list for a
window, and filter out any bogus IDs. It also caches KActivityController's
list of activities to prevent dbus deadlocks.
CCMAIL: plasma-devel at kde.org
M +3 -0 atoms.cpp
M +1 -0 atoms.h
M +40 -6 client.cpp
M +2 -0 client.h
M +2 -0 events.cpp
M +3 -0 manage.cpp
M +8 -0 workspace.cpp
M +4 -0 workspace.h
--- trunk/KDE/kdebase/workspace/kwin/atoms.cpp #1179042:1179043
@@ -38,6 +38,9 @@
atoms[n] = &kwin_running;
names[n++] = (char *) "KWIN_RUNNING";
+ atoms[n] = &activities;
+ names[n++] = (char *) "_KDE_NET_WM_ACTIVITIES";
+
atoms[n] = &wm_protocols;
names[n++] = (char *) "WM_PROTOCOLS";
--- trunk/KDE/kdebase/workspace/kwin/atoms.h #1179042:1179043
@@ -34,6 +34,7 @@
Atoms();
Atom kwin_running;
+ Atom activities;
Atom wm_protocols;
Atom wm_delete_window;
--- trunk/KDE/kdebase/workspace/kwin/client.cpp #1179042:1179043
@@ -1523,13 +1523,12 @@
*/
void Client::setOnActivity( const QString &activity, bool enable )
{
- if( activityList.contains(activity) == enable ) //nothing to do
+ QStringList newActivitiesList = activities();
+ if( newActivitiesList.contains(activity) == enable ) //nothing to do
return;
- //check whether we should set it to all activities
- QStringList newActivitiesList = activityList;
if (enable)
{
- QStringList allActivities = KActivityConsumer().availableActivities();
+ QStringList allActivities = workspace()->activityList();
if( !allActivities.contains(activity) ) //bogus ID
return;
newActivitiesList.append(activity);
@@ -1544,13 +1543,19 @@
*/
void Client::setOnActivities( QStringList newActivitiesList )
{
- QStringList allActivities = KActivityConsumer().availableActivities();
+ QStringList allActivities = workspace()->activityList();
if( newActivitiesList.size() == allActivities.size() || newActivitiesList.isEmpty() )
{
setOnAllActivities(true);
return;
}
+
+ QByteArray joined = newActivitiesList.join(",").toAscii();
+ char *data = joined.data();
activityList = newActivitiesList;
+ XChangeProperty(display(), window(), atoms->activities, XA_STRING, 8,
+ PropModeReplace, (unsigned char *)data, joined.size());
+
updateActivities( false );
}
@@ -1589,7 +1594,6 @@
* Returns the list of activities the client window is on.
* if it's on all activities, the list will be empty.
* Don't use this, use isOnActivity() and friends (from class Toplevel)
- * FIXME do I need to consider if it's not mapped yet?
*/
QStringList Client::activities() const
{
@@ -1622,6 +1626,7 @@
if( on )
{
activityList.clear();
+ XDeleteProperty( display(), window(), atoms->activities );
updateActivities( true );
}
else
@@ -2216,6 +2221,35 @@
return &p;
}
+void Client::checkActivities()
+ {
+ QStringList newActivitiesList;
+ QByteArray prop = getStringProperty(window(), atoms->activities);
+ if ( ! prop.isEmpty() )
+ newActivitiesList = QString(prop).split(',');
+
+ if (newActivitiesList == activityList)
+ return; //expected change, it's ok.
+
+ //otherwise, somebody else changed it. we need to validate before reacting
+ QStringList allActivities = workspace()->activityList();
+ if (allActivities.isEmpty())
+ {
+ kDebug() << "no activities!?!?";
+ //don't touch anything, there's probably something bad going on and we don't wanna make it worse
+ return;
+ }
+ for ( int i = 0; i < newActivitiesList.size(); ++i )
+ {
+ if ( ! allActivities.contains( newActivitiesList.at(i) ) )
+ {
+ kDebug() << "invalid:" << newActivitiesList.at(i);
+ newActivitiesList.removeAt( i-- );
+ }
+ }
+ setOnActivities( newActivitiesList );
+ }
+
} // namespace
#include "client.moc"
--- trunk/KDE/kdebase/workspace/kwin/client.h #1179042:1179043
@@ -691,6 +691,8 @@
friend bool performTransiencyCheck();
friend class SWrapper::Client;
+
+ void checkActivities();
};
/**
--- trunk/KDE/kdebase/workspace/kwin/events.cpp #1179042:1179043
@@ -942,6 +942,8 @@
getMotifHints();
else if( e->atom == atoms->net_wm_sync_request_counter )
getSyncCounter();
+ else if( e->atom == atoms->activities )
+ checkActivities();
break;
}
}
--- trunk/KDE/kdebase/workspace/kwin/manage.cpp #1179042:1179043
@@ -159,6 +159,8 @@
init_minimize = rules()->checkMinimize( init_minimize, !isMapped );
noborder = rules()->checkNoBorder( noborder, !isMapped );
+ checkActivities();
+
// Initial desktop placement
if( session )
{
@@ -171,6 +173,7 @@
// If this window is transient, ensure that it is opened on the
// same window as its parent. this is necessary when an application
// starts up on a different desktop than is currently displayed
+ //FIXME do the same for activities too
if( isTransient() )
{
ClientList mainclients = mainClients();
--- trunk/KDE/kdebase/workspace/kwin/workspace.cpp #1179042:1179043
@@ -248,6 +248,7 @@
connect( &activityController_, SIGNAL( currentActivityChanged(QString) ), SLOT( updateCurrentActivity(QString) ));
connect( &activityController_, SIGNAL( activityRemoved(QString) ), SLOT( activityRemoved(QString) ));
+ connect( &activityController_, SIGNAL( activityAdded(QString) ), SLOT( activityAdded(QString) ));
}
void Workspace::init()
@@ -372,6 +373,7 @@
}
if( !setCurrentDesktop( initial_desktop ))
setCurrentDesktop( 1 );
+ allActivities_ = activityController_.availableActivities();
updateCurrentActivity( activityController_.currentActivity() );
// Now we know how many desktops we'll have, thus we initialize the positioning object
@@ -1674,12 +1676,18 @@
*/
void Workspace::activityRemoved(const QString &activity)
{
+ allActivities_.removeOne(activity);
foreach (Client *client, stacking_order)
{
client->setOnActivity(activity, false);
}
}
+void Workspace::activityAdded(const QString &activity)
+ {
+ allActivities_ << activity;
+ }
+
/**
* Called only from D-Bus
*/
--- trunk/KDE/kdebase/workspace/kwin/workspace.h #1179042:1179043
@@ -46,6 +46,7 @@
class QMenu;
class QActionGroup;
+class QStringList;
class KConfig;
class KActionCollection;
class KStartupInfo;
@@ -315,6 +316,7 @@
int* desktopGrid_;
int currentDesktop_;
QString activity_;
+ QStringList allActivities_;
bool desktopLayoutDynamicity_;
KActivityController activityController_;
@@ -337,6 +339,7 @@
QRect screenGeometry( int screen ) const;
int screenNumber( const QPoint& pos ) const;
QString currentActivity() const { return activity_; }
+ QStringList activityList() const { return allActivities_; }
// Tab box
Client* currentTabBoxClient() const;
@@ -759,6 +762,7 @@
void updateCurrentActivity(const QString &new_activity);
void activityRemoved(const QString &activity);
+ void activityAdded(const QString &activity);
protected:
bool keyPressMouseEmulation( XKeyEvent& ev );
More information about the Plasma-devel
mailing list