Add an option to use the matching launcher icon for task items..

With the option disabled, task items use the window icon whenever
possible. With the option enabled, the launcher icon is used
instead. This prevents a jarring icon change when applications use
a different icon theme from Plasma Desktop, at the cost of losing
realtime window icon updates being reflected in the Task Manager.

Defaults to on. The Task Manager applets are getting a checkbox
for it.

This is a rock-and-a-hard-place decision. Users are regularly
upset about what they perceive as their theming choice not being
respected, and pleading for app fixes appears to be fairly fruit-
less. It also looks like Wayland will nix runtime window icon
changes. Nonetheless this will likely produce complaints about
edge cases (e.g. Gimp miniature window previews).

CCMAIL:348050
wilder-5.14
Eike Hein 11 years ago
parent 6cefb78d1e
commit fbd4a876f3
  1. 2
      CMakeLists.txt
  2. 33
      libtaskmanager/groupmanager.cpp
  3. 8
      libtaskmanager/groupmanager.h
  4. 8
      libtaskmanager/launcheritem.cpp
  5. 2
      libtaskmanager/launcheritem.h
  6. 92
      libtaskmanager/taskitem.cpp
  7. 12
      libtaskmanager/taskitem.h

@ -27,7 +27,7 @@ find_package(KF5 REQUIRED COMPONENTS Package)
find_package(KF5 5.1 REQUIRED COMPONENTS Baloo)
find_package(KF5TextEditor)
find_package(KWinDBusInterface CONFIG REQUIRED)
find_package(KF5WebKit)
#find_package(KF5WebKit)
find_package(Phonon4Qt5 4.6.60 REQUIRED NO_MODULE)
set_package_properties(Phonon4Qt5 PROPERTIES

@ -75,6 +75,7 @@ public:
changingGroupingStrategy(false),
readingLauncherConfig(false),
separateLaunchers(true),
alwaysUseLauncherIcons(true),
forceGrouping(false),
launchersLocked(false)
{
@ -139,6 +140,7 @@ public:
bool changingGroupingStrategy : 1;
bool readingLauncherConfig : 1;
bool separateLaunchers : 1;
bool alwaysUseLauncherIcons : 1;
bool forceGrouping : 1;
bool launchersLocked : 1;
};
@ -984,6 +986,35 @@ void GroupManager::setSeparateLaunchers(bool s)
}
}
bool GroupManager::alwaysUseLauncherIcons() const
{
return d->alwaysUseLauncherIcons;
}
void GroupManager::setAlwaysUseLauncherIcons(bool keep)
{
if (d->alwaysUseLauncherIcons != keep) {
d->alwaysUseLauncherIcons = keep;
QStack<TaskGroup *> groups;
groups.push(d->currentRootGroup());
while (!groups.isEmpty()) {
TaskGroup *group = groups.pop();
foreach (AbstractGroupableItem * item, group->members()) {
if (item->itemType() == GroupItemType) {
groups.push(static_cast<TaskGroup *>(item));
} else if (item->itemType() == TaskItemType) {
static_cast<TaskItem *>(item)->setAnnounceIconChanges(!keep);
}
}
}
emit alwaysUseLauncherIconsChanged(keep);
}
}
bool GroupManager::forceGrouping() const
{
return d->forceGrouping;
@ -1106,7 +1137,7 @@ int GroupManagerPrivate::launcherIndex(const QUrl &url)
index = 0;
foreach (const LauncherItem * item, launchers) {
if (item->launcherUrl().scheme() == "preferred") {
KService::Ptr service = KService::serviceByStorageId(item->defaultApplication());
KService::Ptr service = KService::serviceByStorageId(item->defaultApplication(item->launcherUrl()));
if (service) {
QUrl prefUrl(service->entryPath());

@ -60,6 +60,7 @@ class TASKMANAGER_EXPORT GroupManager: public QObject
Q_PROPERTY(bool showOnlyCurrentActivity READ showOnlyCurrentActivity WRITE setShowOnlyCurrentActivity NOTIFY showOnlyCurrentActivityChanged)
Q_PROPERTY(bool showOnlyMinimized READ showOnlyMinimized WRITE setShowOnlyMinimized NOTIFY showOnlyMinimizedChanged)
Q_PROPERTY(bool separateLaunchers READ separateLaunchers WRITE setSeparateLaunchers NOTIFY separateLaunchersChanged)
Q_PROPERTY(bool alwaysUseLauncherIcons READ alwaysUseLauncherIcons WRITE setAlwaysUseLauncherIcons NOTIFY alwaysUseLauncherIconsChanged)
Q_PROPERTY(QList<QUrl> launcherList READ launcherList WRITE setLauncherList NOTIFY launcherListChanged)
public:
@ -189,6 +190,12 @@ public:
/** set if launchers should been show separate from tasks */
void setSeparateLaunchers(bool s);
/** keep using launcher icon for running tasks */
bool alwaysUseLauncherIcons() const;
/** set whether to keep using launcher icons for running tasks */
void setAlwaysUseLauncherIcons(bool keep);
/** Should grouping *always* happen? */
bool forceGrouping() const;
@ -225,6 +232,7 @@ Q_SIGNALS:
void showOnlyCurrentActivityChanged(bool);
void showOnlyMinimizedChanged(bool);
void separateLaunchersChanged(bool);
void alwaysUseLauncherIconsChanged(bool);
private:
Q_PRIVATE_SLOT(d, void currentDesktopChanged(int))

@ -238,7 +238,7 @@ void LauncherItem::launch()
//NOTE: preferred is NOT a protocol, it's just a magic string
if (d->url.scheme() == "preferred") {
KService::Ptr service = KService::serviceByStorageId(defaultApplication());
KService::Ptr service = KService::serviceByStorageId(defaultApplication(d->url));
if (!service) {
return;
@ -262,9 +262,9 @@ QUrl LauncherItem::launcherUrl() const
}
//Ugly hack written by Aaron Seigo from plasmagenericshell/scripting/scriptengine.cpp
QString LauncherItem::defaultApplication() const
QString LauncherItem::defaultApplication(const QUrl &url)
{
const QString application = d->url.host();
const QString application = url.host();
if (application.isEmpty()) {
return QString();
}
@ -380,7 +380,7 @@ void LauncherItem::setLauncherUrl(const QUrl& url)
}
} else if (d->url.scheme() == "preferred") {
//NOTE: preferred is NOT a protocol, it's just a magic string
const KService::Ptr service = KService::serviceByStorageId(defaultApplication());
const KService::Ptr service = KService::serviceByStorageId(defaultApplication(d->url));
if (service) {
QString desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, service->entryPath());

@ -89,7 +89,7 @@ public:
void setLauncherUrl(const QUrl &url);
//preferred applications hack
QString defaultApplication() const;
static QString defaultApplication(const QUrl &url);
public Q_SLOTS:
void toDesktop(int);

@ -24,11 +24,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Own
#include "taskitem.h"
#include "launcheritem.h"
#include <KActivities/Info>
#include <KConfig>
#include <KConfigGroup>
#include <KDesktopFile>
#include <KFileItem>
#include <KService>
#include <KServiceTypeTrader>
#include <processcore/processes.h>
@ -45,24 +47,36 @@ namespace TaskManager
{
class TaskItem::Private
class TaskItemPrivate
{
public:
Private()
: checkedForLauncher(false) {
TaskItemPrivate(TaskItem *item)
: q(item),
announceIconChanges(false),
checkedForLauncher(false) {
}
void filterChange(::TaskManager::TaskChanges change);
TaskItem *q;
QWeakPointer<Task> task;
QWeakPointer<Startup> startupTask;
QUrl launcherUrl;
QIcon launcherIcon;
bool announceIconChanges;
bool checkedForLauncher;
QString taskName;
};
void TaskItemPrivate::filterChange(::TaskManager::TaskChanges change)
{
if (announceIconChanges || change != ::TaskManager::TaskChange::IconChanged) {
emit q->changed(change);
}
}
TaskItem::TaskItem(QObject *parent, Task *task)
: AbstractGroupableItem(parent),
d(new Private)
d(new TaskItemPrivate(this))
{
setTaskPointer(task);
}
@ -70,10 +84,10 @@ TaskItem::TaskItem(QObject *parent, Task *task)
TaskItem::TaskItem(QObject *parent, Startup *task)
: AbstractGroupableItem(parent),
d(new Private)
d(new TaskItemPrivate(this))
{
d->startupTask = task;
connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), this, SIGNAL(changed(::TaskManager::TaskChanges)));
connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), this, SLOT(filterChange(::TaskManager::TaskChanges)));
connect(task, SIGNAL(destroyed(QObject*)), this, SLOT(taskDestroyed())); //this item isn't useful anymore if the Task was closed
}
@ -119,7 +133,7 @@ void TaskItem::setTaskPointer(Task *task)
d->task = task;
if (task) {
connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), this, SIGNAL(changed(::TaskManager::TaskChanges)));
connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), this, SLOT(filterChange(::TaskManager::TaskChanges)));
connect(task, SIGNAL(destroyed(QObject*)), this, SLOT(taskDestroyed()));
emit gotTaskPointer();
}
@ -166,7 +180,19 @@ WindowList TaskItem::winIds() const
QIcon TaskItem::icon() const
{
if (d->task) {
return d->task.data()->icon();
if (static_cast<GroupManager *>(parent())->alwaysUseLauncherIcons()) {
if (d->launcherIcon.isNull()) {
d->launcherIcon = launcherIconFromUrl(launcherUrl());
}
if (!d->launcherIcon.isNull()) {
return d->launcherIcon;
} else {
return d->task.data()->icon();
}
} else {
return d->task.data()->icon();
}
}
if (d->startupTask) {
@ -176,6 +202,16 @@ QIcon TaskItem::icon() const
return QIcon();
}
bool TaskItem::announceIconChanges() const
{
return d->announceIconChanges;
}
void TaskItem::setAnnounceIconChanges(bool announce)
{
d->announceIconChanges = announce;
}
QString TaskItem::name() const
{
if (d->task) {
@ -437,7 +473,13 @@ void TaskItem::setLauncherUrl(const QUrl &url)
if (!d->launcherUrl.isEmpty()) {
return;
}
d->launcherUrl = url;
if (static_cast<GroupManager *>(parent())->alwaysUseLauncherIcons()) {
d->launcherIcon = launcherIconFromUrl(url);
}
d->taskName = QString(); // Cause name to be re-generated...
KConfig cfg("taskmanagerrulesrc");
@ -451,7 +493,13 @@ void TaskItem::setLauncherUrl(const AbstractGroupableItem *item)
if (!d->launcherUrl.isEmpty() || !item) {
return;
}
d->launcherUrl = item->launcherUrl();
if (static_cast<GroupManager *>(parent())->alwaysUseLauncherIcons()) {
d->launcherIcon = launcherIconFromUrl(d->launcherUrl);
}
d->taskName = QString(); // Cause name to be re-generated...
}
@ -716,6 +764,32 @@ QUrl TaskItem::launcherUrlFromTask(GroupManager *groupManager, Task *task, Start
return launcherUrl;
}
QIcon TaskItem::launcherIconFromUrl(const QUrl &url)
{
if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) {
KDesktopFile f(url.toLocalFile());
if (f.tryExec()) {
return QIcon::fromTheme(f.readIcon());
}
} else if (url.scheme() == "preferred") {
//NOTE: preferred is NOT a protocol, it's just a magic string
const KService::Ptr service = KService::serviceByStorageId(LauncherItem::defaultApplication(url));
if (service) {
QString desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, service->entryPath());
KDesktopFile f(desktopFile);
return QIcon::fromTheme(f.readIcon());
}
} else {
const KFileItem fileItem(url);
return QIcon::fromTheme(fileItem.iconName());
}
return QIcon();
}
void TaskItem::resetLauncherCheck()
{
if (d->launcherUrl.isEmpty()) {
@ -749,4 +823,4 @@ bool TaskItem::demandsAttention() const
} // TaskManager namespace
#include "moc_taskitem.cpp"

@ -35,6 +35,7 @@ namespace TaskManager
{
class GroupManager;
class TaskItemPrivate;
/**
* Wrapper class so we do not have to use the Task class directly and the Task* remains guarded
@ -63,6 +64,7 @@ public:
TASKMANAGER_DEPRECATED bool isGroupItem() const;
QIcon icon() const;
QString name() const;
QString taskName() const;
@ -87,8 +89,12 @@ public:
void setLauncherUrl(const AbstractGroupableItem *item);
QUrl launcherUrl() const;
static QUrl launcherUrlFromTask(GroupManager *groupManager, Task *task, Startup *startup = 0);
static QIcon launcherIconFromUrl(const QUrl &url);
void resetLauncherCheck();
bool announceIconChanges() const;
void setAnnounceIconChanges(bool announce);
public Q_SLOTS:
void toDesktop(int);
@ -118,8 +124,10 @@ Q_SIGNALS:
void gotTaskPointer();
private:
class Private;
Private * const d;
Q_PRIVATE_SLOT(d, void filterChange(::TaskManager::TaskChanges change))
friend class TaskItemPrivate;
TaskItemPrivate * const d;
};
} // TaskManager namespace

Loading…
Cancel
Save