The object the SignalTracker belongs to is stored in a map managed by
the SignalManager which keeps a reference to that object. This map is
never destroyed nor is any entry ever removed. This leads to all objects
that ever had SignalTrackers used on them being kept alive even after
all references outside of the SignalTracker are long gone. This then
also extends to other objects which are leaked indirectly through
reference chains from these objects.
And if some of those objects are GObjects, this will prevent them from
being finalized, leaking further resources. A StWidget for example will
not release its shadow textures.
Fix this by using a WeakMap in SignalManager.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5807
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5796
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2450>
This mode changes the current IBus engine to ibus-typing-booster
under the rug (i.e. no changes in keyboard status menu) for any
XKB engine selected.
In order to make it useful for the currently selected language,
the typing-booster dictionary is changed to the current XKB
layout language. And since the OSK has its own emoji panel,
typing-boosters own emoji completion is disabled.
These changes only apply as long as the OSK panel is shown,
reverting to the original engine and typing-booster configuration
after it is hidden. This in theory also caters for users that
do have ibus-typing-booster enabled as an input source.
The final effect is text prediction for the language that is
being typed, according to the OSK layout, given that
ibus-typing-booster and the relevant hunspell dictionaries are
used.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2278>
This action will replace CLUTTER_KEY_Backspace emission for
the OSK backspace key. Following the available mockups, implement
different modes of operation:
- Single tap deletes a single character
- Long tap starts deleting characters one by one
- Longer tap switches to word-by-word deletion
This is made possible via the input method surrounding text,
inspecting the string to look the previous char/word position
backwards, and relies on IM focus providing enough context.
Since deleting text and getting surrounding text are both
async operations, we make one happen after the other, until
the button is released.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2278>
Newer versions of IBus (> 1.5.26) have the IBUS_CAP_OSK capability
which can be used to hint the active IM about an OSK driving input as
opposed to a physical keyboard. This may be used by IMs to tweak their
behavior to suit OSKs better.
Add the GNOME Shell side handling for this capability, and toggle it
on whenever the OSK is visible.
Since this is a far too new enum value and we don't want such new
IBus dependency, this change plays fast and loose with JS guarantees,
since a logical OR with an undefined value results in the other operand
unmodified it will work for older versions where the capability does not
exist and thus we want nothing extra enabled.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2415>
Multiple booleans - both in arguments and return values - are almost
always problematic API, because people have to memorize (or more likely
look up) the meaning of each position.
Instead, return a JS object so each value has a name attached to it.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2370>
After porting the more complex cases - in particular those that
affect a module's API - we are left with straight-forward D-Bus
method calls that can be moved to promise-based wrappers in one
go.
For consistency, this also switches from Remote to Async where
the call result is ignored.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2344>
The LoginManager abstraction is still mostly callback-based, not
least because the methods are thin wrappers around logind D-Bus
calls.
However as gjs' dbus wrapper now generates promised-based wrappers
as well, we can implement a proper async API just as naturally.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2344>
There are a couple of places left where we still use the old
indentation style, update them before making code changes.
After that, there are only a couple of non-type-safe comparisons
left of legacy style, so change those as well while we're at it.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2344>
Since IBus does not provide this information right away, we
so far cannot do much about providing a truthful anchor position
for the preedit text. But with the Mutter API in place it will
be up to this object to do so in the future.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2384>
ES modules do not allow exports to be overriden, in anticipation
of the ESM port add a `setCurrentExtension` utility which will
throw if used in the shell. This is tested using a conditional
import of Main.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2363>
We considered any ConnectFlag value major than SWAPPED as invalid, while
it's technically not fully true as we need to ensure that the passed
value is respecting the whole flags mask.
In fact, per se SWAPPED|AFTER (> SWAPPED) is a valid value (even if we
don't support the AFTER value).
But this makes the check more future-proof.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2366>
While untracking an object we used to compute it's proto for each signal
we were disconnecting from, while this is not needed when we're just
iterating over all the same owner signals, so let's add few more
functions to compute an object prototype, and repeat the disconnections
in the simplest way we can.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2366>
We used to create a temporary array of signal tracker keys and then to
iterate through them in order to untrack the objects, but the Map's can
be iterated directly so let's just use their native forEach.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2366>
Introduce a new class, EventEmitter, which implements signal
handling for pure JavaScript classes. EventEmitter still
utilizes GJS' addSignalMethods internally.
EventEmitter allows static typechecking to understand the
structure of event-emitting JS classes and makes creating
child classes simpler.
The name 'EventEmitter' mirrors a common name for this pattern
in Node and in JS libraries.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2043>
Both bluetooth and screencast support are based on build checks
right now. However in both cases, the dependency is only consumed
at runtime via the typelib, so let's actually check for that.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2297>
The screencast portal supports recording a single window,
and presents a list of open windows when that option is
selected. To allow updating that list when windows are
opened or closed, add a new "WindowsChanged" signal that
the portal can listen to.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2229>
We currently assume that any '::destroy' signal on a GObject type
has the semantics of the ClutterActor/GtkWidget signal, and should
therefore result in all signals being disconnected.
But we already have a case where the assumption doesn't hold: ShellWM
uses '::destroy' for the closing animation of windows, and the ShellWM
object itself remains very valid after the emission.
So rather than making assumptions about '::destroy', check objects
against a list of destroyable types that are explicitly registered
as such.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2226>
There are cases where we want to connect to a number of signals
for the lifetime of an object, but also other signals for a
limited period (say: between show and hide).
It is currently not possible to use disconnectObject() for the
latter, because it will disconnect all signals.
To address this use case, add a small class that can be used as
a transient signal holder, while still benefiting from autocleanup
by proxying the real owner.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2221>
The 'destroy' signal currently doesn't work with connectObject(),
because the handler is only connected after the signal tracker's
own destroy handler, which disconnects all handlers.
Address this by using connect_after for the cleanup handler, so
that other destroy handlers run before it (unless they also use
ConnectFlags.AFTER, but well *shrug*).
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2221>
Start using the new methods to simplify signal cleanup. For now,
focus on replacing existing cleanups; in most cases this means
signals connected in the constructor and disconnected on destroy,
but also other cases with a similarly defined lifetime (say: from
show to hide).
This doesn't change signal connections that only exist for a short
time (say: once), handlers that are connected on-demand (say: the
first time a particular method is called), or connections that
aren't tracked (read: disconnected) at all.
We will eventually replace the latter with connectObject() as
well - especially from actor subclasses - but the changeset is
already big enough as-is :-)
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1953>
The module exports a `addObjectSignalMethods()` method that extends
the provided prototype with `connectObject()` and `disconnectObject()`
methods.
In its simplest form, `connectObject()` looks like the regular
`connect()` method, except for an additional parameter:
```js
this._button.connectObject('clicked',
() => this._onButtonClicked(), this);
```
The additional object can be used to disconnect all handlers on the
instance that were connected with that object, similar to
`g_signal_handlers_disconnect_by_data()` (which cannot be used
from introspection).
For objects that are subclasses of Clutter.Actor, that will happen
automatically when the actor is destroyed, similar to
`g_signal_connect_object()`.
Finally, `connectObject()` allows to conveniently connect multiple
signals at once, similar to `g_object_connect()`:
```js
this._toggleButton.connect(
'clicked', () => this._onClicked(),
'notify::checked', () => this._onChecked(), this);
```
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1953>
We have made good progress on object literals as well, although there
are still a lot that use the old style, given how ubiquitous object
literals are.
But the needed reindentation isn't overly intrusive, as changes are
limited to the object literals themselves (i.e. they don't affect
surrounding code).
And given that object literals account for quite a bit of the remaining
differences between regular and legacy rules, doing the transition now
is still worthwhile.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2200>
There's a few things that are really unncessary to log without any
debugging enabled, for example "Getting parental controls for user", so
remove that.
Other things can be useful, so use console.debug() to log those.
Especially the warning in showAppInfo() we don't want log by default as
it spills tons of messages during shell startup (the async
initialization of the malcontent manager takes some time).
While at it, also make the !HAVE_MALCONTENT message a bit more accurate.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2196>
If the finish function isn't specified, promisify will now try
to use the async name without '_async'/'_begin' suffix (if any)
and '_finish' appended.
Everything except IBus uses a variation of that pattern, so there's
quite a bit of boilerplate we get to remove…
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2174>
Use GLib's spawn_async() instead of Gio.SubprocessLauncher() which does
not support the child setup function to start ibus-daemon.
This way we can restore the NOFILE limit prior to run the ibus-daemon.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2117>
The code to highlight matches did not properly escape the passed in text
as for markup before adding its highlighting markup. This lead to some
search result descriptions not showing up, because their descriptions
contained characters, such as "<", that would have to be escaped when
used in markup or otherwise lead to invalid markup.
To work around this some search providers wrongly started escaping the
description on their end before sending them to gnome-shell. This lead
to another issue. Now if the highlighter was trying to highlight the
term "a", and the escaped description contained "'", the "a" in
that would be considered a match and surrounded by "<b></b>". This
however would also generate invalid markup, again leading to an error
and the description not being shown.
Fix this by always escaping the passed in string before applying the
highlights in such a way that there are no matches within entities.
This also means that search providers that escaped their description
strings will now show up with the markup syntax. This will have to be
fixed separately in the affected search providers.
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4791
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2033>
This signal announces the preferred commit mode of the preedit text when
the input context is reset. Keep this mode around, and ensure to honor this
mode (e.g. maybe commit the preedit string) whenever the input method would
be reset.
This is delegated to the internal layers, so propagate this mode via
clutter_input_method_set_preedit_text().
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1929>
!1940 added support for soup 3, including a fallback to soup 2.4
where the newer version isn't available.
Unfortunately it missed that libgweather has a hidden soup dependency,
and now gnome-shell fails to start if a weather location has been set
up and soup 3 is available.
We don't have a good way to detect that case, so hide the soup 3 support
behind a build option. Distributors are expected to switch it at the
same time as libgweather.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1966>
We have initTranslations() for binding an extension's
gettext domain, but nothing to help with using gettext
from an extension.
Such help would be useful though, as an extension that
calls textdomain() like a normal application would
inadvertently changes the default domain for the whole
gnome-shell process.
Instead, extensions have to use domain-specific versions
of the gettext functions:
```js
const Gettext = imports.gettext.domain('my-extension');
const _ = Gettext.gettext;
```
Make this a bit easier by adding those functions directly
to the extensions object when initTranslations() is called,
then expose helper functions for calling them.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2594
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1941>
When adapting the check to the new versioning check, we just blindly
copied the old behavior for stable/unstable versions:
- stable releases must have matching major numbers
- unstable releases must match major and minor ("alpha", "beta", "rc")
That worked for the old even/odd scheme, but now has the absurd effect
that we consider an extension that lists "40.alpha" in its shell-version
incompatible with "40.beta", but compatible with "40.2".
At least this provides us with a good opportunity to reconsider the
behavior. While it is true that breakage is much more likely between
unstable releases, in practice extensions are either following shell
development closely or update once around the time of a stable release.
For the former, the stricter check isn't usually too useful (as the
extension releases around the same time as gnome-shell anyway).
For the latter, it's annoying that ".rc" is treated differently from
".0" and requires an update to become compatible.
The latter is also by far the more common case, so update the check
to only match on the major version regardless of whether a release
is stable or unstable.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3787
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1719>
This ports the runDialog changes of [1] to the underlying history
component, where they can benefit looking glass as well: the history is
now responsible for trimming the input and deciding that it shouldn’t be
stored if empty. (Note that _setPrevItem and _setNextItem already
skipped updating the history if the entry was empty.)
Since both users, runDialog and lookingGlass, also need the trimmed
input for other reasons – runDialog to avoid issues when interpreting
the command as a file path (if it can’t be executed as a command),
lookingGlass to decide whether a command should be run at all – have
addItem return the trimmed input. (runDialog and lookingGlass are not
yet changed to take advantage of this – that will be done in separate
commits.)
[1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1442
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1653>
gjs improved its default property getter/setters, and as a result it
is no longer possible to set read-only properties.
Add proper getters (backed by private properties) to fix the resulting
errors.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3203
With the new versioning scheme, the previously-minor version gets
shifted up to major, and unstable releases are marked by non-numeric
"versions" rather than uneven numbers. Reflect that in the extension
version check.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1456
We split the search string into words using whitespace, while
GLib.tokenize_and_fold() splits on any non-alphanumeric characters.
That is, a valid search term like ',' will be tokenized as [], so
the original non-empty terms may get mapped to an empty array.
And as [].every() returns true for any condition[0], we end up
matching *all* system actions in that case. We want the exact
opposite and not return any results, so handle that case explicitly.
[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/everyhttps://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3169
Move the screencasting into a separate D-Bus service process, using
PipeWire instead of Clutter API. The service is implemented in
Javascript using the dbusService.js helper, and implements the same API
as was done by screencast.js and the corresponding C code.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1372
Changing the icon to 'system-log-out-symbolic' has no visual
change in a default GNOME setup since both 'system-log-out-symbolic'
and 'application-exit-symbolic' are the same in adwaita-icon-theme
(at the time of writing), however, other icon themes differentiate
between the two icons so pointing to the appropriate icon name
is the right thing to do.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2751
Commit 764527c8c9 not only ports this file
to Promises but also changes the behavior of _initPanelService method.
Instead of always calling _updateReadiness when _panelService is ready,
it only calls it when get_global_engine_async succeeds.
The only callers of _updateReadiness are _initEngines and
_initPanelService. Assume that _initEngines completes first. Its
_updateReadiness call keeps _ready as false and it is expected for
_initPanelService to change it to true. However, since
get_global_engine_async fails because there is no active engine,
_initPanelService never calls _updateReadiness. Therefore, all setEngine
calls do nothing because _ready is false, and the input method panel
never shows. Users are unable to use any input method even if they can
see that ibus-daemon is already running.
Fix the issue by changing it back to the old behavior.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1235
Filter the apps shown on the desktop and in search results according to
whether they are blacklisted by the user’s parental controls.
This supports dynamically updating the filter during the user’s session.
This adds an optional dependency on libmalcontent. If that’s unavailable, no
parental controls filtering will occur.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/465
Promises make asynchronous operations easier to manage, in particular
when used through the async/await syntax that allows for asynchronous
code to closely resemble synchronous one.
gjs has included a Gio._promisify() helper for a while now, which
monkey-patches methods that follow GIO's async pattern to return a
Promise when called without a callback argument.
Use that to get rid of all those GAsyncReadyCallbacks!
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1126
The offset argument is changing from uint to int. Which means we
might would pass a negative offset and trigger an "out of bounds"
error. Make it work more or less alright with older mutters, by
clamping the offset to 0.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1146