When computing the delta between the visible and the last saved launcher
order state, following the reordering of launchers, the code was incorrectly
comparing resolved and unresolved (i.e., for config storage) launcher URLs.
This lead to an incorrect result and therefore pinned tasks jumping around
in the Task Manager applet.
BUG:426880
the source model is set asyncronously so onComponentcomplete count is 0, and when the proper source is set the notify is not emitted. furthermore the source canchange at runtime, so count needs to be reevaluated every time this happens
the source model is set asyncronously so onComponentcomplete count is 0, and when the proper source is set the notify is not emitted. furthermore the source canchange at runtime, so count needs to be reevaluated every time this happens
Summary:
Includes, among other things:
* A refactoring towards supporting more than one desktop per window,
for an eventual virtual desktops / activities merge
* A scheme for process-internal window ids on Wayland as DND payload
so DND in and to the Pager works in the shell
* Implemented various previously missing behavior in WaylandTasksModel
such as implicit moves of windows to the current desktop on various
actions
* Expanded VirtualDesktopInfo API so the Pager can better abstract
over windowing systems
* Implicit internal sharing of VirtualDesktopInfo since there are many
more instances now
* Various cleanups
Still missing:
* Fixing the VirtualDesktops data role in the grouping proxy
* The protocol doesn't have desktop creation/destruction yet, so some
of the related logic is still missing
* Some FIXME TODOs in the code when I was unhappy with the current
KWayland API
This code is largely untested and subject to change.
Depends on D12820 and relates to T4457.
Reviewers: mart, mvourlakos, davidedmundson
Reviewed By: davidedmundson
Subscribers: alexde, anthonyfieroni, zzag, ngraham, abetts, plasma-devel
Tags: #plasma
Maniphest Tasks: T4457
Differential Revision: https://phabricator.kde.org/D13745
Summary:
Due to not passing `parent` to QAIM::index(), we were moving top-level
indices in the map instead. This meant the sort map would become out of
sync with the row move, and to the user it would look like both the
group children and unrelated top-level entries moved.
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15550
Summary:
Due to not passing `parent` to QAIM::index(), we were moving top-level
indices in the map instead. This meant the sort map would become out of
sync with the row move, and to the user it would look like both the
group children and unrelated top-level entries moved.
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15550
Summary:
Due to not passing `parent` to QAIM::index(), we were moving top-level
indices in the map instead. This meant the sort map would become out of
sync with the row move, and to the user it would look like both the
group children and unrelated top-level entries moved.
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15550
Summary:
Turns out c8358c203f only worked accidentally. We can't do this
via filterModel->mapFromSource, because in a lambda connected to
its source model's rowsInserted signal, the proxy hasn't seen that
row yet.
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15462
Summary:
LibreOffice reuses the same main window for both its start center and
sub-apps like Writer launched from it, changing the window metadata on
the fly. This ensures we hide e.g. a launcher for Writer when picking
it in the LO start center.
Reviewers: broulik
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15458
Summary:
Some apps initially show their window with bogus/useless window
metadata and then update to useful metadata during early startup.
For example, LibreOffice sets WM_CLASS to soffice/Soffice and
then updates to libreoffice-writer/libreoffice. This leads to
a poor user experience on particular the Icons-only Task Manager,
but also the regular Task Manager depending on settings.
Depending on its configuration (and Icons-only Task Manager is
a particular set of configuration options, as far as the model
is concerned), TasksModel will try to sort a new window task
adjacent to its launcher task. The appearance of a new window
task also causes matching (in terms of identification) launcher
or startup tasks to be filtered out. To the user, this forms a
lifecycle of the launcher being replaced by the window in-place
(and a startup state inbetween, optionally but by default).
Prior to this patch, this sorting decision was only done once,
when a new window enters the source model stack. This meant the
LibreOffice window would initially be sorted into the "wrong"
spot (the bogus metadata doesn't allow us to relate it to its
launcher) and then, following the metadata change, stick to the
wrong position.
Simply changing the code to sort things again on any metadata
change would not have been good enough: Metadata changes can
occur at any time, and things should not just move around on
the user - this sort mode is called "Manual" for a reason. Also,
the visual result would still be poor: The window would initially
appear at the wrong position, then move to the right one a bit
later.
This patch takes the following approach:
* It adds a new config key to taskmanagerrulesrc for listing
ids of matching tasks to completely hide, and of course the
code needed to implement this.
* It adds LibreOffice' bogus initial metadata to this key, so
the tasks is initially hidden.
* The sort code skips over hidden window tasks in the sort
insert queue instead of moving them. The queue is marked as
stale then, and cleared on unrelated windowing system changes.
* It resorts when tasks are unhidden (i.e. once the metadata
update has occured and the task no longer matches the above
config key).
The visual result is that the startup notification on the
launcher spins a little bit longer than before, even though the
window has already appeared (although LO lags in filling in its
contents anyway), and then morphs into the window task
representation once the client has completed the window metadata
change. This happens in such a short order as to be more or less
imperceptible.
If startup notifications are turned off it's broadly the same,
minus the spinning.
BUG:396871
Reviewers: davidedmundson, broulik, ngraham
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15410
Summary: Used in the minimizeAll plasmoid (see D10019)
Test Plan: Used in applet
Reviewers: #plasma
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D11059
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