Summary:
This introduces the use of QQmlParserStatus to delay populating
the model until all properties have been set, to avoid delegate
churn.
TasksModel is also meant to be used by C++. There's no good way
to determine whether an object is being instanciated by QML
during construction time, therefore this patch also introduces a
delay in initial population of the model after construction via
a single-shot timer. At the time the slot is invoked we know if
we're used by QML (because QQmlParserStatus::classBegin has
either been called or not by then) so we can decide to populate
or wait more for QQmlParserStatus::componentComplete.
I'm not super happy with this behavior change for C++ users,
however as the model is usually used via QML currently, it's
pragmatic to optimize performance for the common case, and it
doesn't technically break QAbstractItemModel semantics, as model
population isn't required to be sync.
There's a decent change this fixes a recently-reported crash as a
by-product:
CCBUG:386630
Reviewers: #plasma, davidedmundson, mart
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D8723
begin() and end() operate on the hash values.
This avoids creating a temporary list just for this.
Differential Revision: https://phabricator.kde.org/D7917
Summary:
The pinned launchers that are assigned to other activities
will have a -1 as the order. We should not forget them
when saving to the configuration file.
Reviewers: hein, mart
Reviewed By: hein
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D5933
Summary:
The pinned launchers that are assigned to other activities
will have a -1 as the order. We should not forget them
when saving to the configuration file.
Reviewers: hein, mart
Reviewed By: hein
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D5933
Summary:
This is implemented by TasksModel and allows clients to reliably
query whether a row has an associated launcher. Useful for things
like Pin/Unpin action state or layout decisions.
Previously clients would have to reimplement something like
TaskTools::appsMatch on top of the model, which we absolutely do
not want to do - there should only be one copy of the app matching
logic for consistency's sake. In practice clients would do things
like fetch LauncherUrl and run it by launcherPosition(), which
omits appsMatch's AppId comparision, as an example of such unwated
drift. This approach also avoids the large performance overhead
involved.
The role is not implemented by the single-type or munging tasks
models as it has no use there.
Reviewers: #plasma, davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D5504
Summary:
Previously we updated the prop after checking for
AbstractTasksModel::IsDemandingAttention on window closure, but
as the window is gone, we can't actually get state for it anymore,
so we always need to update.
To make up for it, this patch also optimizes the prop updates to occur
only once per insert/remove batch - this is a bit academic because
the source models currently only insert single rows at a time, but
it's good hygiene.
BUG:378254
Reviewers: #plasma, mart
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D5261
Summary:
What happens:
* Activity switch calls invalidateFilter on TaskFilterProxyModel,
which may remove rows in response.
* Up the proxy chain, TasksModel may ask LauncherTasksModel to
emit dataChanged for its contents in response to the row removal,
to cause its own filtering to re-evaluate the launchers for the
life cycle logic.
* This can cause TFPM to do more filtering before invalidateFilter
has actually returned, causing trip-ups such as duplicated rows
in the proxy.
* Eventually the corrupted maps cause a memory corruption crash.
This patch changes step 2 to "find the launchers in the TFPM (the
direct source model) and ask for a dataChanged for each". This
costs us a loop and accesses to IsLauncher, but on the other hand
fixes the crash and avoids a lot of filtering and mapping work
between LTM and up to and including TFPM. It's also just better
code to ask for the dataChanged only from the model we need it
from.
BUG:376055
Reviewers: #plasma, davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D4631
Summary:
Alphabetical sorting currently compares a concatenation of
"AppName" (determined by heuristic) and Qt::DisplayRole (usually
the window title) using QString::localeAwareSort. This reflects
that the motivation behind alphabetical sorting is generally to
keep windows belonging to the same app grouped together and then
order those groups alphabetically.
The current code achieves this, but the particulars turn out to
negatively impact users of multi-windowed apps that frequently
change window titles in ways that impact sorting, particularly
tabbed web browsers. Switching between tabs may change the order
of browser windows on the Task Manager. Multiple instances of
feedback suggest this is jarring and unexpected, despite
technically being alphabetical.
This patch changes behavior as follows:
1. Instead of comparing "<App Name><DisplayRole>" it will try to only
compare "<App Name>", falling back to "<DisplayRole>" if the app
name can't be determined.
2. If two tasks compare to equal in the above, it will fall back to
source model row order, i.e. creation/append sorting.
This still achieves the primary goal laid out above while
keeping the sort order within an app "group" stable when using
alphabetical sorting.
BUG:373698
An alternative means to achive this behavior would be via existing
Task Manager settings. To wit:
1. Enable grouping
2. Disable group popups, so groups are instead maintained inline
on the widget
I'm actually considering suggesting the above (plus changing
sorting to Manual) as new default settings for 5.10 - but in
the meantime it still makes sense to tune the alphabetical
sorting mode in this way, and put the improved behavior into
5.8 and 5.9 to address user feedback earlier.
Reviewers: #plasma, davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D4469
Summary:
syncLaunchers() is called after drag operations end to write the order
of launchers in the all-capping TasksModel to the LauncherTaskModel
source model. The per-activity launcher pinning work recently broke
this by changing the model that's looped over.
Reviewers: #plasma, ivan, davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D4608
Summary:
It turns out that Chrome under certain conditions will change its
window metadata as it quits, causing a race we sometimes lose, failing
to reveal the associated launcher because we can no longer match it
to the window at window closing time. Instead we are now forced to
re-check all launchers after the window is gone. As a speed optimi-
zation we only consider top-level windows (and startups) as being in
a group implies matching siblings.
In addition this refactoring eliminates a use of Qt::QueuedConnection
that allowed for an unpredictable event loop spin inbetween things.
BUG:365617
Reviewers: davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D3950
Summary:
It turns out that Chrome under certain conditions will change its
window metadata as it quits, causing a race we sometimes lose, failing
to reveal the associated launcher because we can no longer match it
to the window at window closing time. Instead we are now forced to
re-check all launchers after the window is gone. As a speed optimi-
zation we only consider top-level windows (and startups) as being in
a group implies matching siblings.
In addition this refactoring eliminates a use of Qt::QueuedConnection
that allowed for an unpredictable event loop spin inbetween things.
BUG:365617
Reviewers: davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D3950
- The URL in the configuration file now contains also the list
of activities it should be shown in
- The configuration format is backwards compatible
- Added API to differentiate between the shown launchers (for
the current activity), and all configured launchers
- Supports reordering of the launchers
Testing: It needs the ivan/per-activity-launchers branch of
plasma-workspace because of the API changes
Summary:
This introduces a new WindowTasksModel which is a QIdentityProxyModel
around an instance of either WaylandTasksModel or XWindowsTasksModel.
This arbitration was previously done directly in TasksModel, along with
refcounting to share a single window tasks sub-model between TasksModel
instances. Factoring out both of these things has two goals:
- It allows users of libtaskmanager which are solely interested in
window data (e.g. the Pager) to skip the unnecessary complexity
of TasksModel, while still sharing the windowing monitoring with
users of TasksModel.
- TasksModel becomes fully free of windowing system-specific code
and calls to KWindowSystem (to query the platform), making its
code a little cleaner.
The downside is another layer of indirection (the QIdentityProxyModel),
but the upside is clear: The Pager wants to share window data and
window monitoring with the Task Manager, but is not interested in
startup notifications, does its own sorting (using the window stacking
order), does not need grouping and has different filtering needs.
The Pager backend will use QSortFilterProxyModel around WindowTasksModel
to mix in its own data and sort by stacking order.
Reviewers: #plasma, mart, davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D2379
Summary:
Previously the launcher tasks model was always instanciated; with
this change it's only done once a launcher list gets set or a
request to add a launcher happens. This avoids an unnecessary model
in TasksModel instances that will never store any launchers (e.g.
in the Window List applet).
Reviewers: #plasma, davidedmundson
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D2378
Summary:
Reduces code duplication and we always opperate on cached value, that
is the platform is only checked once in application life cycle.
Reviewers: #plasma, hein
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D2342
In practice the parent will no longer jump around when a group is dissolved
by dropping the member count to 1 by deleting the 'lead' entry (the source
index the parent maps to). When doing this from the group's tooltip, the
delegate would run amok as a result.
BUG:365173
Summary:
Avoids problems stemming from libtaskmanager and plasma-framework's
AppletInterface::screen numbering screens differently (QScreen order
vs. who knows what).
CCBUG:365246
Reviewers: #plasma, graesslin, mart
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D2143
TaskGroupingProxyModel appends; the proxy may sort differently
(e.g. alphabetically by default). The win id list was returned
in TGPM sort order, which meant the tooltips had the thumbnails
in the wrong order, and clicking them would activate the wrong
window.
BUG:365181
Fixes a nasty bug causing two TasksModel instances to interfere
with each other.
BUG:365011
Also removes an assumption that the launcher list will pass
through LauncherTasksModel unharmed -- if launchers become
activity-silo'd, that might not be the case any longer.
- Use appsMatch() consistently. Some blocks were still repeating its
business logic redundantly.
- Now that we have the ordering worked out, updateLauncherCount can just
count after all the filtering is done for an additional speedup. We
can also avoid calling it for every about-to-be-removed row.
This also fixes that updateLauncherCount wasn't considering appid
matches (it was only looking at URLs), whereas filterAcceptsRow
worked like appsMatch() did, causing a wrong launcherCount in the
edge case of the URLs for a stored launcher and a running window
not matching, but the app id matching.
- Some more sanity checks in startup notification comparisons.
If the window never comes, the launcher would remain hidden otherwise;
also, if a startup times out before a window appears, we get an ugly
gap when using launch-in-place behavior (i.e. on Icontasks).
BUG:364612
Summary:
Acts like requestVirtualDesktops only with a QStringList
make runningActivities invokable
Test Plan: See subsequent plasma-desktop review
Reviewers: hein, #plasma
Reviewed By: hein, #plasma
Subscribers: hein, mart, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D1814
This is a pretty big behavior change vs. libtm-old, and upon reflection
probably better done early in the 5.8 cycle to find out how deeply users
expect the old behavior.
This reverts commit f542116cc2.
We don't show a startup notification if we already have a matching
window -- however, this test was done against all window tasks, even
if some of them are being filtered out (e.g. by virtual desktop).
Now "do we have a window?" is checked against the filtered window
tasks, so a startup notification for $app is shown even if $app
already has a window on a different desktop.
When a launcher was removed, the cache was invalidated at the time the
top-level proxy removes the row for it. However this happens in
response to rowsAboutToBeRemoved from the source model, at which time
launcherList() still contains the launcher at the row about to be
removed. While invalidating the cache in response to rows being removed
from the top-level proxy is correct (for the case where a window task
shadowing a launcher is removed), to handle a launcher removal we also
need to invalidate it when the launcher list changes.
CCBUG:364537