Compare commits

..

62 Commits

Author SHA1 Message Date
Carlos Garnacho
aea56b6f55 core: Set timestamp in our DESKTOP_STARTUP_ID tokens
We must be educated to X11 clients (which usually parse the timestamp from
the DESKTOP_STARTUP_ID, and request focus with it) to make focus stealing
prevention work across the board.

To wayland clients the startup ID should be as opaque and meaningless as
it was before.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/540
2019-04-17 18:56:44 +02:00
Carlos Garnacho
217bd31531 x11: Drop usage of libstartup-notification
And replace with our own XClientMessageEvent handling. It has the advantage
that we can mix Wayland and X11 startup notifications without always going
through X11 so that libstartup-notification is able to get the full picture.
This will fare much better on no/intermittent X11 availability.

A second advantage is the removed dependency, and that it seems to result
in less code (yay abstractions!).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/540
2019-04-17 18:56:44 +02:00
Carlos Garnacho
3de6f7ebfe core: Emit MetaStartupNotification::changed on sequence completion
This way handlers that want to know the get_complete() status will be able
to do so without further delays.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:42:09 +02:00
Carlos Garnacho
38ff01d6d0 core: Add MetaStartupSequence::complete signal
It was a vfunc so far, but we want things subscribing to it.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:42:04 +02:00
Carlos Garnacho
40103d6f41 core: Account for completed sequences in feedback updates
The sequences may stay completed in the list (eg. pending a focus request),
it's then confusing to show the "wait" cursor icon until they are really
gone.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:42:00 +02:00
Carlos Garnacho
ab7ef5f8bf core: Fix differing sequence timestamp precision expectations
Calculations were being done at places accounting on usec precision,
however those are still treated as having msec precision at places. Let's
consolidate for the latter since it requires less changes across the board
and usec precision doesn't buy us anything here.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:41:13 +02:00
Olivier Fourdan
2c1a951b6e wayland/output: Set user data of xdg_output resource
mutter would randomly crash in `send_xdg_output_events()` when changing
the fractional scaling:

  wl_resource_post_event ()
  zxdg_output_v1_send_logical_size ()
  send_xdg_output_events ()
  wayland_output_update_for_output ()
  meta_wayland_compositor_update_outputs ()
  on_monitors_changed ()
  g_closure_invoke ()
  signal_emit_unlocked_R ()
  g_signal_emit_valist ()
  _signal_emit ()
  meta_monitor_manager_notify_monitors_changed ()
  meta_monitor_manager_rebuild ()

This is because the xdg-output resource got freed but wasn't removed
from the list of resources.

Fix this by setting the user data of the xdg-output resource to the
corresponding `MetaWaylandOutput` so that the xdg-output resource
destructor can remove it from the list of resources.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/538
2019-04-15 15:41:47 +02:00
Jonas Dreßler
6ec330ccfa keybindings: Stop keybinding if a touch happens while Super is pressed
We use the combination of pressing Super and clicking+moving the mouse
to drag windows around and we also support pressing Super and using the
touchscreen to drag windows.

Since we don't want to show the overview when the Super key was used to
initiate a window drag, prevent showing the overview in case a
TOUCH_BEGIN or TOUCH_END event happened during the key was pressed.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/228

https://gitlab.gnome.org/GNOME/mutter/merge_requests/495
2019-04-15 11:10:47 +00:00
Daniel van Vugt
20c1295a33 cogl-winsys-glx: Fix frame notification race/leak
If a second `set_{sync,complete}_pending` was queued before the idle
handler had flushed the first then one of them would be forgotten.
It would stay queued forever and never emitted as a notification.

This could happen repeatedly causing a slow leak. But worse still,
`clutter-stage-cogl` would then have `pending_swaps` permanently stuck
above zero preventing the presentation timing logic from being used.

The problem is that a boolean can only count to one, but in some cases
(triple buffering, whether intentional or accidental #334) we need it to
count to two. So just change booleans to integers and count properly.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/216
2019-04-12 11:09:00 +08:00
Olivier Fourdan
fa4a787386 clutter/evdev: Toggle accessibility features from keyboard
The keyboard accessibility setting "enable" is actually even more
misleading that initially anticipated, as it does not control the
entire keyboard accessibility feature, but just the "enable by
keyboard" feature, i.e. being able to enable or disable stickykeys
or slowkeys using various keyboard actions.

Yet the accessibility features should still work even if the "enable"
setting is unset, those can be controlled by the accessibility menu in
GNOME Shell for example.

Change the clutter/evdev implementation to match that behavior as found
in the x11 backend, so both backends are now consistent.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/531
2019-04-11 13:51:43 +00:00
Olivier Fourdan
85b734fde8 clutter/device-manager: Small code cleanup
Use a `memcmp()` instead of checking every field in the structure to be
equal, it's both faster and less error prone.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/531
2019-04-11 13:51:43 +00:00
Pekka Paalanen
28419cdedf renderer/native: Check primary GPU supports EGL
Since "renderer/native: make EGL initialization failure not fatal" it is
possible, under specific failure conditions, to end up with a primary GPU whose
EGL initialization failed. That cannot work.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/521
2019-04-11 15:11:41 +03:00
Pekka Paalanen
3b46a8cd70 renderer/native: Make EGL initialization failure not fatal
The failure to initialize EGL does not necessarily mean the KMS device cannot
be used. The device could still be used as a "secondary GPU" with the CPU copy
mode.

If meta_renderer_native_create_renderer_gpu_data () fails,
meta_renderer_native_get_gpu_data () will return NULL, which may cause crashes.
This patch removes most of the failures, but does not fix the NULL dereferences
that will still happen if creating gpu data fails.

This patch reorders create_renderer_gpu_data_gbm () so that it fails hard only
if GBM device cannot be created, and otherwise always returns an initialized
gpu data structure. Users of the gpu data structure are responsible for
checking egl_display validity.

The GBM device creation failure is a hard failure because presumably GBM is
necessary for cursors.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/542
https://gitlab.gnome.org/GNOME/mutter/merge_requests/521
2019-04-11 15:11:41 +03:00
Jonas Ådahl
b2d0184c6e renderer-native: Freeze frames while retrying to page flip
We're currently always waiting for unfinished page flips before flipping
again. This is awkward when we are in an asynchronous retry-page-flip
loop, as we can synchronously wait for any KMS page flip event.

To avoid ending up with such situations, just freeze the frame clock
while we're retrying, then thaw it when we succeded.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:50:00 +00:00
Jonas Ådahl
808a75b231 renderer-native: Add helper to get backend from renderer
https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:49:59 +00:00
Jonas Ådahl
88e4ff7409 backend: Add API to freeze/thaw frame clock
It's just a thin wrapper around the ClutterStage API, with the intention
to hide the awkward nest of interdependent backends.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:49:59 +00:00
Jonas Ådahl
3cc3b7526c renderer-native: Fake page flipping slower when power saving
We rely on the frame clock to compress input events, thus if the frame
clock stops, input events are not dispatched. At the same time, there
is no reason to redraw at a full frame rate, as nothing will be
presented anyway, so slow down to 10Hz (compared to the most common
60Hz). Note that we'll only actually reach 10Hz if there is an active
animation being displayed, which won't happen e.g. if there is a screen
shield in the way.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:49:59 +00:00
Jonas Ådahl
53b59d8bff renderer-native: Fake page flipped if power saving when retrying
When we're in a page-flip retry loop due to the FIFO being full
(drmModePageFlip() failing with EBUSY), we should not continue to try
when starting to power save, as that means we're blocking new frames,
which itself blocks input events due to them being compressed using the
frame clock.

We'd also hit an assert assuming we only try to page flip when not power
saving.

Thus, fake we flipped if we ended up reaching a power saving state while
retrying.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/509

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:49:59 +00:00
Jonas Ådahl
40e7e5d356 renderer-native: Fix page flip retry timeout calculation
It tried to add a (implicitly casted) float to a uint64_t, and due to
floating point precision issues resulted in timestamps intended to be
in the future to actually be in the past. Fix this by first casting the
delay to an uint64_t, then add it to the time stamp.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:49:59 +00:00
Jonas Ådahl
4cae9b5b11 monitor-manager: Clean up DPMS state tracking
DPMS is configured from a bit all over the place: via D-Bus, via X11 and
when reading the current KMS state. Each of these places did it slightly
differently, directly poking at the field in MetaMonitorManager.

To make things a bit more managable, move the field into a new
MetaMonitorManagerPrivate, and add helpers to get and set the current
value. Prior to this, there were for example situations where the DPMS
setting was changed, but without signal listeners being notified about
it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
2019-04-02 13:49:59 +00:00
Jonas Ådahl
72aeeb8c37 ci: Blacklist .c and .h in the commit message subject prefix
`boxes.c: Do that` should be just `boxes: Do that`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/519
2019-04-02 11:42:44 +00:00
Jonas Ådahl
7b3dee2d97 ci: Nag about invalid commit message subject prefixes
Prefixes use an abbreviated form of the module or section being changed.
For example, changes to MetaBackend/meta-backend.c are prefixed with
`backend:` and generic changes to src/x11/ are prefixed `x11:`.

This extra nit picking check is meant to avoid using non-abbreviated
prefixes, e.g. `MetaBackend:`, or `meta-backend:`, other prefixes are
Currently consisting of only a "blacklist".

https://gitlab.gnome.org/GNOME/mutter/merge_requests/519
2019-04-02 11:42:44 +00:00
Jonas Ådahl
5199c7834d backends/native: Move underscan setting to MetaOutputKms
The 'underscan' property is a drm connector property, not a CRTC
property, so we would never find it. We also didn't advertise support
for the feature, meaning even if it was on the CRTC, Settings wouldn't
know about it.

Fix this by moving the property to where it belongs: in MetaOutputKms,
and properly advertise support for it if the property is found.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/507
2019-04-02 09:38:45 +00:00
Heiher
afe8610b4a cogl/texture: Implement is_get_data_supported on GLES textures
https://gitlab.gnome.org/GNOME/mutter/merge_requests/515
2019-04-02 09:15:14 +00:00
Daniel van Vugt
9d49e8abd0 launch-context: Swap reversed timestamp/workspace
The parameters had been mixed up for X11 sessions.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/505
2019-04-01 10:34:51 +00:00
Daniel Mustieles
4043d0b455 Updated Spanish translation 2019-04-01 10:30:08 +02:00
Carlos Garnacho
34ee46022e clutter: Fix check for keyboard a11y features
The typo was actually toggling the feature on for those who had it
disabled.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/529
2019-03-28 12:03:00 +01:00
Daniel van Vugt
ee507d9ab2 clutter-actor: Keep is_dirty unchanged for culled actors
In a multi-monitor setup there is a separate paint run for each monitor.
If an actor doesn't intersect the first monitor painted then it is culled
out for that monitor to save time. Unfortunately this would mean
`clutter_actor_paint` was setting `is_dirty = FALSE` before the actor had
yet been painted on any monitor.

This meant that effects like `ClutterOffscreenEffect` were not receiving
the flag `CLUTTER_EFFECT_PAINT_ACTOR_DIRTY` when they should have, and
so would rightfully think they don't need to do a full internal
invalidation. So `ClutterOffscreenEffect`, and probably other effects,
did not repaint correctly unless on the first monitor in the list.

The fix is to simply avoid setting `is_dirty = FALSE` on those paint
runs where the actor has been culled out (`clutter_actor_continue_paint`
wasn't called). It is only safe to clear the flag after
`clutter_actor_continue_paint` has been called at least once per stage
paint.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1049
https://gitlab.gnome.org/GNOME/mutter/merge_requests/511
2019-03-28 17:42:01 +08:00
Jan Alexander Steffens (heftig)
28e0a7bfb5 wayland/xdg-shell: Correct window menu position in logical layout mode
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/527
2019-03-26 22:41:57 +01:00
Goran Vidović
58f7059ea4 Update Croatian translation 2019-03-26 11:41:13 +00:00
Daniel van Vugt
d15e11bfe7 background: Shrink wallpaper using LINEAR_MIPMAP_LINEAR
Commit 8e9184b6 added filtering to avoid image jaggies when downscaling
but used `LINEAR_MIPMAP_NEAREST`. In some situations this could lead to
GL choosing a single lower resolution mipmap and then upscaling it, hence
slightly blurry.

We don't want to revert that change since it avoids aliasing jaggies, so
let's use `LINEAR_MIPMAP_LINEAR` instead. This provides the highest quality
filtering that GL can do and avoids the situation of GL using a single
mipmap that's lower resolution than the screen. Now it will blend that one
with the next mipmap which is higher resolution than the screen. This still
avoids jaggies but also maintains 1px resolution.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1105
https://gitlab.gnome.org/GNOME/mutter/merge_requests/505
2019-03-26 11:38:52 +08:00
Jonas Ådahl
1eabaf12da renderer/native: Make the EGLStreams operate in mailbox mode
This means eglSwapBuffers() wont dead lock if there is an old buffer pending
page flip. This could happen after e.g. mode changes or for other reasons.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/485
2019-03-25 17:29:25 +00:00
Jonas Ådahl
fe86694ddd renderer/native: Make EGLStream page flip errors non-fatal
Just continue rendering; we don't care if we were busy once, as it'll most
likely work when we flip the next time.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/485
2019-03-25 17:29:25 +00:00
Carlos Garnacho
a1969c98cd wayland: Defer text_input.done on an idle
With the right priority so we hopefully group events properly.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/499
https://gitlab.gnome.org/GNOME/gtk/issues/1365
2019-03-25 14:55:12 +00:00
Carlos Garnacho
47663c7e0f clutter: Drop no longer necessary API
clutter_input_device_get_physical_size was just used for device mapping
heuristics in MetaInputMapper. It now started using the info from udev
on for both backends, so this means this clutter API is no longer
necessary.

https://gitlab.gnome.org/GNOME/mutter/issues/514
2019-03-25 14:08:40 +01:00
Carlos Garnacho
9843e21fff backends: Use udev to determine absolute input devices' size
Use the ID_INPUT_WIDTH_MM/ID_INPUT_HEIGHT_MM udev properties to figure out
absolute input devices' physical size. This works across both backends, and
requires less moving pieces to have it get the right results.

Concretely, fixes size detection on X11/libinput, which makes touchscreen
mapping go wrong.

https://gitlab.gnome.org/GNOME/mutter/issues/514
2019-03-25 14:08:40 +01:00
Olivier Fourdan
5c27bf6a2b clutter/evdev: Fix toggling accessibility features from keyboard
Enabling keyboard accessibility features on Wayland from the keyboard
was wrongly assumed to be controlled by the "togglekeys" setting,
whereas it should be simply controlled by the "enable" setting.

As "togglekeys" is off by default and doesn't have a UI option to
enable, that would prevent turning on or off the keyboard accessibility
features using the keyboard.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/501
2019-03-20 18:41:56 +01:00
Carlos Garnacho
f0b9654deb core: Remove startup sequences after timeout
The complete/remove semantics were split to cater for presenting windows,
so we must now separately do both here.

Related: https://gitlab.gnome.org/GNOME/mutter/issues/501
2019-03-18 18:06:01 +00:00
Florian Müllner
a1e325f749 build: Don't use absolute paths with subdir keyword
Meson 0.50.0 made passing an absolute path to install_headers()'
subdir keyword a fatal error. This means we have to track both
relative (to includedir) paths for header subdirs and absolute
paths for generated headers now :-(

https://gitlab.gnome.org/GNOME/mutter/merge_requests/492
2019-03-18 12:37:14 +00:00
Jonas Ådahl
00b4556051 constraints: Don't use intersection when sliding with custom rule
If an intersection is empty, the (x, y) coordinates are undefined, so
just use the work area and in-progress constrained window rect when
sliding according to the SLIDE_X or SLIDE_Y custom placement rule.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
86b5247770 constraints: Only get parent rect once when placement rule constraining
We got it in a switch case, then again when finalizing. Only get it once
instead.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
23f31e518e constraints: Only readjust placement constraint when not checking
When check_only is TRUE, the constraint should not be applied, just
checked. We failed to comply here when a placed transient window was
to be moved together with its parent, updating the window position
directly even if check_only was TRUE.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
f580b28a27 window: Replace placement constrained bool with state
Using an actual state instead of a boolean makes it clearer it's a state
that changes. Eventually we might add more state too.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
b4f1569640 window: Unmanage rule placed window if ending up outside of parent
If a client maps a persistent popup with a placement rule, then resizes
the parent window so that the popup ends up outside of the parent,
unmanage the popup and log a warning about the client being buggy.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
f2d7165a52 window: Don't try to move hidden attached windows
When a parent window is moved, attached windows (attached modal dialogs
or popups) is moved with it. This is problematic when such a window
hasn't been shown yet (e.g. a popup that has been configured but not
shown), as it'll mean we try to constrain an empty window. Avoid this
issue by not trying to auto-move empty windows.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
1bd3c13fe1 wayland/xdg-shell: Split out popup placement out of setup finish
Makes the function slightly more comprehensible.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Jonas Ådahl
5d1eccfb6f boxes: Fix spelling in API
Change adjecent to adjacent.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
2019-03-17 14:12:40 +00:00
Khaled Hosny
c96cf0608d Update Arabic translation 2019-03-15 23:42:49 +02:00
Erik Kurzinger
056c45fe0c wayland/buffer: Try realizing EGLStream before EGLImage buffer
Currently, it is assumed that if querying the EGL_TEXTURE_FORMAT of a
Wayland buffer succeeds it is an EGLImage. However, this assumption will no
longer hold on upcoming versions of the NVIDIA EGL Wayland driver which
will include support for querying this attribute for EGLStream buffers as
well. Hence, we need to check if buffers are EGLStreams first.

Fixes #488
https://gitlab.gnome.org/GNOME/mutter/merge_requests/477
2019-03-14 14:39:52 -07:00
Tom Briden
2ac7f7f1e5 build: Make libsystemd an optional dependency
Otherwise it errors out before checking for elogind instead

https://gitlab.gnome.org/GNOME/mutter/merge_requests/491
2019-03-12 13:39:15 +00:00
Pablo Barciela
318164779c boxes: Actually check for rectangle containment
Fixes condition duplicated:

          /* If a contains b, just remove b */
          if (meta_rectangle_contains_rect (a, b))
            {
              delete_me = other;
            }
          /* If b contains a, just remove a */
          else if (meta_rectangle_contains_rect (a, b))
            {
              delete_me = compare;
            }

Closes https://gitlab.gnome.org/GNOME/mutter/issues/480
2019-03-12 05:03:53 +01:00
Florian Müllner
7bd33e7b00 frame: Remove flashing support
It's now unused.

https://gitlab.gnome.org/GNOME/mutter/issues/491
2019-03-12 00:27:07 +00:00
Florian Müllner
f8d62da2dc bell: Always flash window instead of frame
Traditionally visual alerts were implemented by flashing the focus
window's frame. As that only works for windows that we decorate,
flashing the whole window was added as a fallback for client-decorated
windows.

However that introduces some confusing inconsistency, better to just
always flash the entire window.

https://gitlab.gnome.org/GNOME/mutter/issues/491
2019-03-12 00:27:07 +00:00
Marco Trevisan (Treviño)
303e02bdac monitor: Fix indentation style on foreach functions
https://gitlab.gnome.org/GNOME/mutter/merge_requests/488
2019-03-12 00:15:43 +00:00
Marco Trevisan (Treviño)
e2525f286d monitor: Fix indentation style on calculate_crtc_pos and friends
https://gitlab.gnome.org/GNOME/mutter/merge_requests/488
2019-03-12 00:15:43 +00:00
Marco Trevisan (Treviño)
9b8510ac56 monitor: Fix indentation style on calculate_supported_scales and friends
https://gitlab.gnome.org/GNOME/mutter/merge_requests/488
2019-03-12 00:15:42 +00:00
Florian Müllner
8a87e87a05 shadow-factory: Update shadow of attached modals
When commit 91c6a144da synced shadows with Adwaita, it removed the
shadow completely from attached modal dialogs. However Adwaita uses
the same shadow for all dialogs (modal or not), so do the same here.

https://gitlab.gnome.org/GNOME/mutter/issues/490
2019-03-12 00:05:42 +00:00
Florian Müllner
9aca31c814 cogl: Introspect CoglTexture2D(Sliced)
gnome-shell cannot use CoglTexture if gjs can't tell that an object
in question implements the CoglTexture interface.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1020
https://gitlab.gnome.org/GNOME/mutter/merge_requests/482
2019-03-11 23:57:08 +00:00
Adam Jackson
a555a2c8eb cogl: Remove unused CoglTextureDriver::try_setting_gl_border_color
https://gitlab.gnome.org/GNOME/mutter/merge_requests/480
2019-03-11 23:50:10 +00:00
Florian Müllner
32504ae917 meta-monitor: Remove useless variable
Since commit f76b3edf9c, the variable is never set to TRUE and
we can simply remove it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/475
2019-03-11 23:44:46 +00:00
Benjamin Berg
80ceeb2848 keybindings: Fix theoretical memory leak while ungrabbing
In the unlikely event that one tries to ungrab an action which does not
exist, a small leak could occur. Fix this by using g_autofree.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/478
2019-03-11 23:39:25 +00:00
Florian Müllner
1574099449 prefs: Change default of show-fallback-app-menu
The app menu always was a GNOME-only thing, so after it was removed this
cycle, assuming that it is not displayed by the environment is a better
default.

https://gitlab.gnome.org/GNOME/mutter/issues/493
2019-03-11 23:30:10 +00:00
77 changed files with 1857 additions and 1359 deletions

View File

@@ -23,9 +23,35 @@ function commit_message_has_url() {
return $?
}
function commit_message_subject_is_compliant() {
commit=$1
commit_message_subject=$(git show -s --format='format:%s' $commit)
if echo "$commit_message_subject" | grep -qe "\(^meta-\|^Meta\)"; then
echo " - message subject should not be prefixed with 'meta-' or 'Meta'"
return 1
fi
if echo "$commit_message_subject" | grep -qe "\.[ch]:"; then
echo " - message subject prefix should not include .c, .h, etc."
return 1
fi
return 0
}
for commit in $commits; do
commit_short=$(echo $commit | cut -c -8)
if ! commit_message_has_url $commit; then
echo "Missing merge request or issue URL on commit $(echo $commit | cut -c -8)"
echo "Missing merge request or issue URL on commit $commit_short"
exit 1
fi
errors=$(commit_message_subject_is_compliant $commit)
if [ $? != 0 ]; then
echo "Commit message for $commit_short is not compliant:"
echo "$errors"
exit 1
fi
done

View File

@@ -4007,12 +4007,12 @@ clutter_actor_paint (ClutterActor *self)
pick_mode == CLUTTER_PICK_NONE))
_clutter_actor_draw_paint_volume (self);
done:
/* If we make it here then the actor has run through a complete
paint run including all the effects so it's no longer dirty */
if (pick_mode == CLUTTER_PICK_NONE)
priv->is_dirty = FALSE;
done:
if (clip_set)
{
CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);

View File

@@ -167,10 +167,6 @@ struct _ClutterInputDeviceClass
gboolean (* is_grouped) (ClutterInputDevice *device,
ClutterInputDevice *other_device);
gboolean (* get_physical_size) (ClutterInputDevice *device,
gdouble *width,
gdouble *height);
/* Keyboard accessbility */
void (* process_kbd_a11y_event) (ClutterEvent *event,
ClutterInputDevice *device,

View File

@@ -550,13 +550,7 @@ static gboolean
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
ClutterKbdA11ySettings *b)
{
return (a->controls == b->controls &&
a->slowkeys_delay == b->slowkeys_delay &&
a->debounce_delay == b->debounce_delay &&
a->timeout_delay == b->timeout_delay &&
a->mousekeys_init_delay == b->mousekeys_init_delay &&
a->mousekeys_max_speed == b->mousekeys_max_speed &&
a->mousekeys_accel_time == b->mousekeys_accel_time);
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
}
void

View File

@@ -2284,15 +2284,3 @@ clutter_input_device_is_grouped (ClutterInputDevice *device,
return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device);
}
gboolean
clutter_input_device_get_physical_size (ClutterInputDevice *device,
gdouble *width,
gdouble *height)
{
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->get_physical_size (device,
width,
height);
}

View File

@@ -171,10 +171,6 @@ void clutter_input_device_set_mapping_mode (ClutterInputDev
CLUTTER_EXPORT
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
ClutterInputDevice *other_device);
CLUTTER_EXPORT
gboolean clutter_input_device_get_physical_size (ClutterInputDevice *device,
gdouble *width,
gdouble *height);
G_END_DECLS

View File

@@ -676,7 +676,7 @@ stop_toggle_slowkeys (ClutterInputDeviceEvdev *device)
}
static void
handle_togglekeys_press (ClutterEvent *event,
handle_enablekeys_press (ClutterEvent *event,
ClutterInputDeviceEvdev *device)
{
if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R)
@@ -698,7 +698,7 @@ handle_togglekeys_press (ClutterEvent *event,
}
static void
handle_togglekeys_release (ClutterEvent *event,
handle_enablekeys_release (ClutterEvent *event,
ClutterInputDeviceEvdev *device)
{
if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R)
@@ -1132,8 +1132,13 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
goto emit_event;
if (!device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
goto emit_event;
if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
{
if (event->type == CLUTTER_KEY_PRESS)
handle_enablekeys_press (event, device_evdev);
else
handle_enablekeys_release (event, device_evdev);
}
if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
{
@@ -1145,14 +1150,6 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
return; /* swallow event */
}
if (device_evdev->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED)
{
if (event->type == CLUTTER_KEY_PRESS)
handle_togglekeys_press (event, device_evdev);
else
handle_togglekeys_release (event, device_evdev);
}
if ((device_evdev->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_ENABLED) &&
(get_debounce_delay (device) != 0))
{
@@ -1266,18 +1263,6 @@ clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device,
GINT_TO_POINTER (touch_state->device_slot));
}
static gboolean
clutter_input_device_evdev_get_physical_size (ClutterInputDevice *device,
gdouble *width,
gdouble *height)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
return libinput_device_get_size (libinput_device, width, height) == 0;
}
static void
clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
{
@@ -1293,7 +1278,6 @@ clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
klass->get_group_n_modes = clutter_input_device_evdev_get_group_n_modes;
klass->is_grouped = clutter_input_device_evdev_is_grouped;
klass->process_kbd_a11y_event = clutter_input_device_evdev_process_kbd_a11y_event;
klass->get_physical_size = clutter_input_device_evdev_get_physical_size;
obj_props[PROP_DEVICE_MATRIX] =
g_param_spec_boxed ("device-matrix",

View File

@@ -1,3 +1,4 @@
clutter_clutter_includesubdir = join_paths(clutter_includesubdir, 'clutter')
clutter_clutter_includedir = join_paths(clutter_includedir, 'clutter')
clutter_headers = [
@@ -577,16 +578,16 @@ if have_introspection
endif
install_headers(clutter_headers,
subdir: clutter_clutter_includedir)
subdir: clutter_clutter_includesubdir)
install_headers(cally_headers,
subdir: join_paths(clutter_includedir, 'cally'))
subdir: join_paths(clutter_includesubdir, 'cally'))
install_headers(clutter_deprecated_headers,
subdir: join_paths(clutter_clutter_includedir, 'deprecated'))
subdir: join_paths(clutter_clutter_includesubdir, 'deprecated'))
install_headers(clutter_x11_headers,
subdir: join_paths(clutter_clutter_includedir, 'x11'))
subdir: join_paths(clutter_clutter_includesubdir, 'x11'))
pkg.generate(libmutter_clutter,
name: 'Mutters Clutter',

View File

@@ -180,56 +180,6 @@ clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device,
return button_group == (int) group;
}
static gboolean
clutter_input_device_xi2_get_physical_size (ClutterInputDevice *device,
gdouble *width,
gdouble *height)
{
Display *xdisplay;
XIDeviceInfo *dev_info;
gdouble w = 0, h = 0;
int i, n_info, device_id;
xdisplay = clutter_x11_get_default_display ();
device_id = clutter_input_device_get_device_id (device);
clutter_x11_trap_x_errors ();
dev_info = XIQueryDevice (xdisplay, device_id, &n_info);
if (clutter_x11_untrap_x_errors ())
return FALSE;
if (!dev_info)
return FALSE;
for (i = 0; i < dev_info->num_classes; i++)
{
XIValuatorClassInfo *valuator;
gdouble *value;
if (dev_info->classes[i]->type != XIValuatorClass)
continue;
valuator = (XIValuatorClassInfo *) dev_info->classes[i];
if (valuator->label == XInternAtom (xdisplay, "Abs X", True) ||
valuator->label == XInternAtom (xdisplay, "Abs MT Position X", True))
value = &w;
else if (valuator->label == XInternAtom (xdisplay, "Abs Y", True) ||
valuator->label == XInternAtom (xdisplay, "Abs MT Position Y", True))
value = &h;
else
continue;
*value = (valuator->max - valuator->min) * 1000 / valuator->resolution;
}
XIFreeDeviceInfo (dev_info);
*width = w;
*height = h;
return (w > 0 && h > 0);
}
static void
clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
{
@@ -243,7 +193,6 @@ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
device_class->is_grouped = clutter_input_device_xi2_is_grouped;
device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes;
device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button;
device_class->get_physical_size = clutter_input_device_xi2_get_physical_size;
}
static void

View File

@@ -1,4 +1,5 @@
clutter_includedir = join_paths(pkgincludedir, 'clutter')
clutter_includesubdir = join_paths(pkgname, 'clutter')
clutter_includedir = join_paths(includedir, clutter_includesubdir)
clutter_srcdir = join_paths(top_srcdir, 'clutter')
clutter_builddir = join_paths(builddir, 'clutter')

View File

@@ -27,9 +27,9 @@ libmutter_cogl_gles2 = shared_library('mutter-cogl-gles2-' + libmutter_api_versi
install: true,
)
cogl_gles2_includedir = join_paths(cogl_includedir, 'cogl-gles2/GLES2')
cogl_gles2_includesubdir = join_paths(cogl_includesubdir, 'cogl-gles2/GLES2')
install_headers(cogl_gles2_public_headers,
subdir: cogl_gles2_includedir)
subdir: cogl_gles2_includesubdir)
pkg.generate(libmutter_cogl_gles2,
name: 'CoglGles2',

View File

@@ -70,8 +70,8 @@ if have_introspection
)
endif
cogl_pango_includedir = join_paths(cogl_includedir, 'cogl-pango')
install_headers(cogl_pango_public_headers, subdir: cogl_pango_includedir)
cogl_pango_includesubdir = join_paths(cogl_includesubdir, 'cogl-pango')
install_headers(cogl_pango_public_headers, subdir: cogl_pango_includesubdir)
pkg.generate(libmutter_cogl_pango,
name: 'CoglPango',

View File

@@ -1,3 +1,4 @@
cogl_path_includesubdir = join_paths(cogl_includesubdir, 'cogl-path')
cogl_path_includedir = join_paths(cogl_includedir, 'cogl-path')
cogl_path_public_headers = [
@@ -76,7 +77,7 @@ libmutter_cogl_path_dep = declare_dependency(
)
install_headers(cogl_path_public_headers,
subdir: cogl_path_includedir)
subdir: cogl_path_includesubdir)
pkg.generate(libmutter_cogl_path,
name: 'CoglPath',

View File

@@ -78,7 +78,7 @@ typedef struct _CoglTexture2DSliced CoglTexture2DSliced;
GType cogl_texture_2d_sliced_get_gtype (void);
/**
* cogl_texture_2d_sliced_new_with_size:
* cogl_texture_2d_sliced_new_with_size: (skip)
* @ctx: A #CoglContext
* @width: The virtual width of your sliced texture.
* @height: The virtual height of your sliced texture.
@@ -125,7 +125,7 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
int max_waste);
/**
* cogl_texture_2d_sliced_new_from_file:
* cogl_texture_2d_sliced_new_from_file: (skip)
* @ctx: A #CoglContext
* @filename: the file to load
* @max_waste: The threshold of how wide a strip of wasted texels
@@ -173,7 +173,7 @@ cogl_texture_2d_sliced_new_from_file (CoglContext *ctx,
CoglError **error);
/**
* cogl_texture_2d_sliced_new_from_data:
* cogl_texture_2d_sliced_new_from_data: (skip)
* @ctx: A #CoglContext
* @width: width of texture in pixels
* @height: height of texture in pixels

View File

@@ -86,7 +86,7 @@ gboolean
cogl_is_texture_2d (void *object);
/**
* cogl_texture_2d_new_with_size:
* cogl_texture_2d_new_with_size: (skip)
* @ctx: A #CoglContext
* @width: Width of the texture to allocate
* @height: Height of the texture to allocate
@@ -120,7 +120,7 @@ cogl_texture_2d_new_with_size (CoglContext *ctx,
int height);
/**
* cogl_texture_2d_new_from_file:
* cogl_texture_2d_new_from_file: (skip)
* @ctx: A #CoglContext
* @filename: the file to load
* @error: A #CoglError to catch exceptional errors or %NULL
@@ -154,7 +154,7 @@ cogl_texture_2d_new_from_file (CoglContext *ctx,
CoglError **error);
/**
* cogl_texture_2d_new_from_data:
* cogl_texture_2d_new_from_data: (skip)
* @ctx: A #CoglContext
* @width: width of texture in pixels
* @height: height of texture in pixels
@@ -231,6 +231,9 @@ cogl_texture_2d_new_from_data (CoglContext *ctx,
CoglTexture2D *
cogl_texture_2d_new_from_bitmap (CoglBitmap *bitmap);
/**
* cogl_egl_texture_2d_new_from_image: (skip)
*/
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
/* NB: The reason we require the width, height and format to be passed
* even though they may seem redundant is because GLES 1/2 don't
@@ -247,6 +250,9 @@ typedef gboolean (*CoglTexture2DEGLImageExternalAlloc) (CoglTexture2D *tex_2d,
gpointer user_data,
GError **error);
/**
* cogl_texture_2d_new_from_egl_image_external: (skip)
*/
CoglTexture2D *
cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx,
int width,

View File

@@ -171,15 +171,6 @@ struct _CoglTextureDriver
int height,
int depth);
/*
* This driver abstraction is needed because GLES doesn't support setting
* a texture border color.
*/
void
(* try_setting_gl_border_color) (CoglContext *ctx,
GLuint gl_target,
const GLfloat *transparent_color);
/*
* It may depend on the driver as to what texture targets may be used when
* creating a foreign texture. E.g. OpenGL supports ARB_texture_rectangle

View File

@@ -485,19 +485,6 @@ _cogl_texture_driver_size_supported (CoglContext *ctx,
return new_width != 0;
}
static void
_cogl_texture_driver_try_setting_gl_border_color
(CoglContext *ctx,
GLuint gl_target,
const GLfloat *transparent_color)
{
/* Use a transparent border color so that we can leave the
color buffer alone when using texture co-ordinates
outside of the texture */
GE( ctx, glTexParameterfv (gl_target, GL_TEXTURE_BORDER_COLOR,
transparent_color) );
}
static gboolean
_cogl_texture_driver_allows_foreign_gl_target (CoglContext *ctx,
GLenum gl_target)
@@ -541,7 +528,6 @@ _cogl_texture_driver_gl =
_cogl_texture_driver_gl_get_tex_image,
_cogl_texture_driver_size_supported,
_cogl_texture_driver_size_supported_3d,
_cogl_texture_driver_try_setting_gl_border_color,
_cogl_texture_driver_allows_foreign_gl_target,
_cogl_texture_driver_find_best_gl_get_data_format
};

View File

@@ -429,6 +429,12 @@ _cogl_driver_update_features (CoglContext *context,
return TRUE;
}
static gboolean
_cogl_driver_texture_2d_is_get_data_supported (CoglTexture2D *tex_2d)
{
return FALSE;
}
const CoglDriverVtable
_cogl_driver_gles =
{
@@ -453,7 +459,7 @@ _cogl_driver_gles =
_cogl_texture_2d_gl_get_gl_handle,
_cogl_texture_2d_gl_generate_mipmap,
_cogl_texture_2d_gl_copy_from_bitmap,
NULL, /* texture_2d_is_get_data_supported */
_cogl_driver_texture_2d_is_get_data_supported,
NULL, /* texture_2d_get_data */
_cogl_gl_flush_attributes_state,
_cogl_clip_stack_gl_flush,

View File

@@ -590,15 +590,6 @@ _cogl_texture_driver_size_supported (CoglContext *ctx,
return width <= max_size && height <= max_size;
}
static void
_cogl_texture_driver_try_setting_gl_border_color
(CoglContext *ctx,
GLuint gl_target,
const GLfloat *transparent_color)
{
/* FAIL! */
}
static gboolean
_cogl_texture_driver_allows_foreign_gl_target (CoglContext *ctx,
GLenum gl_target)
@@ -636,7 +627,6 @@ _cogl_texture_driver_gles =
_cogl_texture_driver_gl_get_tex_image,
_cogl_texture_driver_size_supported,
_cogl_texture_driver_size_supported_3d,
_cogl_texture_driver_try_setting_gl_border_color,
_cogl_texture_driver_allows_foreign_gl_target,
_cogl_texture_driver_find_best_gl_get_data_format
};

View File

@@ -1,3 +1,4 @@
cogl_cogl_includesubdir = join_paths(cogl_includesubdir, 'cogl')
cogl_cogl_includedir = join_paths(cogl_includedir, 'cogl')
cdata = configuration_data()
@@ -89,6 +90,8 @@ cogl_headers = [
'cogl-pipeline-layer-state.h',
'cogl-primitives.h',
'cogl-texture.h',
'cogl-texture-2d.h',
'cogl-texture-2d-sliced.h',
'cogl-types.h',
'cogl.h',
]
@@ -117,10 +120,8 @@ cogl_nonintrospected_headers = [
'cogl-matrix-stack.h',
'cogl-poll.h',
'cogl-texture-3d.h',
'cogl-texture-2d.h',
'cogl-texture-2d-gl.h',
'cogl-texture-rectangle.h',
'cogl-texture-2d-sliced.h',
'cogl-sub-texture.h',
'cogl-atlas-texture.h',
'cogl-meta-texture.h',
@@ -514,16 +515,16 @@ install_headers([
cogl_headers,
cogl_nonintrospected_headers,
],
subdir: cogl_cogl_includedir)
subdir: cogl_cogl_includesubdir)
install_headers([
cogl_deprecated_headers,
cogl_deprecated_nonintrospected_headers,
],
subdir: join_paths(cogl_cogl_includedir, 'deprecated'))
subdir: join_paths(cogl_cogl_includesubdir, 'deprecated'))
install_headers(cogl_gl_prototype_headers,
subdir: join_paths(cogl_cogl_includedir, 'gl-prototypes'))
subdir: join_paths(cogl_cogl_includesubdir, 'gl-prototypes'))
pkg.generate(libmutter_cogl,
name: 'Cogl',

View File

@@ -99,9 +99,9 @@ typedef struct _CoglOnscreenGLX
CoglOnscreenXlib _parent;
GLXDrawable glxwin;
uint32_t last_swap_vsync_counter;
gboolean pending_sync_notify;
gboolean pending_complete_notify;
gboolean pending_resize_notify;
uint32_t pending_sync_notify;
uint32_t pending_complete_notify;
uint32_t pending_resize_notify;
GThread *swap_wait_thread;
GQueue *swap_wait_queue;
@@ -347,35 +347,35 @@ flush_pending_notifications_cb (void *data,
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
gboolean pending_sync_notify = glx_onscreen->pending_sync_notify;
gboolean pending_complete_notify = glx_onscreen->pending_complete_notify;
/* If swap_region is called then notifying the sync event could
* potentially immediately queue a subsequent pending notify so
* we need to clear the flag before invoking the callback */
glx_onscreen->pending_sync_notify = FALSE;
glx_onscreen->pending_complete_notify = FALSE;
if (pending_sync_notify)
while (glx_onscreen->pending_sync_notify > 0 ||
glx_onscreen->pending_complete_notify > 0 ||
glx_onscreen->pending_resize_notify > 0)
{
CoglFrameInfo *info = g_queue_peek_head (&onscreen->pending_frame_infos);
if (glx_onscreen->pending_sync_notify > 0)
{
CoglFrameInfo *info =
g_queue_peek_head (&onscreen->pending_frame_infos);
_cogl_onscreen_notify_frame_sync (onscreen, info);
}
_cogl_onscreen_notify_frame_sync (onscreen, info);
glx_onscreen->pending_sync_notify--;
}
if (pending_complete_notify)
{
CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);
if (glx_onscreen->pending_complete_notify > 0)
{
CoglFrameInfo *info =
g_queue_pop_head (&onscreen->pending_frame_infos);
_cogl_onscreen_notify_complete (onscreen, info);
_cogl_onscreen_notify_complete (onscreen, info);
cogl_object_unref (info);
glx_onscreen->pending_complete_notify--;
}
cogl_object_unref (info);
}
if (glx_onscreen->pending_resize_notify)
{
_cogl_onscreen_notify_resize (onscreen);
glx_onscreen->pending_resize_notify = FALSE;
if (glx_onscreen->pending_resize_notify > 0)
{
_cogl_onscreen_notify_resize (onscreen);
glx_onscreen->pending_resize_notify--;
}
}
}
}
@@ -417,7 +417,7 @@ set_sync_pending (CoglOnscreen *onscreen)
NULL);
}
glx_onscreen->pending_sync_notify = TRUE;
glx_onscreen->pending_sync_notify++;
}
static void
@@ -440,7 +440,7 @@ set_complete_pending (CoglOnscreen *onscreen)
NULL);
}
glx_onscreen->pending_complete_notify = TRUE;
glx_onscreen->pending_complete_notify++;
}
static void
@@ -533,7 +533,7 @@ notify_resize (CoglContext *context,
NULL);
}
glx_onscreen->pending_resize_notify = TRUE;
glx_onscreen->pending_resize_notify++;
if (!xlib_onscreen->is_foreign_xwin)
{

View File

@@ -1,4 +1,5 @@
cogl_includedir = join_paths(pkgincludedir, 'cogl')
cogl_includesubdir = join_paths(pkgname, 'cogl')
cogl_includedir = join_paths(includedir, cogl_includesubdir)
cogl_srcdir = join_paths(top_srcdir, 'cogl')
cogl_builddir = join_paths(builddir, 'cogl')

View File

@@ -46,9 +46,6 @@
/* Building with SM support */
#mesondefine HAVE_SM
/* Building with startup notification support */
#mesondefine HAVE_STARTUP_NOTIFICATION
/* Path to Xwayland executable */
#mesondefine XWAYLAND_PATH

View File

@@ -178,7 +178,7 @@ if have_native_backend
libgbm_dep = dependency('gbm', version: gbm_req)
libinput_dep = dependency('libinput', version: libinput_req)
libsystemd_dep = dependency('libsystemd')
libsystemd_dep = dependency('libsystemd', required: false)
if libsystemd_dep.found()
logind_provider_dep = libsystemd_dep
else
@@ -225,12 +225,6 @@ if have_pango_ft2
pangoft2_dep = dependency('pangoft2')
endif
have_startup_notification = get_option('startup_notification')
if have_startup_notification
libstartup_notification_dep = dependency('libstartup-notification-1.0',
version: libstartup_notification_req)
endif
have_remote_desktop = get_option('remote_desktop')
if have_remote_desktop
libpipewire_dep = dependency('libpipewire-0.2', version: libpipewire_req)
@@ -334,7 +328,6 @@ cdata.set('HAVE_WAYLAND_EGLSTREAM', have_wayland_eglstream)
cdata.set('HAVE_LIBGUDEV', have_libgudev)
cdata.set('HAVE_LIBWACOM', have_libwacom)
cdata.set('HAVE_SM', have_sm)
cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification)
cdata.set('HAVE_INTROSPECTION', have_introspection)
xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
@@ -399,7 +392,6 @@ output = [
' gudev.................... ' + have_libgudev.to_string(),
' Wacom.................... ' + have_libwacom.to_string(),
' SM....................... ' + have_sm.to_string(),
' Startup notification..... ' + have_startup_notification.to_string(),
' Introspection............ ' + have_introspection.to_string(),
'',
' Tests:',

817
po/ar.po
View File

@@ -4,15 +4,14 @@
# Arafat Medini <lumina@silverpen.de>, 2003.
# Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004.
# Djihed Afifi <djihed@gmail.com>, 2006.
# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017.
# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017, 2019.
# Anas Afif Emad <anas.e87@gmail.com>, 2008.
msgid ""
msgstr ""
"Project-Id-Version: metacity.HEAD\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&"
"keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-11-03 10:20+0200\n"
"PO-Revision-Date: 2017-11-03 10:22+0200\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-15 23:40+0200\n"
"PO-Revision-Date: 2019-03-15 23:42+0200\n"
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"Language: ar\n"
@@ -21,126 +20,599 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Virtaal 1.0.0-beta1\n"
"X-Generator: Virtaal 0.7.1\n"
"X-Project-Style: gnome\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
msgstr "الإبحار"
#: data/50-mutter-navigation.xml:9
msgid "Move window to workspace 1"
msgstr "انقل النافذة إلى مساحة العمل 1"
#: data/50-mutter-navigation.xml:12
msgid "Move window to workspace 2"
msgstr "انقل النافذة إلى مساحة العمل 2"
#: data/50-mutter-navigation.xml:15
msgid "Move window to workspace 3"
msgstr "انقل النافذة إلى مساحة العمل 3"
#: data/50-mutter-navigation.xml:18
msgid "Move window to workspace 4"
msgstr "انقل النافذة إلى مساحة العمل 4"
#: data/50-mutter-navigation.xml:21
msgid "Move window to last workspace"
msgstr "انقل النافذة إلى مساحة العمل الأخيرة"
#: data/50-mutter-navigation.xml:24
msgid "Move window one workspace up"
msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى"
#: data/50-mutter-navigation.xml:27
msgid "Move window one workspace down"
msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل"
#: data/50-mutter-navigation.xml:30
msgid "Move window one monitor to the left"
msgstr "انقل النافذة شاشة واحدة إلى اليسار"
#: data/50-mutter-navigation.xml:33
msgid "Move window one monitor to the right"
msgstr "انقل النافذة شاشة واحدة إلى اليمين"
#: data/50-mutter-navigation.xml:36
msgid "Move window one monitor up"
msgstr "انقل النافذة شاشة واحدة إلى الأعلى"
#: data/50-mutter-navigation.xml:39
msgid "Move window one monitor down"
msgstr "انقل النافذة شاشة واحدة إلى الأسفل"
#: data/50-mutter-navigation.xml:43
msgid "Switch applications"
msgstr "تنقل بين التطبيقات"
#: data/50-mutter-navigation.xml:48
msgid "Switch to previous application"
msgstr "انتقل إلى التطبيق السابق"
#: data/50-mutter-navigation.xml:52
msgid "Switch windows"
msgstr "تنقل بين النوافذ"
#: data/50-mutter-navigation.xml:57
msgid "Switch to previous window"
msgstr "انتقل إلى النافذة السابقة"
#: data/50-mutter-navigation.xml:61
msgid "Switch windows of an application"
msgstr "تنقل بين نوافذ التطبيق"
#: data/50-mutter-navigation.xml:66
msgid "Switch to previous window of an application"
msgstr "انتقل إلى نافذة التطبيق السابقة"
#: data/50-mutter-navigation.xml:70
msgid "Switch system controls"
msgstr "تنقل بين تحكمات النظام"
#: data/50-mutter-navigation.xml:75
msgid "Switch to previous system control"
msgstr "انتقل إلى تحكم النظام السابق"
#: data/50-mutter-navigation.xml:79
msgid "Switch windows directly"
msgstr "تنقل مباشرة بين النوافذ"
#: data/50-mutter-navigation.xml:84
msgid "Switch directly to previous window"
msgstr "انتقل مباشرة إلى النافذة السابقة"
#: data/50-mutter-navigation.xml:88
msgid "Switch windows of an app directly"
msgstr "تنقل مباشرة بين نوافذ التطبيق"
#: data/50-mutter-navigation.xml:93
msgid "Switch directly to previous window of an app"
msgstr "انتقل مباشرة إلى نافذة التطبيق السابقة"
#: data/50-mutter-navigation.xml:97
msgid "Switch system controls directly"
msgstr "تنقل مباشرة بين تحكمات النظام"
#: data/50-mutter-navigation.xml:102
msgid "Switch directly to previous system control"
msgstr "انتقل مباشرة إلى تحكم النظام السابق"
#: data/50-mutter-navigation.xml:105
msgid "Hide all normal windows"
msgstr "أخفِ كل النوافذ العادية"
#: data/50-mutter-navigation.xml:108
msgid "Switch to workspace 1"
msgstr "انتقل إلى مساحة العمل 1"
#: data/50-mutter-navigation.xml:111
msgid "Switch to workspace 2"
msgstr "انتقل إلى مساحة العمل 2"
#: data/50-mutter-navigation.xml:114
msgid "Switch to workspace 3"
msgstr "انتقل إلى مساحة العمل 3"
#: data/50-mutter-navigation.xml:117
msgid "Switch to workspace 4"
msgstr "انتقل إلى مساحة العمل 4"
#: data/50-mutter-navigation.xml:120
msgid "Switch to last workspace"
msgstr "انتقل إلى مساحة العمل الأخيرة"
#: data/50-mutter-navigation.xml:123
msgid "Move to workspace above"
msgstr "انقل لمساحة العمل أعلى"
#: data/50-mutter-navigation.xml:126
msgid "Move to workspace below"
msgstr "انقل لمساحة العمل أسفل"
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
msgid "System"
msgstr "النظام"
#: data/50-mutter-system.xml:8
msgid "Show the run command prompt"
msgstr "أظهر محث تشغيل أمر"
#: data/50-mutter-system.xml:10
msgid "Show the activities overview"
msgstr "أظهر نظرة عامة على الأنشطة"
#: data/50-mutter-wayland.xml:8
msgid "Restore the keyboard shortcuts"
msgstr "استعد اختصارات لوحة المفاتيح"
#: data/50-mutter-windows.xml:6
msgid "Windows"
msgstr "النوافذ"
#: data/50-mutter-windows.xml:8
msgid "Activate the window menu"
msgstr "فعّل قائمة النافذة"
#: data/50-mutter-windows.xml:10
msgid "Toggle fullscreen mode"
msgstr "بدّل نمط ملء الشاشة"
#: data/50-mutter-windows.xml:12
msgid "Toggle maximization state"
msgstr "بدّل حالة التكبير"
#: data/50-mutter-windows.xml:14
msgid "Maximize window"
msgstr "كبّر النّافذة"
#: data/50-mutter-windows.xml:16
msgid "Restore window"
msgstr "استعد النّافذة"
#: data/50-mutter-windows.xml:18
msgid "Close window"
msgstr "أغلق النّافذة"
#: data/50-mutter-windows.xml:20
msgid "Hide window"
msgstr "أخفِ النّافذة"
#: data/50-mutter-windows.xml:22
msgid "Move window"
msgstr "انقل النّافذة"
#: data/50-mutter-windows.xml:24
msgid "Resize window"
msgstr "حجّم النّافذة"
#: data/50-mutter-windows.xml:27
msgid "Toggle window on all workspaces or one"
msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل أو واحدة منها"
#: data/50-mutter-windows.xml:29
msgid "Raise window if covered, otherwise lower it"
msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك"
#: data/50-mutter-windows.xml:31
msgid "Raise window above other windows"
msgstr "ارفع النافذة فوق النوافذ الأخرى"
#: data/50-mutter-windows.xml:33
msgid "Lower window below other windows"
msgstr "اخفض النافذة تحت النوافذ الأخرى"
#: data/50-mutter-windows.xml:35
msgid "Maximize window vertically"
msgstr "كبّر النافذة رأسيا"
#: data/50-mutter-windows.xml:37
msgid "Maximize window horizontally"
msgstr "كبّر النافذة أفقيا"
#: data/50-mutter-windows.xml:41
msgid "View split on left"
msgstr "المنظور مقسوم على اليمين"
#: data/50-mutter-windows.xml:45
msgid "View split on right"
msgstr "المنظور مقسوم على اليسار"
#: data/mutter.desktop.in:4
msgid "Mutter"
msgstr "مَتَر"
#: data/org.gnome.mutter.gschema.xml.in:7
msgid "Modifier to use for extended window management operations"
msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ "
#: data/org.gnome.mutter.gschema.xml.in:8
msgid ""
"This key will initiate the “overlay”, which is a combination window overview "
"and application launching system. The default is intended to be the “Windows "
"key” on PC hardware. Its expected that this binding either the default or "
"set to the empty string."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:20
#, fuzzy
msgid "Attach modal dialogs"
msgstr "صندوق حوار سائد"
#: data/org.gnome.mutter.gschema.xml.in:21
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
"the parent window."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:30
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:31
msgid ""
"If enabled, dropping windows on vertical screen edges maximizes them "
"vertically and resizes them horizontally to cover half of the available "
"area. Dropping windows on the top screen edge maximizes them completely."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:40
msgid "Workspaces are managed dynamically"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:41
msgid ""
"Determines whether workspaces are managed dynamically or whether theres a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:50
msgid "Workspaces only on primary"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:51
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:59
msgid "No tab popup"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:60
msgid ""
"Determines whether the use of popup and highlight frame should be disabled "
"for window cycling."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:68
msgid "Delay focus changes until the pointer stops moving"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:69
msgid ""
"If set to true, and the focus mode is either “sloppy” or “mouse” then the "
"focus will not be changed immediately when entering a window, but only after "
"the pointer stops moving."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:79
msgid "Draggable border width"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:80
msgid ""
"The amount of total draggable borders. If the themes visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:89
msgid "Auto maximize nearly monitor sized windows"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:90
msgid ""
"If enabled, new windows that are initially the size of the monitor "
"automatically get maximized."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:98
msgid "Place new windows in the center"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:99
msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:141
msgid "Select window from tab popup"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:146
msgid "Cancel tab popup"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:151
#, fuzzy
msgid "Switch monitor configurations"
msgstr "غيّر الشاشة"
#: data/org.gnome.mutter.gschema.xml.in:156
msgid "Rotates the built-in monitor configuration"
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
#, fuzzy
msgid "Switch to VT 1"
msgstr "انتقل إلى مساحة العمل 1"
#: data/org.gnome.mutter.wayland.gschema.xml.in:10
#, fuzzy
msgid "Switch to VT 2"
msgstr "انتقل إلى مساحة العمل 2"
#: data/org.gnome.mutter.wayland.gschema.xml.in:14
#, fuzzy
msgid "Switch to VT 3"
msgstr "انتقل إلى مساحة العمل 3"
#: data/org.gnome.mutter.wayland.gschema.xml.in:18
#, fuzzy
msgid "Switch to VT 4"
msgstr "انتقل إلى مساحة العمل 4"
#: data/org.gnome.mutter.wayland.gschema.xml.in:22
#, fuzzy
msgid "Switch to VT 5"
msgstr "انتقل إلى مساحة العمل 5"
#: data/org.gnome.mutter.wayland.gschema.xml.in:26
#, fuzzy
msgid "Switch to VT 6"
msgstr "انتقل إلى مساحة العمل 6"
#: data/org.gnome.mutter.wayland.gschema.xml.in:30
#, fuzzy
msgid "Switch to VT 7"
msgstr "انتقل إلى مساحة العمل 7"
#: data/org.gnome.mutter.wayland.gschema.xml.in:34
#, fuzzy
msgid "Switch to VT 8"
msgstr "انتقل إلى مساحة العمل 8"
#: data/org.gnome.mutter.wayland.gschema.xml.in:38
#, fuzzy
msgid "Switch to VT 9"
msgstr "انتقل إلى مساحة العمل 9"
#: data/org.gnome.mutter.wayland.gschema.xml.in:42
#, fuzzy
msgid "Switch to VT 10"
msgstr "انتقل إلى مساحة العمل 10"
#: data/org.gnome.mutter.wayland.gschema.xml.in:46
#, fuzzy
msgid "Switch to VT 11"
msgstr "انتقل إلى مساحة العمل 11"
#: data/org.gnome.mutter.wayland.gschema.xml.in:50
#, fuzzy
msgid "Switch to VT 12"
msgstr "انتقل إلى مساحة العمل 12"
#: data/org.gnome.mutter.wayland.gschema.xml.in:54
msgid "Re-enable shortcuts"
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
msgid "Allow grabs with Xwayland"
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
msgid ""
"Allow keyboard grabs issued by X11 applications running in Xwayland to be "
"taken into account. For a X11 grab to be taken into account under Wayland, "
"the client must also either send a specific X11 ClientMessage to the root "
"window or be among the applications white-listed in key “xwayland-grab-"
"access-rules”."
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
msgid "Xwayland applications allowed to issue keyboard grabs"
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
msgid ""
"List the resource names or resource class of X11 windows either allowed or "
"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or "
"resource class of a given X11 window can be obtained using the command "
"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. "
"Values starting with “!” are blacklisted, which has precedence over the "
"whitelist, to revoke applications from the default system list. The default "
"system list includes the following applications: "
"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by "
"using the specific keyboard shortcut defined by the keybinding key “restore-"
"shortcuts”."
msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: ../src/backends/meta-input-settings.c:2167
#: src/backends/meta-input-settings.c:2424
#, c-format
msgid "Mode Switch (Group %d)"
msgstr ""
msgstr "تغيير الأوضاع (مجموعة %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: ../src/backends/meta-input-settings.c:2190
#: src/backends/meta-input-settings.c:2447
msgid "Switch monitor"
msgstr "غيّر الشاشة"
#: ../src/backends/meta-input-settings.c:2192
#: src/backends/meta-input-settings.c:2449
msgid "Show on-screen help"
msgstr "اعرض المساعدة على الشاشة"
#: ../src/backends/meta-monitor-manager.c:900
#: src/backends/meta-monitor-manager.c:955
msgid "Built-in display"
msgstr "شاشة مدمجة"
#: ../src/backends/meta-monitor-manager.c:923
#: src/backends/meta-monitor-manager.c:987
msgid "Unknown"
msgstr "غير معروفة"
#: ../src/backends/meta-monitor-manager.c:925
#: src/backends/meta-monitor-manager.c:989
msgid "Unknown Display"
msgstr "شاشة غير معروفة"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:933
#: src/backends/meta-monitor-manager.c:997
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor-manager.c:1005
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
"inches could not be calculated, e.g. Dell U2414H"
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: ../src/compositor/compositor.c:476
#: src/compositor/compositor.c:482
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
msgstr "يعمل مدير مزج آخر على الشاشة %i و العرض ”%s“."
#: ../src/core/bell.c:194
#: src/core/bell.c:192
msgid "Bell event"
msgstr "حدث جرس"
#: ../src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "فشل فتح عرض نظام نوافذ إكس ”%s“\n"
#: ../src/core/main.c:189
#: src/core/main.c:185
msgid "Disable connection to session manager"
msgstr "عطّل الاتصال بمدير الجلسة"
#: ../src/core/main.c:195
#: src/core/main.c:191
msgid "Replace the running window manager"
msgstr "استبدل بمدير النوافذ الذي يعمل"
#: ../src/core/main.c:201
#: src/core/main.c:197
msgid "Specify session management ID"
msgstr "حدّد رقم هويّة إدارة الجلسة"
#: ../src/core/main.c:206
#: src/core/main.c:202
msgid "X Display to use"
msgstr "معراض س الذي سيستعمل"
#: ../src/core/main.c:212
#: src/core/main.c:208
msgid "Initialize session from savefile"
msgstr "ابدأ الجلسة من ملف محفوظ"
#: ../src/core/main.c:218
#: src/core/main.c:214
msgid "Make X calls synchronous"
msgstr "اجعل نداءات س متزامنة"
#: ../src/core/main.c:225
#: src/core/main.c:221
msgid "Run as a wayland compositor"
msgstr ""
#: ../src/core/main.c:231
#: src/core/main.c:227
msgid "Run as a nested compositor"
msgstr ""
#: ../src/core/main.c:239
#: src/core/main.c:233
msgid "Run wayland compositor without starting Xwayland"
msgstr ""
#: src/core/main.c:241
msgid "Run as a full display server, rather than nested"
msgstr ""
#: src/core/main.c:247
msgid "Run with X11 backend"
msgstr ""
#. Translators: %s is a window title
#: ../src/core/meta-close-dialog-default.c:147
#: src/core/meta-close-dialog-default.c:151
#, c-format
msgid "“%s” is not responding."
msgstr "”‏%s“ لا يستجيب."
#: ../src/core/meta-close-dialog-default.c:149
#: src/core/meta-close-dialog-default.c:153
msgid "Application is not responding."
msgstr "لا يستجيب التطبيق"
#: ../src/core/meta-close-dialog-default.c:154
#: src/core/meta-close-dialog-default.c:158
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr "ربما ترغب في الانتظار قليلا ليُكمِل أو إجبار التطبيق على الإنهاء كُلّية."
#: ../src/core/meta-close-dialog-default.c:161
#: src/core/meta-close-dialog-default.c:165
msgid "_Force Quit"
msgstr "أ_جبر الإنهاء"
#: ../src/core/meta-close-dialog-default.c:161
#: src/core/meta-close-dialog-default.c:165
msgid "_Wait"
msgstr "ا_نتظر"
#: ../src/core/mutter.c:39
#: src/core/mutter.c:38
#, c-format
msgid ""
"mutter %s\n"
@@ -154,43 +626,52 @@ msgstr ""
"هذا برنامج حر، راجع المصدر لشروط النسخ.\n"
"لا يوجد أي ضمان: و لا حتى ضمان قابلية التسويق أو المناسبة لأي هدف.\n"
#: ../src/core/mutter.c:53
#: src/core/mutter.c:52
msgid "Print version"
msgstr "اطبع الإصدارة"
#: ../src/core/mutter.c:59
#: src/core/mutter.c:58
msgid "Mutter plugin to use"
msgstr "ملحق مَتَر الذي سيُستخدم"
#: ../src/core/prefs.c:1997
#: src/core/prefs.c:1786
#, c-format
msgid "Workspace %d"
msgstr "مساحة العمل %d"
#: ../src/core/screen.c:583
#: src/core/util.c:121
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "جُمِّع مَتَر دون دعم للنمط المطنب\n"
#: src/wayland/meta-wayland-tablet-pad.c:567
#, c-format
msgid "Mode Switch: Mode %d"
msgstr ""
#: src/x11/meta-x11-display.c:666
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
"replace the current window manager."
msgstr ""
"الشاشة ”%s“ لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل --replace لتحُلّ"
" محلّ مدير النوافذ الحالي."
"الشاشة ”%s“ لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل --replace لتحُلّ "
"محلّ مدير النوافذ الحالي."
#: ../src/core/screen.c:668
#: src/x11/meta-x11-display.c:1008
msgid "Failed to initialize GDK\n"
msgstr ""
#: src/x11/meta-x11-display.c:1032
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "فشل فتح عرض نظام نوافذ إكس ”%s“\n"
#: src/x11/meta-x11-display.c:1113
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "الشاشة %d على العرض ”%s“ غير صحيحة\n"
#: ../src/core/util.c:120
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "جُمِّع مَتَر دون دعم للنمط المطنب\n"
#: ../src/wayland/meta-wayland-tablet-pad.c:563
#, c-format
msgid "Mode Switch: Mode %d"
msgstr ""
#: ../src/x11/session.c:1815
#: src/x11/session.c:1821
msgid ""
"These windows do not support “save current setup” and will have to be "
"restarted manually next time you log in."
@@ -198,245 +679,26 @@ msgstr ""
"هذه النوافذ لا تدعم ” الضبط الحالي&quot; إعادة تشغيلها يدويا عند الولوج "
"المرة القادمة."
#: ../src/x11/window-props.c:559
#: src/x11/window-props.c:569
#, c-format
msgid "%s (on %s)"
msgstr "%s (على %s)"
#~ msgid "Navigation"
#~ msgstr "الإبحار"
#~ msgid "Move window to workspace 1"
#~ msgstr "انقل النافذة إلى مساحة العمل 1"
#~ msgid "Move window to workspace 2"
#~ msgstr "انقل النافذة إلى مساحة العمل 2"
#~ msgid "Move window to workspace 3"
#~ msgstr "انقل النافذة إلى مساحة العمل 3"
#~ msgid "Move window to workspace 4"
#~ msgstr "انقل النافذة إلى مساحة العمل 4"
#~ msgid "Move window to last workspace"
#~ msgstr "انقل النافذة إلى مساحة العمل الأخيرة"
#~ msgid "Move window one workspace to the left"
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى اليسار"
#~ msgid "Move window one workspace to the right"
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى اليمين"
#~ msgid "Move window one workspace up"
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى"
#~ msgid "Move window one workspace down"
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل"
#~ msgid "Move window one monitor to the left"
#~ msgstr "انقل النافذة شاشة واحدة إلى اليسار"
#~ msgid "Move window one monitor to the right"
#~ msgstr "انقل النافذة شاشة واحدة إلى اليمين"
#~ msgid "Move window one monitor up"
#~ msgstr "انقل النافذة شاشة واحدة إلى الأعلى"
#~ msgid "Move window one monitor down"
#~ msgstr "انقل النافذة شاشة واحدة إلى الأسفل"
#~ msgid "Switch applications"
#~ msgstr "تنقل بين التطبيقات"
#~ msgid "Switch to previous application"
#~ msgstr "انتقل إلى التطبيق السابق"
#~ msgid "Switch windows"
#~ msgstr "تنقل بين النوافذ"
#~ msgid "Switch to previous window"
#~ msgstr "انتقل إلى النافذة السابقة"
#~ msgid "Switch windows of an application"
#~ msgstr "تنقل بين نوافذ التطبيق"
#~ msgid "Switch to previous window of an application"
#~ msgstr "انتقل إلى نافذة التطبيق السابقة"
#~ msgid "Switch system controls"
#~ msgstr "تنقل بين تحكمات النظام"
#~ msgid "Switch to previous system control"
#~ msgstr "انتقل إلى تحكم النظام السابق"
#~ msgid "Switch windows directly"
#~ msgstr "تنقل مباشرة بين النوافذ"
#~ msgid "Switch directly to previous window"
#~ msgstr "انتقل مباشرة إلى النافذة السابقة"
#~ msgid "Switch windows of an app directly"
#~ msgstr "تنقل مباشرة بين نوافذ التطبيق"
#~ msgid "Switch directly to previous window of an app"
#~ msgstr "انتقل مباشرة إلى نافذة التطبيق السابقة"
#~ msgid "Switch system controls directly"
#~ msgstr "تنقل مباشرة بين تحكمات النظام"
#~ msgid "Switch directly to previous system control"
#~ msgstr "انتقل مباشرة إلى تحكم النظام السابق"
#~ msgid "Hide all normal windows"
#~ msgstr "أخفِ كل النوافذ العادية"
#~ msgid "Switch to workspace 1"
#~ msgstr "انتقل إلى مساحة العمل 1"
#~ msgid "Switch to workspace 2"
#~ msgstr "انتقل إلى مساحة العمل 2"
#~ msgid "Switch to workspace 3"
#~ msgstr "انتقل إلى مساحة العمل 3"
#~ msgid "Switch to workspace 4"
#~ msgstr "انتقل إلى مساحة العمل 4"
#~ msgid "Switch to last workspace"
#~ msgstr "انتقل إلى مساحة العمل الأخيرة"
#~ msgid "Move to workspace left"
#~ msgstr "انقل لمساحة العمل على اليسار"
#~ msgid "Move to workspace right"
#~ msgstr "انقل لمساحة العمل على اليمين"
#~ msgid "Move to workspace above"
#~ msgstr "انقل لمساحة العمل أعلى"
#~ msgid "Move to workspace below"
#~ msgstr "انقل لمساحة العمل أسفل"
#~ msgid "System"
#~ msgstr "النظام"
#~ msgid "Show the run command prompt"
#~ msgstr "أظهر محث تشغيل أمر"
#~ msgid "Show the activities overview"
#~ msgstr "أظهر نظرة عامة على الأنشطة"
#~ msgid "Windows"
#~ msgstr "النوافذ"
#~ msgid "Activate the window menu"
#~ msgstr "فعّل قائمة النافذة"
#~ msgid "Toggle fullscreen mode"
#~ msgstr "بدّل نمط ملء الشاشة"
#~ msgid "Toggle maximization state"
#~ msgstr "بدّل حالة التكبير"
#~ msgid "Maximize window"
#~ msgstr "كبّر النّافذة"
#~ msgid "Restore window"
#~ msgstr "استعد النّافذة"
#~ msgid "Toggle shaded state"
#~ msgstr "بدّل حالة الإخفاء"
#~ msgid "Close window"
#~ msgstr "أغلق النّافذة"
#~ msgid "Hide window"
#~ msgstr "أخفِ النّافذة"
#~ msgid "Move window"
#~ msgstr "انقل النّافذة"
#~ msgid "Resize window"
#~ msgstr "حجّم النّافذة"
#~ msgid "Toggle window on all workspaces or one"
#~ msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل أو واحدة منها"
#~ msgid "Raise window if covered, otherwise lower it"
#~ msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك"
#~ msgid "Raise window above other windows"
#~ msgstr "ارفع النافذة فوق النوافذ الأخرى"
#~ msgid "Lower window below other windows"
#~ msgstr "اخفض النافذة تحت النوافذ الأخرى"
#~ msgid "Maximize window vertically"
#~ msgstr "كبّر النافذة رأسيا"
#~ msgid "Maximize window horizontally"
#~ msgstr "كبّر النافذة أفقيا"
#~ msgid "View split on left"
#~ msgstr "المنظور مقسوم على اليمين"
#~ msgid "View split on right"
#~ msgstr "المنظور مقسوم على اليسار"
#~ msgid "Mutter"
#~ msgstr "مَتَر"
#~ msgid "Modifier to use for extended window management operations"
#~ msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ "
#, fuzzy
#~ msgid "Switch to VT 1"
#~ msgstr "انتقل إلى مساحة العمل 1"
#, fuzzy
#~ msgid "Switch to VT 2"
#~ msgstr "انتقل إلى مساحة العمل 2"
#, fuzzy
#~ msgid "Switch to VT 3"
#~ msgstr "انتقل إلى مساحة العمل 3"
#, fuzzy
#~ msgid "Switch to VT 4"
#~ msgstr "انتقل إلى مساحة العمل 4"
#, fuzzy
#~ msgid "Switch to VT 5"
#~ msgstr "انتقل إلى مساحة العمل 5"
#, fuzzy
#~ msgid "Switch to VT 6"
#~ msgstr "انتقل إلى مساحة العمل 6"
#, fuzzy
#~ msgid "Switch to VT 7"
#~ msgstr "انتقل إلى مساحة العمل 7"
#, fuzzy
#~ msgid "Switch to VT 8"
#~ msgstr "انتقل إلى مساحة العمل 8"
#, fuzzy
#~ msgid "Switch to VT 9"
#~ msgstr "انتقل إلى مساحة العمل 9"
#, fuzzy
#~ msgid "Switch to VT 10"
#~ msgstr "انتقل إلى مساحة العمل 10"
#, fuzzy
#~ msgid "Switch to VT 11"
#~ msgstr "انتقل إلى مساحة العمل 11"
#, fuzzy
#~ msgid "Switch to VT 12"
#~ msgstr "انتقل إلى مساحة العمل 12"
#~ msgid "Unknown window information request: %d"
#~ msgstr "طلب معلومات نافذة مجهول: %d"
@@ -1162,9 +1424,6 @@ msgstr "%s (على %s)"
#~ msgid "Border"
#~ msgstr "حد"
#~ msgid "Attached Modal Dialog"
#~ msgstr "صندوق حوار سائد"
#~ msgid "Button layout test %d"
#~ msgstr "تجربة تصميم الأزرار %d"

View File

@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2019-02-20 14:35+0000\n"
"POT-Creation-Date: 2019-03-28 12:21+0000\n"
"PO-Revision-Date: 2019-03-01 12:17+0100\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\n"
@@ -154,7 +154,7 @@ msgstr "Cambiar a la útima área de trabajo"
#: data/50-mutter-navigation.xml:123
msgid "Move to workspace above"
msgstr "Mover al área de trabajo de la arriba"
msgstr "Mover al área de trabajo de arriba"
#: data/50-mutter-navigation.xml:126
msgid "Move to workspace below"
@@ -534,7 +534,7 @@ msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2423
#: src/backends/meta-input-settings.c:2424
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Cambiar modo (grupo %d)"
@@ -542,34 +542,34 @@ msgstr "Cambiar modo (grupo %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2446
#: src/backends/meta-input-settings.c:2447
msgid "Switch monitor"
msgstr "Cambiar monitor"
#: src/backends/meta-input-settings.c:2448
#: src/backends/meta-input-settings.c:2449
msgid "Show on-screen help"
msgstr "Mostrar la ayuda en pantalla"
#: src/backends/meta-monitor-manager.c:954
#: src/backends/meta-monitor-manager.c:955
msgid "Built-in display"
msgstr "Pantalla integrada"
#: src/backends/meta-monitor-manager.c:986
#: src/backends/meta-monitor-manager.c:987
msgid "Unknown"
msgstr "Desconocida"
#: src/backends/meta-monitor-manager.c:988
#: src/backends/meta-monitor-manager.c:989
msgid "Unknown Display"
msgstr "Pantalla desconocida"
#: src/backends/meta-monitor-manager.c:996
#: src/backends/meta-monitor-manager.c:997
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor-manager.c:1004
#: src/backends/meta-monitor-manager.c:1005
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
@@ -587,7 +587,7 @@ msgstr ""
"Ya existe un gestor de composición ejecutándose en la monitor %i, pantalla "
"«%s»."
#: src/core/bell.c:252
#: src/core/bell.c:192
msgid "Bell event"
msgstr "Evento de campana"
@@ -636,16 +636,16 @@ msgid "Run with X11 backend"
msgstr "Ejecutar con «backend» de X11"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:150
#: src/core/meta-close-dialog-default.c:151
#, c-format
msgid "“%s” is not responding."
msgstr "«%s» no está respondiendo."
#: src/core/meta-close-dialog-default.c:152
#: src/core/meta-close-dialog-default.c:153
msgid "Application is not responding."
msgstr "La aplicación no está respondiendo."
#: src/core/meta-close-dialog-default.c:157
#: src/core/meta-close-dialog-default.c:158
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@@ -653,11 +653,11 @@ msgstr ""
"Puede elegir esperar un rato para ver si continua o forzar la aplicación "
"para cerrarla completamente."
#: src/core/meta-close-dialog-default.c:164
#: src/core/meta-close-dialog-default.c:165
msgid "_Force Quit"
msgstr "_Forzar la salida"
#: src/core/meta-close-dialog-default.c:164
#: src/core/meta-close-dialog-default.c:165
msgid "_Wait"
msgstr "_Esperar"
@@ -717,7 +717,7 @@ msgstr "Falló al inicializar GDK\n"
msgid "Failed to open X Window System display “%s”\n"
msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
#: src/x11/meta-x11-display.c:1115
#: src/x11/meta-x11-display.c:1113
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
@@ -730,7 +730,7 @@ msgstr ""
"Estas ventanas no soportan «guardar la configuración actual» y tendrán que "
"reiniciarse manualmente la próxima vez que inicie una sesión."
#: src/x11/window-props.c:568
#: src/x11/window-props.c:569
#, c-format
msgid "%s (on %s)"
msgstr "%s (on %s)"

View File

@@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: metacity 0\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2018-07-07 09:58+0000\n"
"PO-Revision-Date: 2018-09-02 18:40+0200\n"
"POT-Creation-Date: 2019-02-04 17:52+0000\n"
"PO-Revision-Date: 2019-03-26 12:40+0100\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <lokalizacija@linux.hr>\n"
"Language: hr\n"
@@ -16,7 +16,7 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Launchpad-Export-Date: 2008-05-28 13:28+0000\n"
"X-Generator: Poedit 2.1.1\n"
"X-Generator: Poedit 2.0.6\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@@ -518,7 +518,7 @@ msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2325
#: src/backends/meta-input-settings.c:2423
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Način prebacivanja (Grupa %d)"
@@ -526,102 +526,109 @@ msgstr "Način prebacivanja (Grupa %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2348
#: src/backends/meta-input-settings.c:2446
msgid "Switch monitor"
msgstr "Prebaci zaslon"
#: src/backends/meta-input-settings.c:2350
#: src/backends/meta-input-settings.c:2448
msgid "Show on-screen help"
msgstr "Prikaži zaslonsku pomoć"
#: src/backends/meta-monitor-manager.c:907
#: src/backends/meta-monitor-manager.c:954
msgid "Built-in display"
msgstr "Ugrađeni zaslon"
#: src/backends/meta-monitor-manager.c:930
#: src/backends/meta-monitor-manager.c:986
msgid "Unknown"
msgstr "Nepoznat"
#: src/backends/meta-monitor-manager.c:932
#: src/backends/meta-monitor-manager.c:988
msgid "Unknown Display"
msgstr "Nepoznat zaslon"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:940
#: src/backends/meta-monitor-manager.c:996
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor-manager.c:1004
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
"inches could not be calculated, e.g. Dell U2414H"
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:481
#: src/compositor/compositor.c:482
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
msgstr ""
"Drugi upravitelja kompoziranja već je pokrenut na zaslonu %i prikaza \"%s\"."
#: src/core/bell.c:254
#: src/core/bell.c:252
msgid "Bell event"
msgstr "Događaj zvona"
#: src/core/main.c:191
#: src/core/main.c:185
msgid "Disable connection to session manager"
msgstr "Onemogući povezivanje sa upraviteljem sesija"
#: src/core/main.c:197
#: src/core/main.c:191
msgid "Replace the running window manager"
msgstr "Zamijeni pokrenutoga upravitelja porozora"
#: src/core/main.c:203
#: src/core/main.c:197
msgid "Specify session management ID"
msgstr "Odredite ID upravljanja sesijama"
#: src/core/main.c:208
#: src/core/main.c:202
msgid "X Display to use"
msgstr "X Prikaz za korištenje"
#: src/core/main.c:214
#: src/core/main.c:208
msgid "Initialize session from savefile"
msgstr "Pokreni sesiju iz spremljene datoteke"
#: src/core/main.c:220
#: src/core/main.c:214
msgid "Make X calls synchronous"
msgstr "Napravi X pozive usklađenim"
#: src/core/main.c:227
#: src/core/main.c:221
msgid "Run as a wayland compositor"
msgstr "Pokreni wayland kompozitor"
#: src/core/main.c:233
#: src/core/main.c:227
msgid "Run as a nested compositor"
msgstr "Pokreni kao ugrađeni kompozitor"
#: src/core/main.c:239
#: src/core/main.c:233
msgid "Run wayland compositor without starting Xwayland"
msgstr "Pokreni wayland kompozitor bez pokretanja Xwaylanda"
#: src/core/main.c:247
#: src/core/main.c:241
msgid "Run as a full display server, rather than nested"
msgstr "Pokreni kao potpuni poslužitelj zaslona, radije nego ugrađeni"
#: src/core/main.c:253
#: src/core/main.c:247
msgid "Run with X11 backend"
msgstr "Pokreni s X11 pozadinskim programom"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:148
#: src/core/meta-close-dialog-default.c:150
#, c-format
msgid "“%s” is not responding."
msgstr "“%s” ne odgovara."
#: src/core/meta-close-dialog-default.c:150
#: src/core/meta-close-dialog-default.c:152
msgid "Application is not responding."
msgstr "Aplikacija ne odgovara."
#: src/core/meta-close-dialog-default.c:155
#: src/core/meta-close-dialog-default.c:157
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@@ -629,15 +636,15 @@ msgstr ""
"Možete pričekati neko vrijeme da aplikacija nastavi s radom ili možete "
"prisiliti prekid rada aplikacije."
#: src/core/meta-close-dialog-default.c:162
#: src/core/meta-close-dialog-default.c:164
msgid "_Force Quit"
msgstr "_Prisili izlaženje"
#: src/core/meta-close-dialog-default.c:162
#: src/core/meta-close-dialog-default.c:164
msgid "_Wait"
msgstr "_Čekaj"
#: src/core/mutter.c:39
#: src/core/mutter.c:38
#, c-format
msgid ""
"mutter %s\n"
@@ -652,20 +659,20 @@ msgstr ""
"NE postoji jamstvo; čak i bez podrazumijevanih jamstava UPORABLJIVOSTI ZA "
"ODREĐENU SVRHU.\n"
#: src/core/mutter.c:53
#: src/core/mutter.c:52
msgid "Print version"
msgstr "Inačica za ispis"
#: src/core/mutter.c:59
#: src/core/mutter.c:58
msgid "Mutter plugin to use"
msgstr "Mutter priključak koji se koristi"
#: src/core/prefs.c:1915
#: src/core/prefs.c:1786
#, c-format
msgid "Workspace %d"
msgstr "Radni prostor %d"
#: src/core/util.c:120
#: src/core/util.c:121
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter je kompiliran bez podrške za opširan način rada\n"
@@ -683,21 +690,21 @@ msgstr ""
"Prikaz \"%s\" već ima upravitelja prozora; pokušajte koristiti --replace "
"mogućnost za zamjenu trenutnog upravitelja prozora."
#: src/x11/meta-x11-display.c:1010
#: src/x11/meta-x11-display.c:1008
msgid "Failed to initialize GDK\n"
msgstr "Neuspjelo GDK pokretanje\n"
#: src/x11/meta-x11-display.c:1034
#: src/x11/meta-x11-display.c:1032
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "Neuspjelo otvaranje sustava prikaza X prozora \"%s\"\n"
#: src/x11/meta-x11-display.c:1117
#: src/x11/meta-x11-display.c:1115
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "Zaslon %d na prikazu '%s' je neispravan\n"
#: src/x11/session.c:1819
#: src/x11/session.c:1821
msgid ""
"These windows do not support “save current setup” and will have to be "
"restarted manually next time you log in."
@@ -705,7 +712,7 @@ msgstr ""
"Ovi prozori ne podržavaju mogućnost \"spremi trenutne postavke\" i moraju se "
"ručno ponovno pokrenuti sljedeći puta kada se prijavite."
#: src/x11/window-props.c:565
#: src/x11/window-props.c:568
#, c-format
msgid "%s (on %s)"
msgstr "%s (na %s)"

View File

@@ -147,6 +147,10 @@ xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
gboolean meta_backend_is_lid_closed (MetaBackend *backend);
void meta_backend_freeze_updates (MetaBackend *backend);
void meta_backend_thaw_updates (MetaBackend *backend);
void meta_backend_update_last_device (MetaBackend *backend,
int device_id);

View File

@@ -475,7 +475,7 @@ meta_backend_real_post_init (MetaBackend *backend)
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
priv->stage = meta_stage_new ();
priv->stage = meta_stage_new (backend);
clutter_actor_realize (priv->stage);
META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
@@ -1079,6 +1079,24 @@ meta_backend_get_stage (MetaBackend *backend)
return priv->stage;
}
void
meta_backend_freeze_updates (MetaBackend *backend)
{
ClutterStage *stage;
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
clutter_stage_freeze_updates (stage);
}
void
meta_backend_thaw_updates (MetaBackend *backend)
{
ClutterStage *stage;
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
clutter_stage_thaw_updates (stage);
}
static gboolean
update_last_device (MetaBackend *backend)
{

View File

@@ -20,6 +20,10 @@
#include "config.h"
#ifdef HAVE_LIBGUDEV
#include <gudev/gudev.h>
#endif
#include "meta-input-mapper-private.h"
#include "meta-monitor-manager-private.h"
#include "meta-logical-monitor.h"
@@ -39,6 +43,9 @@ struct _MetaInputMapper
ClutterDeviceManager *input_device_manager;
GHashTable *input_devices; /* ClutterInputDevice -> MetaMapperInputInfo */
GHashTable *output_devices; /* MetaLogicalMonitor -> MetaMapperOutputInfo */
#ifdef HAVE_LIBGUDEV
GUdevClient *udev_client;
#endif
};
typedef enum
@@ -270,6 +277,33 @@ match_edid (MetaMapperInputInfo *input,
return TRUE;
}
static gboolean
input_device_get_physical_size (MetaInputMapper *mapper,
ClutterInputDevice *device,
double *width,
double *height)
{
#ifdef HAVE_LIBGUDEV
g_autoptr (GUdevDevice) udev_device = NULL;
const char *node;
node = clutter_input_device_get_device_node (device);
udev_device = g_udev_client_query_by_device_file (mapper->udev_client, node);
if (udev_device &&
g_udev_device_has_property (udev_device, "ID_INPUT_WIDTH_MM"))
{
*width = g_udev_device_get_property_as_double (udev_device,
"ID_INPUT_WIDTH_MM");
*height = g_udev_device_get_property_as_double (udev_device,
"ID_INPUT_HEIGHT_MM");
return TRUE;
}
#endif
return FALSE;
}
static gboolean
find_size_match (MetaMapperInputInfo *input,
GList *monitors,
@@ -282,7 +316,8 @@ find_size_match (MetaMapperInputInfo *input,
min_w_diff = min_h_diff = MAX_SIZE_MATCH_DIFF;
if (!clutter_input_device_get_physical_size (input->device, &i_width, &i_height))
if (!input_device_get_physical_size (input->mapper, input->device,
&i_width, &i_height))
return FALSE;
for (l = monitors; l; l = l->next)
@@ -520,6 +555,9 @@ meta_input_mapper_finalize (GObject *object)
g_hash_table_unref (mapper->input_devices);
g_hash_table_unref (mapper->output_devices);
#ifdef HAVE_LIBGUDEV
g_clear_object (&mapper->udev_client);
#endif
G_OBJECT_CLASS (meta_input_mapper_parent_class)->finalize (object);
}
@@ -527,11 +565,18 @@ meta_input_mapper_finalize (GObject *object)
static void
meta_input_mapper_constructed (GObject *object)
{
#ifdef HAVE_LIBGUDEV
const char *udev_subsystems[] = { "input", NULL };
#endif
MetaInputMapper *mapper = META_INPUT_MAPPER (object);
MetaBackend *backend;
G_OBJECT_CLASS (meta_input_mapper_parent_class)->constructed (object);
#ifdef HAVE_LIBGUDEV
mapper->udev_client = g_udev_client_new (udev_subsystems);
#endif
mapper->input_device_manager = clutter_device_manager_get_default ();
g_signal_connect (mapper->input_device_manager, "device-removed",
G_CALLBACK (input_mapper_device_removed_cb), mapper);

View File

@@ -1766,9 +1766,11 @@ power_save_mode_changed_cb (MetaMonitorManager *manager,
ClutterInputDevice *device;
MetaLogicalMonitor *logical_monitor;
MetaMonitor *builtin;
MetaPowerSave power_save_mode;
gboolean on;
on = (manager->power_save_mode == META_POWER_SAVE_ON);
power_save_mode = meta_monitor_manager_get_power_save_mode (manager);
on = power_save_mode == META_POWER_SAVE_ON;
priv = meta_input_settings_get_instance_private (user_data);
builtin = meta_monitor_manager_get_laptop_panel (manager);

View File

@@ -1540,7 +1540,7 @@ meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor
}
static gboolean
has_adjecent_neighbour (MetaMonitorsConfig *config,
has_adjacent_neighbour (MetaMonitorsConfig *config,
MetaLogicalMonitorConfig *logical_monitor_config)
{
GList *l;
@@ -1559,7 +1559,7 @@ has_adjecent_neighbour (MetaMonitorsConfig *config,
if (logical_monitor_config == other_logical_monitor_config)
continue;
if (meta_rectangle_is_adjecent_to (&logical_monitor_config->layout,
if (meta_rectangle_is_adjacent_to (&logical_monitor_config->layout,
&other_logical_monitor_config->layout))
return TRUE;
}
@@ -1665,10 +1665,10 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
has_primary = TRUE;
}
if (!has_adjecent_neighbour (config, logical_monitor_config))
if (!has_adjacent_neighbour (config, logical_monitor_config))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors not adjecent");
"Logical monitors not adjacent");
return FALSE;
}

View File

@@ -694,11 +694,11 @@ meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *man
}
static float *
meta_monitor_manager_dummy_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
meta_monitor_manager_dummy_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorScalesConstraint constraints =
META_MONITOR_SCALES_CONSTRAINT_NONE;

View File

@@ -116,8 +116,6 @@ struct _MetaMonitorManager
gboolean in_init;
unsigned int serial;
MetaPowerSave power_save_mode;
MetaLogicalMonitorLayoutMode layout_mode;
int screen_width;
@@ -192,6 +190,8 @@ struct _MetaMonitorManagerClass
GBytes* (*read_edid) (MetaMonitorManager *,
MetaOutput *);
void (*read_current_state) (MetaMonitorManager *);
void (*ensure_initial_config) (MetaMonitorManager *);
gboolean (*apply_monitors_config) (MetaMonitorManager *,
@@ -305,6 +305,11 @@ void meta_monitor_manager_get_screen_size (MetaMonitorManager *
int *width,
int *height);
MetaPowerSave meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager);
void meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager,
MetaPowerSave mode);
void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
gboolean ok);

View File

@@ -95,7 +95,13 @@ static gfloat transform_matrices[][6] = {
static int signals[SIGNALS_LAST];
G_DEFINE_TYPE (MetaMonitorManager, meta_monitor_manager, G_TYPE_OBJECT)
typedef struct _MetaMonitorManagerPrivate
{
MetaPowerSave power_save_mode;
} MetaMonitorManagerPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager,
G_TYPE_OBJECT)
static void initialize_dbus_interface (MetaMonitorManager *manager);
static void monitor_manager_setup_dbus_config_handlers (MetaMonitorManager *manager);
@@ -107,6 +113,9 @@ meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
static MetaMonitor *
meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager);
static void
meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager);
MetaBackend *
meta_monitor_manager_get_backend (MetaMonitorManager *manager)
{
@@ -329,11 +338,24 @@ meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manag
primary_logical_monitor);
}
void
meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager,
MetaPowerSave mode)
{
MetaMonitorManagerPrivate *priv =
meta_monitor_manager_get_instance_private (manager);
priv->power_save_mode = mode;
g_signal_emit (manager, signals[POWER_SAVE_MODE_CHANGED], 0);
}
static void
power_save_mode_changed (MetaMonitorManager *manager,
GParamSpec *pspec,
gpointer user_data)
{
MetaMonitorManagerPrivate *priv =
meta_monitor_manager_get_instance_private (manager);
MetaMonitorManagerClass *klass;
int mode = meta_dbus_display_config_get_power_save_mode (manager->display_config);
@@ -341,7 +363,7 @@ power_save_mode_changed (MetaMonitorManager *manager,
return;
/* If DPMS is unsupported, force the property back. */
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
if (priv->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
{
meta_dbus_display_config_set_power_save_mode (manager->display_config, META_POWER_SAVE_UNSUPPORTED);
return;
@@ -351,9 +373,7 @@ power_save_mode_changed (MetaMonitorManager *manager,
if (klass->set_power_save_mode)
klass->set_power_save_mode (manager, mode);
manager->power_save_mode = mode;
g_signal_emit (manager, signals[POWER_SAVE_MODE_CHANGED], 0);
meta_monitor_manager_power_save_mode_changed (manager, mode);
}
void
@@ -400,11 +420,11 @@ meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager,
}
float *
meta_monitor_manager_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
meta_monitor_manager_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
@@ -855,6 +875,7 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
object_class->set_property = meta_monitor_manager_set_property;
klass->read_edid = meta_monitor_manager_real_read_edid;
klass->read_current_state = meta_monitor_manager_real_read_current_state;
signals[MONITORS_CHANGED] =
g_signal_new ("monitors-changed",
@@ -2684,6 +2705,15 @@ meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
*height = manager->screen_height;
}
MetaPowerSave
meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager)
{
MetaMonitorManagerPrivate *priv =
meta_monitor_manager_get_instance_private (manager);
return priv->power_save_mode;
}
static void
rebuild_monitors (MetaMonitorManager *manager)
{
@@ -2760,8 +2790,8 @@ meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager,
return manager_class->is_transform_handled (manager, crtc, transform);
}
void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
static void
meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager)
{
GList *l;
@@ -2782,6 +2812,15 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
rebuild_monitors (manager);
}
void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
manager_class->read_current_state (manager);
}
static void
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
{

View File

@@ -615,12 +615,12 @@ meta_monitor_normal_get_suggested_position (MetaMonitor *monitor,
}
static void
meta_monitor_normal_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
meta_monitor_normal_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
*out_x = 0;
*out_y = 0;
@@ -1267,12 +1267,12 @@ meta_monitor_tiled_get_suggested_position (MetaMonitor *monitor,
}
static void
meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
MetaMonitorModeTiled *mode_tiled = (MetaMonitorModeTiled *) monitor_mode;
@@ -1461,12 +1461,12 @@ meta_monitor_get_modes (MetaMonitor *monitor)
}
void
meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
META_MONITOR_GET_CLASS (monitor)->calculate_crtc_pos (monitor,
monitor_mode,
@@ -1587,7 +1587,6 @@ get_closest_scale_factor_for_resolution (float width,
float scaled_w;
float best_scale;
int base_scaled_w;
gboolean limit_exceeded;
gboolean found_one;
best_scale = 0;
@@ -1604,7 +1603,6 @@ get_closest_scale_factor_for_resolution (float width,
i = 0;
found_one = FALSE;
limit_exceeded = FALSE;
base_scaled_w = floorf (scaled_w);
do
@@ -1637,17 +1635,17 @@ get_closest_scale_factor_for_resolution (float width,
i++;
}
while (!found_one && !limit_exceeded);
while (!found_one);
out:
return best_scale;
}
float *
meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorScalesConstraint constraints,
int *n_supported_scales)
meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorScalesConstraint constraints,
int *n_supported_scales)
{
unsigned int i, j;
int width, height;
@@ -1727,11 +1725,11 @@ meta_monitor_mode_get_flags (MetaMonitorMode *monitor_mode)
}
gboolean
meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error)
meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error)
{
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
@@ -1753,11 +1751,11 @@ meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
}
gboolean
meta_monitor_mode_foreach_output (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error)
meta_monitor_mode_foreach_output (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error)
{
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);

View File

@@ -74,12 +74,12 @@ struct _MetaMonitorClass
MetaOutput * (* get_main_output) (MetaMonitor *monitor);
void (* derive_layout) (MetaMonitor *monitor,
MetaRectangle *layout);
void (* calculate_crtc_pos) (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
void (* calculate_crtc_pos) (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
gboolean (* get_suggested_position) (MetaMonitor *monitor,
int *width,
int *height);
@@ -214,22 +214,22 @@ META_EXPORT_TEST
GList * meta_monitor_get_modes (MetaMonitor *monitor);
META_EXPORT_TEST
void meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
void meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
META_EXPORT_TEST
float meta_monitor_calculate_mode_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode);
META_EXPORT_TEST
float * meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorScalesConstraint constraints,
int *n_supported_scales);
float * meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorScalesConstraint constraints,
int *n_supported_scales);
META_EXPORT_TEST
const char * meta_monitor_mode_get_id (MetaMonitorMode *monitor_mode);
@@ -249,18 +249,18 @@ META_EXPORT_TEST
MetaCrtcModeFlag meta_monitor_mode_get_flags (MetaMonitorMode *monitor_mode);
META_EXPORT_TEST
gboolean meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error);
gboolean meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error);
META_EXPORT_TEST
gboolean meta_monitor_mode_foreach_output (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error);
gboolean meta_monitor_mode_foreach_output (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorModeFunc func,
gpointer user_data,
GError **error);
META_EXPORT_TEST
gboolean meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode);

View File

@@ -23,12 +23,13 @@
#include "backends/meta-cursor.h"
#include "meta/boxes.h"
#include "meta/meta-stage.h"
#include "meta/types.h"
G_BEGIN_DECLS
typedef struct _MetaOverlay MetaOverlay;
ClutterActor *meta_stage_new (void);
ClutterActor *meta_stage_new (MetaBackend *backend);
MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage);
void meta_stage_remove_cursor_overlay (MetaStage *stage,

View File

@@ -180,6 +180,15 @@ meta_stage_deactivate (ClutterStage *actor)
stage->is_active = FALSE;
}
static void
on_power_save_changed (MetaMonitorManager *monitor_manager,
MetaStage *stage)
{
if (meta_monitor_manager_get_power_save_mode (monitor_manager) ==
META_POWER_SAVE_ON)
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
static void
meta_stage_class_init (MetaStageClass *klass)
{
@@ -209,11 +218,21 @@ meta_stage_init (MetaStage *stage)
}
ClutterActor *
meta_stage_new (void)
meta_stage_new (MetaBackend *backend)
{
return g_object_new (META_TYPE_STAGE,
"cursor-visible", FALSE,
NULL);
MetaStage *stage;
MetaMonitorManager *monitor_manager;
stage = g_object_new (META_TYPE_STAGE,
"cursor-visible", FALSE,
NULL);
monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (monitor_manager, "power-save-mode-changed",
G_CALLBACK (on_power_save_changed),
stage);
return CLUTTER_ACTOR (stage);
}
static void

View File

@@ -41,9 +41,6 @@
typedef struct _MetaCrtcKms
{
unsigned int index;
uint32_t underscan_prop_id;
uint32_t underscan_hborder_prop_id;
uint32_t underscan_vborder_prop_id;
uint32_t primary_plane_id;
uint32_t rotation_prop_id;
uint32_t rotation_map[ALL_TRANSFORMS];
@@ -137,54 +134,6 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc)
}
}
void
meta_crtc_kms_set_underscan (MetaCrtc *crtc,
gboolean is_underscanning)
{
MetaCrtcKms *crtc_kms = crtc->driver_private;
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaGpuKms *gpu_kms = META_GPU_KMS (gpu);
int kms_fd;
if (!crtc_kms->underscan_prop_id)
return;
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
if (is_underscanning)
{
drmModeObjectSetProperty (kms_fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_prop_id, (uint64_t) 1);
if (crtc_kms->underscan_hborder_prop_id)
{
uint64_t value;
value = crtc->current_mode->width * 0.05;
drmModeObjectSetProperty (kms_fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_hborder_prop_id, value);
}
if (crtc_kms->underscan_vborder_prop_id)
{
uint64_t value;
value = crtc->current_mode->height * 0.05;
drmModeObjectSetProperty (kms_fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_vborder_prop_id, value);
}
}
else
{
drmModeObjectSetProperty (kms_fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_prop_id, (uint64_t) 0);
}
}
static int
find_property_index (MetaGpu *gpu,
drmModeObjectPropertiesPtr props,
@@ -533,43 +482,6 @@ init_crtc_rotations (MetaCrtc *crtc,
}
}
static void
find_crtc_properties (MetaCrtc *crtc,
MetaGpuKms *gpu_kms)
{
MetaCrtcKms *crtc_kms = crtc->driver_private;
int kms_fd;
drmModeObjectPropertiesPtr props;
unsigned int i;
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
props = drmModeObjectGetProperties (kms_fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!props)
return;
for (i = 0; i < props->count_props; i++)
{
drmModePropertyPtr prop = drmModeGetProperty (kms_fd, props->props[i]);
if (!prop)
continue;
if ((prop->flags & DRM_MODE_PROP_ENUM) &&
strcmp (prop->name, "underscan") == 0)
crtc_kms->underscan_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "underscan hborder") == 0)
crtc_kms->underscan_hborder_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "underscan vborder") == 0)
crtc_kms->underscan_vborder_prop_id = prop->prop_id;
drmModeFreeProperty (prop);
}
drmModeFreeObjectProperties (props);
}
static void
meta_crtc_destroy_notify (MetaCrtc *crtc)
{
@@ -628,7 +540,6 @@ meta_create_kms_crtc (MetaGpuKms *gpu_kms,
crtc->driver_private = crtc_kms;
crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
find_crtc_properties (crtc, gpu_kms);
init_crtc_rotations (crtc, gpu);
return crtc;

View File

@@ -44,9 +44,6 @@ gboolean meta_crtc_kms_is_transform_handled (MetaCrtc *crtc,
void meta_crtc_kms_apply_transform (MetaCrtc *crtc);
void meta_crtc_kms_set_underscan (MetaCrtc *crtc,
gboolean is_underscanning);
GArray * meta_crtc_kms_get_modifiers (MetaCrtc *crtc,
uint32_t format);

View File

@@ -210,7 +210,7 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
g_assert (meta_crtc_get_gpu (crtc) == META_GPU (gpu_kms));
if (monitor_manager->power_save_mode != META_POWER_SAVE_ON)
if (meta_monitor_manager_get_power_save_mode (monitor_manager))
return FALSE;
connected_crtc_found = FALSE;
@@ -273,7 +273,8 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
int ret = -1;
g_assert (meta_crtc_get_gpu (crtc) == gpu);
g_assert (monitor_manager->power_save_mode == META_POWER_SAVE_ON);
g_assert (meta_monitor_manager_get_power_save_mode (monitor_manager) ==
META_POWER_SAVE_ON);
get_crtc_drm_connectors (gpu, crtc, &connectors, &n_connectors);
g_assert (n_connectors > 0);
@@ -836,8 +837,6 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
GError **error)
{
MetaGpuKms *gpu_kms = META_GPU_KMS (gpu);
MetaMonitorManager *monitor_manager =
meta_gpu_get_monitor_manager (gpu);
MetaKmsResources resources;
g_autoptr (GError) local_error = NULL;
@@ -855,8 +854,6 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
gpu_kms->max_buffer_width = resources.resources->max_width;
gpu_kms->max_buffer_height = resources.resources->max_height;
monitor_manager->power_save_mode = META_POWER_SAVE_ON;
/* Note: we must not free the public structures (output, crtc, monitor
mode and monitor info) here, they must be kept alive until the API
users are done with them after we emit monitors-changed, and thus

View File

@@ -108,6 +108,21 @@ meta_monitor_manager_kms_read_edid (MetaMonitorManager *manager,
return meta_output_kms_read_edid (output);
}
static void
meta_monitor_manager_kms_read_current_state (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *parent_class =
META_MONITOR_MANAGER_CLASS (meta_monitor_manager_kms_parent_class);
MetaPowerSave power_save_mode;
power_save_mode = meta_monitor_manager_get_power_save_mode (manager);
if (power_save_mode != META_POWER_SAVE_ON)
meta_monitor_manager_power_save_mode_changed (manager,
META_POWER_SAVE_ON);
parent_class->read_current_state (manager);
}
static void
meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
@@ -512,11 +527,11 @@ meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manag
}
static float *
meta_monitor_manager_kms_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
meta_monitor_manager_kms_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorScalesConstraint constraints =
META_MONITOR_SCALES_CONSTRAINT_NONE;
@@ -755,6 +770,7 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
object_class->dispose = meta_monitor_manager_kms_dispose;
manager_class->read_edid = meta_monitor_manager_kms_read_edid;
manager_class->read_current_state = meta_monitor_manager_kms_read_current_state;
manager_class->ensure_initial_config = meta_monitor_manager_kms_ensure_initial_config;
manager_class->apply_monitors_config = meta_monitor_manager_kms_apply_monitors_config;
manager_class->set_power_save_mode = meta_monitor_manager_kms_set_power_save_mode;

View File

@@ -56,6 +56,10 @@ typedef struct _MetaOutputKms
uint32_t edid_blob_id;
uint32_t tile_blob_id;
uint32_t underscan_prop_id;
uint32_t underscan_hborder_prop_id;
uint32_t underscan_vborder_prop_id;
int suggested_x;
int suggested_y;
uint32_t hotplug_mode_update;
@@ -66,13 +70,55 @@ typedef struct _MetaOutputKms
void
meta_output_kms_set_underscan (MetaOutput *output)
{
MetaOutputKms *output_kms = output->driver_private;
MetaGpu *gpu = meta_output_get_gpu (output);
MetaGpuKms *gpu_kms = META_GPU_KMS (gpu);
MetaCrtc *crtc;
int kms_fd;
uint32_t connector_id;
crtc = meta_output_get_assigned_crtc (output);
if (!crtc)
if (!output_kms->underscan_prop_id)
return;
meta_crtc_kms_set_underscan (crtc, output->is_underscanning);
crtc = meta_output_get_assigned_crtc (output);
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
connector_id = output_kms->connector->connector_id;
if (output->is_underscanning && crtc && crtc->current_mode)
{
drmModeObjectSetProperty (kms_fd, connector_id,
DRM_MODE_OBJECT_CONNECTOR,
output_kms->underscan_prop_id,
(uint64_t) 1);
if (output_kms->underscan_hborder_prop_id)
{
uint64_t value;
value = MIN (128, crtc->current_mode->width * 0.05);
drmModeObjectSetProperty (kms_fd, connector_id,
DRM_MODE_OBJECT_CONNECTOR,
output_kms->underscan_hborder_prop_id,
value);
}
if (output_kms->underscan_vborder_prop_id)
{
uint64_t value;
value = MIN (128, crtc->current_mode->height * 0.05);
drmModeObjectSetProperty (kms_fd, connector_id,
DRM_MODE_OBJECT_CONNECTOR,
output_kms->underscan_vborder_prop_id,
value);
}
}
else
{
drmModeObjectSetProperty (kms_fd, connector_id,
DRM_MODE_OBJECT_CONNECTOR,
output_kms->underscan_prop_id,
(uint64_t) 0);
}
}
uint32_t
@@ -312,6 +358,15 @@ find_connector_properties (MetaGpuKms *gpu_kms,
strcmp (prop->name, "panel orientation") == 0)
handle_panel_orientation (output, prop,
output_kms->connector->prop_values[i]);
else if ((prop->flags & DRM_MODE_PROP_ENUM) &&
strcmp (prop->name, "underscan") == 0)
output_kms->underscan_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "underscan hborder") == 0)
output_kms->underscan_hborder_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "underscan vborder") == 0)
output_kms->underscan_vborder_prop_id = prop->prop_id;
drmModeFreeProperty (prop);
}
@@ -639,6 +694,7 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
output->suggested_x = output_kms->suggested_x;
output->suggested_y = output_kms->suggested_y;
output->hotplug_mode_update = output_kms->hotplug_mode_update;
output->supports_underscanning = output_kms->underscan_prop_id != 0;
if (output_kms->edid_blob_id != 0)
{

View File

@@ -103,8 +103,6 @@ typedef struct _MetaRendererNativeGpuData
#ifdef HAVE_EGL_DEVICE
struct {
EGLDeviceEXT device;
gboolean no_egl_output_drm_flip_event;
} egl;
#endif
@@ -215,6 +213,9 @@ struct _MetaRendererNative
int64_t frame_counter;
gboolean pending_unset_disabled_crtcs;
GList *power_save_page_flip_closures;
guint power_save_page_flip_source_id;
};
static void
@@ -257,6 +258,15 @@ cogl_pixel_format_from_drm_format (uint32_t drm_format,
CoglPixelFormat *out_format,
CoglTextureComponents *out_components);
static MetaBackend *
backend_from_renderer_native (MetaRendererNative *renderer_native)
{
MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
return meta_monitor_manager_get_backend (monitor_manager);
}
static void
meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data)
{
@@ -1485,8 +1495,6 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
renderer_gpu_data =
meta_renderer_native_get_gpu_data (onscreen_native->renderer_native,
onscreen_native->render_gpu);
if (renderer_gpu_data->egl.no_egl_output_drm_flip_event)
return FALSE;
closure_container =
meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu,
@@ -1509,9 +1517,7 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
if (error->domain != META_EGL_ERROR ||
error->code != EGL_RESOURCE_BUSY_EXT)
{
g_warning ("Failed to flip EGL stream (%s), relying on clock from "
"now on", error->message);
renderer_gpu_data->egl.no_egl_output_drm_flip_event = TRUE;
g_warning ("Failed to flip EGL stream: %s", error->message);
}
g_error_free (error);
meta_gpu_kms_flip_closure_container_free (closure_container);
@@ -1532,6 +1538,38 @@ is_timestamp_earlier_than (uint64_t ts1,
return ts2 - ts1 < UINT64_MAX / 2;
}
static gboolean
dummy_power_save_page_flip_cb (gpointer user_data)
{
MetaRendererNative *renderer_native = user_data;
g_list_free_full (renderer_native->power_save_page_flip_closures,
(GDestroyNotify) g_closure_unref);
renderer_native->power_save_page_flip_closures = NULL;
renderer_native->power_save_page_flip_source_id = 0;
return G_SOURCE_REMOVE;
}
static void
queue_dummy_power_save_page_flip (MetaRendererNative *renderer_native,
GClosure *flip_closure)
{
const unsigned int timeout_ms = 100;
if (!renderer_native->power_save_page_flip_source_id)
{
renderer_native->power_save_page_flip_source_id =
g_timeout_add (timeout_ms,
dummy_power_save_page_flip_cb,
renderer_native);
}
renderer_native->power_save_page_flip_closures =
g_list_prepend (renderer_native->power_save_page_flip_closures,
g_closure_ref (flip_closure));
}
typedef struct _RetryPageFlipData
{
MetaCrtc *crtc;
@@ -1547,14 +1585,39 @@ retry_page_flip_data_free (RetryPageFlipData *retry_page_flip_data)
g_free (retry_page_flip_data);
}
static void
retry_page_flip_data_fake_flipped (RetryPageFlipData *retry_page_flip_data,
MetaOnscreenNative *onscreen_native)
{
MetaCrtc *crtc = retry_page_flip_data->crtc;
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
if (gpu_kms != onscreen_native->render_gpu)
{
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
secondary_gpu_state =
meta_onscreen_native_get_secondary_gpu_state (onscreen_native,
gpu_kms);
secondary_gpu_state->pending_flips--;
}
onscreen_native->total_pending_flips--;
}
static gboolean
retry_page_flips (gpointer user_data)
{
MetaOnscreenNative *onscreen_native = user_data;
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
uint64_t now_us;
MetaPowerSave power_save_mode;
GList *l;
now_us = g_source_get_time (onscreen_native->retry_page_flips_source);
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
l = onscreen_native->pending_page_flip_retries;
while (l)
@@ -1566,6 +1629,19 @@ retry_page_flips (gpointer user_data)
g_autoptr (GError) error = NULL;
gboolean did_flip;
if (power_save_mode != META_POWER_SAVE_ON)
{
onscreen_native->pending_page_flip_retries =
g_list_remove_link (onscreen_native->pending_page_flip_retries, l);
retry_page_flip_data_fake_flipped (retry_page_flip_data,
onscreen_native);
retry_page_flip_data_free (retry_page_flip_data);
l = l_next;
continue;
}
if (is_timestamp_earlier_than (now_us,
retry_page_flip_data->retry_time_us))
{
@@ -1582,7 +1658,7 @@ retry_page_flips (gpointer user_data)
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_BUSY))
{
retry_page_flip_data->retry_time_us +=
G_USEC_PER_SEC / crtc->current_mode->refresh_rate;
(uint64_t) (G_USEC_PER_SEC / crtc->current_mode->refresh_rate);
l = l_next;
continue;
}
@@ -1597,17 +1673,8 @@ retry_page_flips (gpointer user_data)
G_IO_ERROR_PERMISSION_DENIED))
g_critical ("Failed to page flip: %s", error->message);
if (gpu_kms != onscreen_native->render_gpu)
{
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
secondary_gpu_state =
meta_onscreen_native_get_secondary_gpu_state (onscreen_native,
gpu_kms);
secondary_gpu_state->pending_flips--;
}
onscreen_native->total_pending_flips--;
retry_page_flip_data_fake_flipped (retry_page_flip_data,
onscreen_native);
}
retry_page_flip_data_free (retry_page_flip_data);
@@ -1636,6 +1703,9 @@ retry_page_flips (gpointer user_data)
}
else
{
MetaBackend *backend = backend_from_renderer_native (renderer_native);
meta_backend_thaw_updates (backend);
g_clear_pointer (&onscreen_native->retry_page_flips_source,
g_source_unref);
return G_SOURCE_REMOVE;
@@ -1666,7 +1736,7 @@ schedule_retry_page_flip (MetaOnscreenNative *onscreen_native,
now_us = g_get_monotonic_time ();
retry_time_us =
now_us + (G_USEC_PER_SEC / crtc->current_mode->refresh_rate);
now_us + (uint64_t) (G_USEC_PER_SEC / crtc->current_mode->refresh_rate);
retry_page_flip_data = g_new0 (RetryPageFlipData, 1);
retry_page_flip_data->crtc = crtc;
@@ -1676,6 +1746,8 @@ schedule_retry_page_flip (MetaOnscreenNative *onscreen_native,
if (!onscreen_native->retry_page_flips_source)
{
MetaBackend *backend =
backend_from_renderer_native (onscreen_native->renderer_native);
GSource *source;
source = g_source_new (&retry_page_flips_source_funcs, sizeof (GSource));
@@ -1684,6 +1756,7 @@ schedule_retry_page_flip (MetaOnscreenNative *onscreen_native,
g_source_attach (source, NULL);
onscreen_native->retry_page_flips_source = source;
meta_backend_freeze_updates (backend);
}
else
{
@@ -1725,12 +1798,8 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
uint32_t fb_id;
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
if (!meta_gpu_kms_is_crtc_active (gpu_kms, crtc))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Tried to flip inactive CRTC");
return FALSE;
}
g_assert (meta_gpu_kms_is_crtc_active (gpu_kms, crtc));
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
render_gpu);
@@ -1971,7 +2040,11 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaRendererView *view = onscreen_native->view;
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
GClosure *flip_closure;
MetaPowerSave power_save_mode;
MetaLogicalMonitor *logical_monitor;
/*
@@ -1989,23 +2062,28 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
(GClosureNotify) flip_closure_destroyed);
g_closure_set_marshal (flip_closure, meta_marshal_VOID__OBJECT_OBJECT_INT64);
/* Either flip the CRTC's of the monitor info, if we are drawing just part
* of the stage, or all of the CRTC's if we are drawing the whole stage.
*/
FlipCrtcData data = {
.onscreen = onscreen,
.flip_closure = flip_closure,
};
logical_monitor = meta_renderer_view_get_logical_monitor (view);
meta_logical_monitor_foreach_crtc (logical_monitor, flip_crtc, &data);
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
if (power_save_mode == META_POWER_SAVE_ON)
{
FlipCrtcData data = {
.onscreen = onscreen,
.flip_closure = flip_closure,
};
logical_monitor = meta_renderer_view_get_logical_monitor (view);
meta_logical_monitor_foreach_crtc (logical_monitor, flip_crtc, &data);
/*
* If we didn't queue a page flip, but instead directly changed the mode due
* to the driver not supporting mode setting, wes must swap the buffers
* directly as we won't get a page flip callback.
*/
if (!data.did_flip && data.did_mode_set)
meta_onscreen_native_swap_drm_fb (onscreen);
/*
* If we didn't queue a page flip, but instead directly changed the mode
* due to the driver not supporting mode setting, we must swap the
* buffers directly as we won't get a page flip callback.
*/
if (!data.did_flip && data.did_mode_set)
meta_onscreen_native_swap_drm_fb (onscreen);
}
else
{
queue_dummy_power_save_page_flip (renderer_native, flip_closure);
}
onscreen_native->pending_queue_swap_notify = TRUE;
@@ -2378,11 +2456,14 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
CoglFrameInfo *frame_info;
gboolean egl_context_changed = FALSE;
MetaPowerSave power_save_mode;
/*
* Wait for the flip callback before continuing, as we might have started the
@@ -2424,7 +2505,10 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
/* If this is the first framebuffer to be presented then we now setup the
* crtc modes, else we flip from the previous buffer */
if (onscreen_native->pending_set_crtc)
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
if (onscreen_native->pending_set_crtc &&
power_save_mode == META_POWER_SAVE_ON)
{
meta_onscreen_native_set_crtc_modes (onscreen);
onscreen_native->pending_set_crtc = FALSE;
@@ -2629,7 +2713,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
EGLOutputLayerEXT output_layer;
EGLAttrib output_attribs[3];
EGLint stream_attribs[] = {
EGL_STREAM_FIFO_LENGTH_KHR, 1,
EGL_STREAM_FIFO_LENGTH_KHR, 0,
EGL_CONSUMER_AUTO_ACQUIRE_EXT, EGL_FALSE,
EGL_NONE
};
@@ -2970,8 +3054,15 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
g_list_free_full (onscreen_native->pending_page_flip_retries,
(GDestroyNotify) retry_page_flip_data_free);
g_clear_pointer (&onscreen_native->retry_page_flips_source,
g_source_destroy);
if (onscreen_native->retry_page_flips_source)
{
MetaBackend *backend =
backend_from_renderer_native (onscreen_native->renderer_native);
meta_backend_thaw_updates (backend);
g_clear_pointer (&onscreen_native->retry_page_flips_source,
g_source_destroy);
}
if (onscreen_egl->egl_surface != EGL_NO_SURFACE)
{
@@ -3294,9 +3385,7 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
static CoglContext *
cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
{
MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
MetaBackend *backend = backend_from_renderer_native (renderer_native);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
return clutter_backend_get_cogl_context (clutter_backend);
@@ -3698,16 +3787,13 @@ gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native,
return data->secondary.is_hardware_rendering;
}
static MetaRendererNativeGpuData *
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
MetaGpuKms *gpu_kms,
GError **error)
static EGLDisplay
init_gbm_egl_display (MetaRendererNative *renderer_native,
struct gbm_device *gbm_device,
GError **error)
{
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
struct gbm_device *gbm_device;
EGLDisplay egl_display;
int kms_fd;
MetaRendererNativeGpuData *renderer_gpu_data;
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
"EGL_MESA_platform_gbm",
@@ -3719,9 +3805,31 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"Missing extension for GBM renderer: EGL_KHR_platform_gbm");
return NULL;
return EGL_NO_DISPLAY;
}
egl_display = meta_egl_get_platform_display (egl,
EGL_PLATFORM_GBM_KHR,
gbm_device, NULL, error);
if (egl_display == EGL_NO_DISPLAY)
return EGL_NO_DISPLAY;
if (!meta_egl_initialize (egl, egl_display, error))
return EGL_NO_DISPLAY;
return egl_display;
}
static MetaRendererNativeGpuData *
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
MetaGpuKms *gpu_kms,
GError **error)
{
struct gbm_device *gbm_device;
int kms_fd;
MetaRendererNativeGpuData *renderer_gpu_data;
g_autoptr (GError) local_error = NULL;
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
gbm_device = gbm_create_device (kms_fd);
@@ -3733,26 +3841,25 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
return NULL;
}
egl_display = meta_egl_get_platform_display (egl,
EGL_PLATFORM_GBM_KHR,
gbm_device, NULL, error);
if (egl_display == EGL_NO_DISPLAY)
{
gbm_device_destroy (gbm_device);
return NULL;
}
if (!meta_egl_initialize (egl, egl_display, error))
return NULL;
renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms);
renderer_gpu_data->renderer_native = renderer_native;
renderer_gpu_data->gbm.device = gbm_device;
renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM;
renderer_gpu_data->egl_display = egl_display;
renderer_gpu_data->egl_display = init_gbm_egl_display (renderer_native,
gbm_device,
&local_error);
if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
{
g_debug ("GBM EGL init for %s failed: %s",
meta_gpu_kms_get_file_path (gpu_kms),
local_error->message);
init_secondary_gpu_data_cpu (renderer_gpu_data);
return renderer_gpu_data;
}
init_secondary_gpu_data (renderer_gpu_data);
return renderer_gpu_data;
}
@@ -4045,8 +4152,8 @@ on_gpu_added (MetaMonitorManager *monitor_manager,
}
static MetaGpuKms *
choose_primary_gpu (MetaMonitorManager *manager,
MetaRendererNative *renderer_native)
choose_primary_gpu_unchecked (MetaMonitorManager *manager,
MetaRendererNative *renderer_native)
{
GList *gpus = meta_monitor_manager_get_gpus (manager);
GList *l;
@@ -4095,6 +4202,28 @@ choose_primary_gpu (MetaMonitorManager *manager,
return NULL;
}
static MetaGpuKms *
choose_primary_gpu (MetaMonitorManager *manager,
MetaRendererNative *renderer_native,
GError **error)
{
MetaGpuKms *gpu_kms;
MetaRendererNativeGpuData *renderer_gpu_data;
gpu_kms = choose_primary_gpu_unchecked (manager, renderer_native);
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
gpu_kms);
if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"The GPU %s chosen as primary is not supported by EGL.",
meta_gpu_kms_get_file_path (gpu_kms));
return NULL;
}
return gpu_kms;
}
static gboolean
meta_renderer_native_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -4118,7 +4247,10 @@ meta_renderer_native_initable_init (GInitable *initable,
}
renderer_native->primary_gpu_kms = choose_primary_gpu (monitor_manager,
renderer_native);
renderer_native,
error);
if (!renderer_native->primary_gpu_kms)
return FALSE;
return TRUE;
}
@@ -4134,6 +4266,13 @@ meta_renderer_native_finalize (GObject *object)
{
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object);
if (renderer_native->power_save_page_flip_closures)
{
g_list_free_full (renderer_native->power_save_page_flip_closures,
(GDestroyNotify) g_closure_unref);
g_source_remove (renderer_native->power_save_page_flip_source_id);
}
g_hash_table_destroy (renderer_native->gpu_datas);
g_clear_object (&renderer_native->gles3);

View File

@@ -97,8 +97,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
GList *l;
int min_width, min_height;
Screen *screen;
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
GList *outputs = NULL;
GList *modes = NULL;
GList *crtcs = NULL;
@@ -107,36 +105,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
XRRFreeScreenResources (gpu_xrandr->resources);
gpu_xrandr->resources = NULL;
dpms_capable = DPMSCapable (xdisplay);
if (dpms_capable &&
DPMSInfo (xdisplay, &dpms_state, &dpms_enabled) &&
dpms_enabled)
{
switch (dpms_state)
{
case DPMSModeOn:
monitor_manager->power_save_mode = META_POWER_SAVE_ON;
break;
case DPMSModeStandby:
monitor_manager->power_save_mode = META_POWER_SAVE_STANDBY;
break;
case DPMSModeSuspend:
monitor_manager->power_save_mode = META_POWER_SAVE_SUSPEND;
break;
case DPMSModeOff:
monitor_manager->power_save_mode = META_POWER_SAVE_OFF;
break;
default:
monitor_manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
break;
}
}
else
{
monitor_manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
}
XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
&min_width,
&min_height,

View File

@@ -121,6 +121,50 @@ meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
return meta_output_xrandr_read_edid (output);
}
static MetaPowerSave
x11_dpms_state_to_power_save (CARD16 dpms_state)
{
switch (dpms_state)
{
case DPMSModeOn:
return META_POWER_SAVE_ON;
case DPMSModeStandby:
return META_POWER_SAVE_STANDBY;
case DPMSModeSuspend:
return META_POWER_SAVE_SUSPEND;
case DPMSModeOff:
return META_POWER_SAVE_OFF;
default:
return META_POWER_SAVE_UNSUPPORTED;
}
}
static void
meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
MetaMonitorManagerClass *parent_class =
META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class);
Display *xdisplay = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr);
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
MetaPowerSave power_save_mode;
dpms_capable = DPMSCapable (xdisplay);
if (dpms_capable &&
DPMSInfo (xdisplay, &dpms_state, &dpms_enabled) &&
dpms_enabled)
power_save_mode = x11_dpms_state_to_power_save (dpms_state);
else
power_save_mode = META_POWER_SAVE_UNSUPPORTED;
meta_monitor_manager_power_save_mode_changed (manager, power_save_mode);
parent_class->read_current_state (manager);
}
static void
meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
@@ -929,11 +973,11 @@ ensure_supported_monitor_scales (MetaMonitorManager *manager)
}
static float *
meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
@@ -1046,6 +1090,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
object_class->constructed = meta_monitor_manager_xrandr_constructed;
manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
manager_class->read_current_state = meta_monitor_manager_xrandr_read_current_state;
manager_class->ensure_initial_config = meta_monitor_manager_xrandr_ensure_initial_config;
manager_class->apply_monitors_config = meta_monitor_manager_xrandr_apply_monitors_config;
manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;

View File

@@ -615,7 +615,7 @@ create_pipeline (PipelineType type)
cogl_pipeline_set_layer_filters (templates[type],
0,
COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST,
COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR,
COGL_PIPELINE_FILTER_LINEAR);
return cogl_pipeline_copy (templates[type]);

View File

@@ -128,7 +128,7 @@ MetaShadowClassInfo default_shadow_classes[] = {
{ "popup-menu", { 1, -1, 0, 0, 128 }, { 1, -1, 0, 0, 128 } },
{ "dropdown-menu", { 1, -1, 0, 0, 128 }, { 1, -1, 0, 0, 128 } },
{ "attached", { 0, -1, 0, 0, 0 }, { 0, -1, 0, 0, 0 } }
{ "attached", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } }
};
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);

View File

@@ -34,10 +34,8 @@
* function then checks what kind of visual flash you like, and calls either
* bell_flash_fullscreen()-- which calls bell_flash_screen() to do
* its work-- or bell_flash_frame(), which flashes the focussed window
* using bell_flash_window_frame(), unless there is no such window, in
* which case it flashes the screen instead. bell_flash_window_frame()
* flashes the frame and calls bell_unflash_frame() as a timeout to
* remove the flash.
* using bell_flash_window(), unless there is no such window, in
* which case it flashes the screen instead.
*
* The visual bell was the result of a discussion in Bugzilla here:
* <http://bugzilla.gnome.org/show_bug.cgi?id=99886>.
@@ -135,62 +133,6 @@ bell_flash_fullscreen (MetaDisplay *display)
meta_compositor_flash_display (display->compositor, display);
}
/**
* bell_unflash_frame:
* @data: The frame to unflash, cast to a gpointer so it can go into
* a callback function.
*
* Makes a frame be not flashed; this is the timeout half of
* bell_flash_window_frame(). This is done simply by clearing the
* flash flag and queuing a redraw of the frame.
*
* If the configure script found we had no XKB, this does not exist.
*
* Returns: Always FALSE, so we don't get called again.
*/
/*
* Bug: This is the parallel to bell_flash_window_frame(), so it should
* really be called meta_bell_unflash_window_frame().
*/
static gboolean
bell_unflash_frame (gpointer data)
{
MetaFrame *frame = (MetaFrame *) data;
frame->is_flashing = 0;
meta_frame_queue_draw (frame);
return FALSE;
}
/**
* bell_flash_window_frame:
* @window: The window to flash
*
* Makes a frame flash and then return to normal shortly afterwards.
* This is done by setting a flag so that the theme
* code will temporarily draw the frame as focussed if it's unfocussed and
* vice versa, and then queueing a redraw. Lastly, we create a timeout so
* that the flag can be unset and the frame re-redrawn.
*
* If the configure script found we had no XKB, this does not exist.
*/
static void
bell_flash_window_frame (MetaWindow *window)
{
guint id;
g_assert (window->frame != NULL);
window->frame->is_flashing = 1;
meta_frame_queue_draw (window->frame);
/* Since this idle is added after the Clutter clock source, with
* the same priority, it will be executed after it as well, so
* we are guaranteed to get at least one frame drawn in the
* flashed state, no matter how loaded we are.
*/
id = g_timeout_add_full (META_PRIORITY_REDRAW, 100,
bell_unflash_frame, window->frame, NULL);
g_source_set_name_by_id (id, "[mutter] bell_unflash_frame");
}
static void
bell_flash_window (MetaWindow *window)
{
@@ -209,9 +151,7 @@ static void
bell_flash_frame (MetaDisplay *display,
MetaWindow *window)
{
if (window && window->frame)
bell_flash_window_frame (window);
else if (window)
if (window)
bell_flash_window (window);
else
bell_flash_fullscreen (display);
@@ -267,19 +207,3 @@ meta_bell_notify (MetaDisplay *display,
return TRUE;
}
/**
* meta_bell_notify_frame_destroy:
* @frame: The frame which is being destroyed
*
* Deals with a frame being destroyed. This is important because if we're
* using a visual bell, we might be flashing the edges of the frame, and
* so we'd have a timeout function waiting ready to un-flash them. If the
* frame's going away, we can tell the timeout not to bother.
*/
void
meta_bell_notify_frame_destroy (MetaFrame *frame)
{
if (frame->is_flashing)
g_source_remove_by_funcs_user_data (&g_timeout_funcs, frame);
}

View File

@@ -41,14 +41,3 @@ MetaBell * meta_bell_new (MetaDisplay *display);
*/
gboolean meta_bell_notify (MetaDisplay *display,
MetaWindow *window);
/**
* meta_bell_notify_frame_destroy:
* @frame: The frame which is being destroyed
*
* Deals with a frame being destroyed. This is important because if we're
* using a visual bell, we might be flashing the edges of the frame, and
* so we'd have a timeout function waiting ready to un-flash them. If the
* frame's going away, we can tell the timeout not to bother.
*/
void meta_bell_notify_frame_destroy (MetaFrame *frame);

View File

@@ -243,7 +243,7 @@ GList* meta_rectangle_find_nonintersected_monitor_edges (
const GSList *all_struts);
META_EXPORT_TEST
gboolean meta_rectangle_is_adjecent_to (MetaRectangle *rect,
gboolean meta_rectangle_is_adjacent_to (MetaRectangle *rect,
MetaRectangle *other);
META_EXPORT_TEST

View File

@@ -468,7 +468,7 @@ merge_spanning_rects_in_region (GList *region)
delete_me = other;
}
/* If b contains a, just remove a */
else if (meta_rectangle_contains_rect (a, b))
else if (meta_rectangle_contains_rect (b, a))
{
delete_me = compare;
}
@@ -2026,7 +2026,7 @@ meta_rectangle_find_nonintersected_monitor_edges (
}
gboolean
meta_rectangle_is_adjecent_to (MetaRectangle *rect,
meta_rectangle_is_adjacent_to (MetaRectangle *rect,
MetaRectangle *other)
{
int rect_x1 = rect->x;

View File

@@ -145,6 +145,8 @@ typedef struct
*/
GList *usable_screen_region;
GList *usable_monitor_region;
gboolean should_unmanage;
} ConstraintInfo;
static gboolean do_screen_and_monitor_relative_constraints (MetaWindow *window,
@@ -253,6 +255,14 @@ do_all_constraints (MetaWindow *window,
satisfied = satisfied &&
(*constraint->func) (window, info, priority, check_only);
if (info->should_unmanage)
{
meta_topic (META_DEBUG_GEOMETRY,
"constraint %s wants to unmanage window.\n",
constraint->name);
return TRUE;
}
if (!check_only)
{
/* Log how the constraint modified the position */
@@ -312,6 +322,12 @@ meta_window_constrain (MetaWindow *window,
*/
satisfied = do_all_constraints (window, &info, priority, check_only);
if (info.should_unmanage)
{
meta_window_unmanage_on_idle (window);
return;
}
/* Drop the least important constraints if we can't satisfy them all */
priority++;
}
@@ -421,6 +437,8 @@ setup_constraint_info (ConstraintInfo *info,
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
info->should_unmanage = FALSE;
/* Log all this information for debugging */
meta_topic (META_DEBUG_GEOMETRY,
"Setting up constraint info:\n"
@@ -761,7 +779,7 @@ try_flip_window_position (MetaWindow *window,
}
static gboolean
is_custom_rule_satisfied (ConstraintInfo *info,
is_custom_rule_satisfied (MetaRectangle *rect,
MetaPlacementRule *placement_rule,
MetaRectangle *intersection)
{
@@ -772,9 +790,9 @@ is_custom_rule_satisfied (ConstraintInfo *info,
y_constrain_actions = (META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y |
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y);
if ((placement_rule->constraint_adjustment & x_constrain_actions &&
info->current.width != intersection->width) ||
rect->width != intersection->width) ||
(placement_rule->constraint_adjustment & y_constrain_actions &&
info->current.height != intersection->height))
rect->height != intersection->height))
return FALSE;
else
return TRUE;
@@ -789,6 +807,7 @@ constrain_custom_rule (MetaWindow *window,
MetaPlacementRule *placement_rule;
MetaRectangle intersection;
gboolean constraint_satisfied;
MetaRectangle adjusted_unconstrained;
MetaPlacementRule current_rule;
MetaWindow *parent;
MetaRectangle parent_rect;
@@ -800,30 +819,65 @@ constrain_custom_rule (MetaWindow *window,
if (!placement_rule)
return TRUE;
if (window->placement_rule_constrained)
{
parent = meta_window_get_transient_for (window);
meta_window_get_frame_rect (parent, &parent_rect);
info->current.x =
parent_rect.x + window->constrained_placement_rule_offset_x;
info->current.y =
parent_rect.y + window->constrained_placement_rule_offset_y;
adjusted_unconstrained = info->current;
return TRUE;
parent = meta_window_get_transient_for (window);
meta_window_get_frame_rect (parent, &parent_rect);
switch (window->placement_state)
{
case META_PLACEMENT_STATE_UNCONSTRAINED:
break;
case META_PLACEMENT_STATE_CONSTRAINED:
adjusted_unconstrained.x =
parent_rect.x + window->constrained_placement_rule_offset_x;
adjusted_unconstrained.y =
parent_rect.y + window->constrained_placement_rule_offset_y;
break;
}
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
meta_rectangle_intersect (&adjusted_unconstrained, &info->work_area_monitor,
&intersection);
constraint_satisfied = is_custom_rule_satisfied (info,
placement_rule,
&intersection);
constraint_satisfied = (meta_rectangle_equal (&info->current,
&adjusted_unconstrained) &&
is_custom_rule_satisfied (&adjusted_unconstrained,
placement_rule,
&intersection));
if (check_only)
return constraint_satisfied;
current_rule = *placement_rule;
switch (window->placement_state)
{
case META_PLACEMENT_STATE_CONSTRAINED:
{
MetaRectangle parent_buffer_rect;
meta_window_get_buffer_rect (parent, &parent_buffer_rect);
if (!meta_rectangle_overlap (&adjusted_unconstrained,
&parent_buffer_rect) &&
!meta_rectangle_is_adjacent_to (&adjusted_unconstrained,
&parent_buffer_rect))
{
g_warning ("Buggy client caused popup to be placed outside of "
"parent window");
info->should_unmanage = TRUE;
return TRUE;
}
else
{
info->current = adjusted_unconstrained;
goto done;
}
break;
}
case META_PLACEMENT_STATE_UNCONSTRAINED:
break;
}
if (constraint_satisfied)
goto done;
@@ -846,7 +900,7 @@ constrain_custom_rule (MetaWindow *window,
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
&intersection);
constraint_satisfied = is_custom_rule_satisfied (info,
constraint_satisfied = is_custom_rule_satisfied (&info->current,
placement_rule,
&intersection);
@@ -856,23 +910,47 @@ constrain_custom_rule (MetaWindow *window,
if (current_rule.constraint_adjustment &
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X)
{
if (info->current.x != intersection.x)
info->current.x = intersection.x;
else if (info->current.width != intersection.width)
info->current.x -= info->current.width - intersection.width;
int current_x2;
int work_area_monitor_x2;
current_x2 = info->current.x + info->current.width;
work_area_monitor_x2 = (info->work_area_monitor.x +
info->work_area_monitor.width);
if (current_x2 > work_area_monitor_x2)
{
info->current.x = MAX (info->work_area_monitor.x,
work_area_monitor_x2 - info->current.width);
}
else if (info->current.x < info->work_area_monitor.x)
{
info->current.x = info->work_area_monitor.x;
}
}
if (current_rule.constraint_adjustment &
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y)
{
if (info->current.y != intersection.y)
info->current.y = intersection.y;
else if (info->current.height != intersection.height)
info->current.y -= info->current.height - intersection.height;
int current_y2;
int work_area_monitor_y2;
current_y2 = info->current.y + info->current.height;
work_area_monitor_y2 = (info->work_area_monitor.y +
info->work_area_monitor.height);
if (current_y2 > work_area_monitor_y2)
{
info->current.y = MAX (info->work_area_monitor.y,
work_area_monitor_y2 - info->current.height);
}
else if (info->current.y < info->work_area_monitor.y)
{
info->current.y = info->work_area_monitor.y;
}
}
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
&intersection);
constraint_satisfied = is_custom_rule_satisfied (info,
constraint_satisfied = is_custom_rule_satisfied (&info->current,
placement_rule,
&intersection);
@@ -893,10 +971,8 @@ constrain_custom_rule (MetaWindow *window,
}
done:
window->placement_rule_constrained = TRUE;
window->placement_state = META_PLACEMENT_STATE_CONSTRAINED;
parent = meta_window_get_transient_for (window);
meta_window_get_frame_rect (parent, &parent_rect);
window->constrained_placement_rule_offset_x = info->current.x - parent_rect.x;
window->constrained_placement_rule_offset_y = info->current.y - parent_rect.y;

View File

@@ -31,10 +31,6 @@
#include <X11/extensions/sync.h>
#include <X11/Xlib.h>
#ifdef HAVE_STARTUP_NOTIFICATION
#include <libsn/sn.h>
#endif
#include "clutter/clutter.h"
#include "core/keybindings-private.h"
#include "core/meta-gesture-tracker-private.h"

View File

@@ -60,7 +60,6 @@ meta_window_ensure_frame (MetaWindow *window)
frame->right_width = 0;
frame->current_cursor = 0;
frame->is_flashing = FALSE;
frame->borders_cached = FALSE;
meta_verbose ("Frame geometry %d,%d %dx%d\n",
@@ -177,8 +176,6 @@ meta_window_destroy_frame (MetaWindow *window)
meta_frame_calc_borders (frame, &borders);
meta_bell_notify_frame_destroy (frame);
/* Unparent the client window; it may be destroyed,
* thus the error trap.
*/
@@ -298,9 +295,6 @@ meta_frame_get_flags (MetaFrame *frame)
if (frame->window->fullscreen)
flags |= META_FRAME_FULLSCREEN;
if (frame->is_flashing)
flags |= META_FRAME_IS_FLASHING;
if (frame->window->wm_state_above)
flags |= META_FRAME_ABOVE;

View File

@@ -49,7 +49,6 @@ struct _MetaFrame
int bottom_height;
guint need_reapply_frame_shape : 1;
guint is_flashing : 1; /* used by the visual bell flash */
guint borders_cached : 1;
MetaUIFrame *ui_frame;

View File

@@ -1654,7 +1654,7 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
MetaKeyBindingManager *keys = &display->key_binding_manager;
MetaKeyBinding *binding;
MetaKeyGrab *grab;
char *key;
g_autofree char *key = NULL;
MetaResolvedKeyCombo resolved_combo = { NULL, 0 };
g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE);
@@ -1683,7 +1683,6 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
}
g_hash_table_remove (external_grabs, key);
g_free (key);
resolved_key_combo_reset (&resolved_combo);
return TRUE;
@@ -2215,6 +2214,8 @@ meta_keybindings_process_event (MetaDisplay *display,
{
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_END:
keys->overlay_key_only_pressed = FALSE;
return FALSE;

View File

@@ -118,11 +118,6 @@ static void prefs_changed_callback (MetaPreference pref,
static void
meta_print_compilation_info (void)
{
#ifdef HAVE_STARTUP_NOTIFICATION
meta_verbose ("Compiled with startup notification\n");
#else
meta_verbose ("Compiled without startup notification\n");
#endif
}
/**

View File

@@ -119,40 +119,37 @@ meta_launch_context_constructed (GObject *object)
"WAYLAND_DISPLAY", getenv ("WAYLAND_DISPLAY"));
}
static gchar *
create_startup_notification_id (uint32_t timestamp)
{
gchar *uuid, *id;
uuid = g_uuid_string_random ();
id = g_strdup_printf ("%s_TIME%u", uuid, timestamp);
g_free (uuid);
return id;
}
static gchar *
meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context,
GAppInfo *info,
GList *files)
{
MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context);
MetaDisplay *display = context->display;
int workspace_idx = -1;
char *startup_id = NULL;
if (context->workspace)
workspace_idx = meta_workspace_index (context->workspace);
if (display->x11_display)
{
/* If there is a X11 display, we prefer going entirely through
* libsn, as SnMonitor expects to keep a view of the full lifetime
* of the startup sequence. We can't avoid it when launching and
* expect that a "remove" message from a X11 client will be handled.
*/
startup_id =
meta_x11_startup_notification_launch (display->x11_display,
info,
workspace_idx,
context->timestamp);
}
if (!startup_id)
{
const char *application_id = NULL;
MetaStartupNotification *sn;
MetaStartupSequence *seq;
startup_id = g_uuid_string_random ();
startup_id = create_startup_notification_id (context->timestamp);
/* Fallback through inserting our own startup sequence, this
* will be enough for wayland clients.

View File

@@ -111,7 +111,7 @@ static gboolean resize_with_right_button = FALSE;
static gboolean edge_tiling = FALSE;
static gboolean force_fullscreen = TRUE;
static gboolean auto_maximize = TRUE;
static gboolean show_fallback_app_menu = FALSE;
static gboolean show_fallback_app_menu = TRUE;
static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH;
static MetaButtonLayout button_layout;

View File

@@ -37,7 +37,7 @@
* OpenOffice or whatever seems to stop launching - people
* might decide they need to launch it again.
*/
#define STARTUP_TIMEOUT 15000000
#define STARTUP_TIMEOUT_MS 15000
enum
{
@@ -59,6 +59,12 @@ enum
N_SEQ_PROPS
};
enum
{
SEQ_COMPLETE,
N_SEQ_SIGNALS
};
enum
{
CHANGED,
@@ -67,6 +73,7 @@ enum
static guint sn_signals[N_SIGNALS];
static GParamSpec *sn_props[N_PROPS];
static guint seq_signals[N_SEQ_SIGNALS];
static GParamSpec *seq_props[N_SEQ_PROPS];
typedef struct
@@ -106,12 +113,26 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupSequence,
static void meta_startup_notification_ensure_timeout (MetaStartupNotification *sn);
static gboolean
meta_startup_notification_has_pending_sequences (MetaStartupNotification *sn)
{
GSList *l;
for (l = sn->startup_sequences; l; l = l->next)
{
if (!meta_startup_sequence_get_completed (l->data))
return TRUE;
}
return FALSE;
}
static void
meta_startup_notification_update_feedback (MetaStartupNotification *sn)
{
MetaDisplay *display = sn->display;
if (sn->startup_sequences != NULL)
if (meta_startup_notification_has_pending_sequences (sn))
{
meta_topic (META_DEBUG_STARTUP,
"Setting busy cursor\n");
@@ -239,6 +260,14 @@ meta_startup_sequence_class_init (MetaStartupSequenceClass *klass)
object_class->set_property = meta_startup_sequence_set_property;
object_class->get_property = meta_startup_sequence_get_property;
seq_signals[SEQ_COMPLETE] =
g_signal_new ("complete",
META_TYPE_STARTUP_SEQUENCE,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MetaStartupSequenceClass, complete),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
seq_props[PROP_SEQ_ID] =
g_param_spec_string ("id",
"ID",
@@ -317,7 +346,6 @@ meta_startup_sequence_get_timestamp (MetaStartupSequence *seq)
void
meta_startup_sequence_complete (MetaStartupSequence *seq)
{
MetaStartupSequenceClass *klass;
MetaStartupSequencePrivate *priv;
g_return_if_fail (META_IS_STARTUP_SEQUENCE (seq));
@@ -327,10 +355,7 @@ meta_startup_sequence_complete (MetaStartupSequence *seq)
return;
priv->completed = TRUE;
klass = META_STARTUP_SEQUENCE_GET_CLASS (seq);
if (klass->complete)
klass->complete (seq);
g_signal_emit (seq, seq_signals[SEQ_COMPLETE], 0);
}
gboolean
@@ -399,12 +424,22 @@ meta_startup_sequence_get_wmclass (MetaStartupSequence *seq)
return priv->wmclass;
}
static void
on_sequence_completed (MetaStartupSequence *seq,
MetaStartupNotification *sn)
{
meta_startup_notification_update_feedback (sn);
g_signal_emit (sn, sn_signals[CHANGED], 0, seq);
}
void
meta_startup_notification_add_sequence (MetaStartupNotification *sn,
MetaStartupSequence *seq)
{
sn->startup_sequences = g_slist_prepend (sn->startup_sequences,
g_object_ref (seq));
g_signal_connect (seq, "complete",
G_CALLBACK (on_sequence_completed), sn);
meta_startup_notification_ensure_timeout (sn);
meta_startup_notification_update_feedback (sn);
@@ -425,10 +460,10 @@ collect_timed_out_foreach (void *element,
meta_topic (META_DEBUG_STARTUP,
"Sequence used %" G_GINT64_FORMAT " ms vs. %d max: %s\n",
elapsed, STARTUP_TIMEOUT,
elapsed, STARTUP_TIMEOUT_MS,
meta_startup_sequence_get_id (sequence));
if (elapsed > STARTUP_TIMEOUT)
if (elapsed > STARTUP_TIMEOUT_MS)
ctod->list = g_slist_prepend (ctod->list, sequence);
}
@@ -440,7 +475,7 @@ startup_sequence_timeout (void *data)
GSList *l;
ctod.list = NULL;
ctod.now = g_get_monotonic_time ();
ctod.now = g_get_monotonic_time () / 1000;
g_slist_foreach (sn->startup_sequences,
collect_timed_out_foreach,
&ctod);
@@ -454,6 +489,7 @@ startup_sequence_timeout (void *data)
meta_startup_sequence_get_id (sequence));
meta_startup_sequence_complete (sequence);
meta_startup_notification_remove_sequence (sn, sequence);
}
g_slist_free (ctod.list);
@@ -493,6 +529,8 @@ meta_startup_notification_remove_sequence (MetaStartupNotification *sn,
sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq);
meta_startup_notification_update_feedback (sn);
g_signal_handlers_disconnect_by_func (seq, on_sequence_completed, sn);
if (sn->startup_sequences == NULL &&
sn->startup_sequence_timeout != 0)
{

View File

@@ -142,6 +142,12 @@ typedef struct _MetaPlacementRule
int height;
} MetaPlacementRule;
typedef enum _MetaPlacementState
{
META_PLACEMENT_STATE_UNCONSTRAINED,
META_PLACEMENT_STATE_CONSTRAINED,
} MetaPlacementState;
typedef enum
{
META_EDGE_CONSTRAINT_NONE = 0,
@@ -524,9 +530,11 @@ struct _MetaWindow
guint bypass_compositor;
MetaPlacementRule *placement_rule;
gboolean placement_rule_constrained;
MetaPlacementState placement_state;
int constrained_placement_rule_offset_x;
int constrained_placement_rule_offset_y;
guint unmanage_idle_id;
};
struct _MetaWindowClass
@@ -610,6 +618,7 @@ MetaWindow * _meta_window_shared_new (MetaDisplay *display,
void meta_window_unmanage (MetaWindow *window,
guint32 timestamp);
void meta_window_unmanage_on_idle (MetaWindow *window);
void meta_window_queue (MetaWindow *window,
guint queuebits);
void meta_window_tile (MetaWindow *window,

View File

@@ -1424,6 +1424,9 @@ meta_window_unmanage (MetaWindow *window,
meta_verbose ("Unmanaging %s\n", window->desc);
window->unmanaging = TRUE;
if (window->unmanage_idle_id)
g_source_remove (window->unmanage_idle_id);
#ifdef HAVE_WAYLAND
/* This needs to happen for both Wayland and XWayland clients,
* so it can't be in MetaWindowWayland. */
@@ -1595,6 +1598,32 @@ meta_window_unmanage (MetaWindow *window,
g_object_unref (window);
}
static gboolean
unmanage_window_idle_callback (gpointer user_data)
{
MetaWindow *window = META_WINDOW (user_data);
uint32_t timestamp;
window->unmanage_idle_id = 0;
timestamp = meta_display_get_current_time_roundtrip (window->display);
meta_window_unmanage (window, timestamp);
return G_SOURCE_REMOVE;
}
void
meta_window_unmanage_on_idle (MetaWindow *window)
{
if (window->unmanage_idle_id)
return;
window->unmanage_idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE,
unmanage_window_idle_callback,
window,
NULL);
}
static void
set_wm_state (MetaWindow *window)
{
@@ -3781,6 +3810,9 @@ static gboolean
maybe_move_attached_window (MetaWindow *window,
void *data)
{
if (window->hidden)
return FALSE;
if (meta_window_is_attached_dialog (window) ||
meta_window_get_placement_rule (window))
meta_window_reposition (window);

View File

@@ -1,4 +1,5 @@
mutter_includedir = join_paths(pkgincludedir, 'meta')
mutter_includesubdir = join_paths(pkgname, 'meta')
mutter_includedir = join_paths(includedir, mutter_includesubdir)
mutter_includes = [
include_directories('.'),
@@ -54,12 +55,6 @@ if have_libgudev
]
endif
if have_startup_notification
mutter_pkg_private_deps += [
libstartup_notification_dep,
]
endif
if have_libwacom
mutter_pkg_private_deps += [
libwacom_dep,

View File

@@ -63,7 +63,6 @@
* @META_FRAME_ALLOWS_SHADE: frame allows shade
* @META_FRAME_ALLOWS_MOVE: frame allows move
* @META_FRAME_FULLSCREEN: frame allows fullscreen
* @META_FRAME_IS_FLASHING: frame is flashing
* @META_FRAME_ABOVE: frame is above
* @META_FRAME_TILED_LEFT: frame is tiled to the left
* @META_FRAME_TILED_RIGHT: frame is tiled to the right
@@ -83,10 +82,9 @@ typedef enum
META_FRAME_ALLOWS_SHADE = 1 << 10,
META_FRAME_ALLOWS_MOVE = 1 << 11,
META_FRAME_FULLSCREEN = 1 << 12,
META_FRAME_IS_FLASHING = 1 << 13,
META_FRAME_ABOVE = 1 << 14,
META_FRAME_TILED_LEFT = 1 << 15,
META_FRAME_TILED_RIGHT = 1 << 16
META_FRAME_ABOVE = 1 << 13,
META_FRAME_TILED_LEFT = 1 << 14,
META_FRAME_TILED_RIGHT = 1 << 15
} MetaFrameFlags;
/**

View File

@@ -48,7 +48,7 @@ if have_x11
endif
install_headers(mutter_public_headers,
subdir: mutter_includedir
subdir: mutter_includesubdir
)
mutter_public_header_files = files(mutter_public_headers)

View File

@@ -373,11 +373,11 @@ meta_monitor_manager_test_calculate_monitor_mode_scale (MetaMonitorManager *mana
}
static float *
meta_monitor_manager_test_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
meta_monitor_manager_test_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorScalesConstraint constraints =
META_MONITOR_SCALES_CONSTRAINT_NONE;

View File

@@ -185,10 +185,10 @@ meta_test_util_later_schedule_from_later (void)
}
static void
meta_test_adjecent_to (void)
meta_test_adjacent_to (void)
{
MetaRectangle base = { .x = 10, .y = 10, .width = 10, .height = 10 };
MetaRectangle adjecent[] = {
MetaRectangle adjacent[] = {
{ .x = 20, .y = 10, .width = 10, .height = 10 },
{ .x = 0, .y = 10, .width = 10, .height = 10 },
{ .x = 0, .y = 1, .width = 10, .height = 10 },
@@ -196,7 +196,7 @@ meta_test_adjecent_to (void)
{ .x = 10, .y = 20, .width = 10, .height = 10 },
{ .x = 10, .y = 0, .width = 10, .height = 10 },
};
MetaRectangle not_adjecent[] = {
MetaRectangle not_adjacent[] = {
{ .x = 0, .y = 0, .width = 10, .height = 10 },
{ .x = 20, .y = 20, .width = 10, .height = 10 },
{ .x = 21, .y = 10, .width = 10, .height = 10 },
@@ -207,11 +207,11 @@ meta_test_adjecent_to (void)
};
unsigned int i;
for (i = 0; i < G_N_ELEMENTS (adjecent); i++)
g_assert (meta_rectangle_is_adjecent_to (&base, &adjecent[i]));
for (i = 0; i < G_N_ELEMENTS (adjacent); i++)
g_assert (meta_rectangle_is_adjacent_to (&base, &adjacent[i]));
for (i = 0; i < G_N_ELEMENTS (not_adjecent); i++)
g_assert (!meta_rectangle_is_adjecent_to (&base, &not_adjecent[i]));
for (i = 0; i < G_N_ELEMENTS (not_adjacent); i++)
g_assert (!meta_rectangle_is_adjacent_to (&base, &not_adjacent[i]));
}
static gboolean
@@ -245,7 +245,7 @@ init_tests (int argc, char **argv)
g_test_add_func ("/util/meta-later/schedule-from-later",
meta_test_util_later_schedule_from_later);
g_test_add_func ("/core/boxes/adjecent-to", meta_test_adjecent_to);
g_test_add_func ("/core/boxes/adjacent-to", meta_test_adjacent_to);
init_monitor_store_tests ();
init_monitor_config_migration_tests ();

View File

@@ -1186,8 +1186,6 @@ meta_style_info_set_flags (MetaStyleInfo *style_info,
int i;
backdrop = !(flags & META_FRAME_HAS_FOCUS);
if (flags & META_FRAME_IS_FLASHING)
backdrop = !backdrop;
if (flags & META_FRAME_MAXIMIZED)
class_name = "maximized";

View File

@@ -119,14 +119,6 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
return TRUE;
}
if (meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
EGL_TEXTURE_FORMAT, &format,
NULL))
{
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_IMAGE;
return TRUE;
}
#ifdef HAVE_WAYLAND_EGLSTREAM
stream = meta_wayland_egl_stream_new (buffer, NULL);
if (stream)
@@ -146,6 +138,14 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
}
#endif /* HAVE_WAYLAND_EGLSTREAM */
if (meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
EGL_TEXTURE_FORMAT, &format,
NULL))
{
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_IMAGE;
return TRUE;
}
dma_buf = meta_wayland_dma_buf_from_buffer (buffer);
if (dma_buf)
{

View File

@@ -258,7 +258,7 @@ zxdg_toplevel_v6_show_window_menu (struct wl_client *client,
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL))
return;
monitor_scale = window->monitor->scale;
monitor_scale = meta_window_wayland_get_geometry_scale (window);
meta_window_show_menu (window, META_WINDOW_MENU_WM,
window->buffer_rect.x + (x * monitor_scale),
window->buffer_rect.y + (y * monitor_scale));

View File

@@ -624,14 +624,14 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
wl_resource_get_version (resource),
id);
wl_resource_set_implementation (xdg_output_resource,
&meta_xdg_output_interface,
NULL, meta_xdg_output_destructor);
wayland_output = wl_resource_get_user_data (output);
if (!wayland_output)
return;
wl_resource_set_implementation (xdg_output_resource,
&meta_xdg_output_interface,
wayland_output, meta_xdg_output_destructor);
wayland_output->xdg_output_resources =
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);

View File

@@ -72,6 +72,8 @@ struct _MetaWaylandTextInput
uint32_t content_type_purpose;
uint32_t text_change_cause;
gboolean enabled;
guint done_idle_id;
};
struct _MetaWaylandTextInputFocus
@@ -116,6 +118,52 @@ increment_serial (MetaWaylandTextInput *text_input,
GUINT_TO_POINTER (serial + 1));
}
static gboolean
done_idle_cb (gpointer user_data)
{
ClutterInputFocus *focus = user_data;
MetaWaylandTextInput *text_input;
struct wl_resource *resource;
text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input;
wl_resource_for_each (resource, &text_input->focus_resource_list)
{
zwp_text_input_v3_send_done (resource,
lookup_serial (text_input, resource));
}
text_input->done_idle_id = 0;
return G_SOURCE_REMOVE;
}
static void
meta_wayland_text_input_focus_defer_done (ClutterInputFocus *focus)
{
MetaWaylandTextInput *text_input;
text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input;
if (text_input->done_idle_id != 0)
return;
/* This operates on 3 principles:
* - GDBus uses G_PRIORITY_DEFAULT to put messages in the thread default main
* context.
* - All relevant ClutterInputFocus methods are ultimately backed by
* DBus methods inside IBus.
* - We want to run .done after them all. The slightly lower
* G_PRIORITY_DEFAULT + 1 priority should ensure we at least group
* all messages seen so far.
*
* FIXME: .done may be delayed indefinitely if there's a high enough
* priority idle source in the main loop. It's unlikely that
* recurring idles run at this high priority though.
*/
text_input->done_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT + 1,
done_idle_cb, focus, NULL);
}
static void
meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
guint cursor,
@@ -129,9 +177,9 @@ meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
wl_resource_for_each (resource, &text_input->focus_resource_list)
{
zwp_text_input_v3_send_delete_surrounding_text (resource, cursor, len);
zwp_text_input_v3_send_done (resource,
lookup_serial (text_input, resource));
}
meta_wayland_text_input_focus_defer_done (focus);
}
static void
@@ -147,9 +195,9 @@ meta_wayland_text_input_focus_commit_text (ClutterInputFocus *focus,
{
zwp_text_input_v3_send_preedit_string (resource, NULL, 0, 0);
zwp_text_input_v3_send_commit_string (resource, text);
zwp_text_input_v3_send_done (resource,
lookup_serial (text_input, resource));
}
meta_wayland_text_input_focus_defer_done (focus);
}
static void
@@ -165,9 +213,9 @@ meta_wayland_text_input_focus_set_preedit_text (ClutterInputFocus *focus,
wl_resource_for_each (resource, &text_input->focus_resource_list)
{
zwp_text_input_v3_send_preedit_string (resource, text, cursor, cursor);
zwp_text_input_v3_send_done (resource,
lookup_serial (text_input, resource));
}
meta_wayland_text_input_focus_defer_done (focus);
}
static void

View File

@@ -264,7 +264,7 @@ xdg_toplevel_show_window_menu (struct wl_client *client,
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL))
return;
monitor_scale = window->monitor->scale;
monitor_scale = meta_window_wayland_get_geometry_scale (window);
meta_window_show_menu (window, META_WINDOW_MENU_WM,
window->buffer_rect.x + (x * monitor_scale),
window->buffer_rect.y + (y * monitor_scale));
@@ -921,6 +921,22 @@ scale_placement_rule (MetaPlacementRule *placement_rule,
placement_rule->height *= geometry_scale;
}
static void
meta_wayland_xdg_popup_place (MetaWaylandXdgPopup *xdg_popup,
MetaPlacementRule *placement_rule)
{
MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaPlacementRule scaled_placement_rule;
scaled_placement_rule = *placement_rule;
scale_placement_rule (&scaled_placement_rule, surface);
meta_window_place_with_placement_rule (surface->window,
&scaled_placement_rule);
}
static void
finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
{
@@ -933,7 +949,6 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurface *parent_surface;
MetaPlacementRule scaled_placement_rule;
MetaWaylandSeat *seat;
uint32_t serial;
MetaDisplay *display = meta_get_display ();
@@ -981,9 +996,7 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
window = meta_window_wayland_new (display, surface);
meta_wayland_shell_surface_set_window (shell_surface, window);
scaled_placement_rule = xdg_popup->setup.placement_rule;
scale_placement_rule (&scaled_placement_rule, surface);
meta_window_place_with_placement_rule (window, &scaled_placement_rule);
meta_wayland_xdg_popup_place (xdg_popup, &xdg_popup->setup.placement_rule);
if (seat)
{

View File

@@ -26,266 +26,301 @@
#include "meta/meta-x11-errors.h"
#include "x11/meta-x11-display-private.h"
#ifdef HAVE_STARTUP_NOTIFICATION
#define MAX_MESSAGE_LENGTH 4096
#define CLIENT_MESSAGE_DATA_LENGTH 20
enum
{
PROP_SEQ_X11_0,
PROP_SEQ_X11_SEQ,
N_SEQ_X11_PROPS
};
struct _MetaStartupSequenceX11
{
MetaStartupSequence parent_instance;
SnStartupSequence *seq;
MESSAGE_TYPE_NEW,
MESSAGE_TYPE_REMOVE,
};
struct _MetaX11StartupNotification
{
SnDisplay *sn_display;
SnMonitorContext *sn_context;
Atom atom_net_startup_info_begin;
Atom atom_net_startup_info;
GHashTable *messages;
MetaX11Display *x11_display;
};
static GParamSpec *seq_x11_props[N_SEQ_X11_PROPS];
G_DEFINE_TYPE (MetaStartupSequenceX11,
meta_startup_sequence_x11,
META_TYPE_STARTUP_SEQUENCE)
static void
meta_startup_sequence_x11_complete (MetaStartupSequence *seq)
typedef struct
{
MetaStartupSequenceX11 *seq_x11;
Window xwindow;
GString *data;
} StartupMessage;
seq_x11 = META_STARTUP_SEQUENCE_X11 (seq);
sn_startup_sequence_complete (seq_x11->seq);
static StartupMessage *
startup_message_new (Window window)
{
StartupMessage *message;
message = g_new0 (StartupMessage, 1);
message->xwindow = window;
message->data = g_string_new (NULL);
return message;
}
static void
meta_startup_sequence_x11_finalize (GObject *object)
startup_message_free (StartupMessage *message)
{
MetaStartupSequenceX11 *seq_x11;
seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
sn_startup_sequence_unref (seq_x11->seq);
G_OBJECT_CLASS (meta_startup_sequence_x11_parent_class)->finalize (object);
g_string_free (message->data, TRUE);
g_free (message);
}
static void
meta_startup_sequence_x11_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
skip_whitespace (const gchar **str)
{
MetaStartupSequenceX11 *seq_x11;
while ((*str)[0] == ' ')
(*str)++;
}
seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
static gchar *
parse_key (const gchar **str)
{
const gchar *start = *str;
switch (prop_id)
while (*str[0] != '\0' && *str[0] != '=')
(*str)++;
if (start == *str)
return NULL;
return g_strndup (start, *str - start);
}
static gchar *
parse_value (const gchar **str)
{
const gchar *end;
gboolean escaped = FALSE, quoted = FALSE;
GString *value;
end = *str;
value = g_string_new (NULL);
while (end[0] != '\0')
{
case PROP_SEQ_X11_SEQ:
seq_x11->seq = g_value_get_pointer (value);
sn_startup_sequence_ref (seq_x11->seq);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
if (escaped)
{
g_string_append_c (value, end[0]);
escaped = FALSE;
}
else
{
if (!quoted && end[0] == ' ')
break;
else if (end[0] == '"')
quoted = !quoted;
else if (end[0] == '\\')
escaped = TRUE;
else
g_string_append_c (value, end[0]);
}
static void
meta_startup_sequence_x11_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaStartupSequenceX11 *seq_x11;
seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
switch (prop_id)
{
case PROP_SEQ_X11_SEQ:
g_value_set_pointer (value, seq_x11->seq);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_startup_sequence_x11_init (MetaStartupSequenceX11 *seq)
{
}
static void
meta_startup_sequence_x11_class_init (MetaStartupSequenceX11Class *klass)
{
MetaStartupSequenceClass *seq_class;
GObjectClass *object_class;
seq_class = META_STARTUP_SEQUENCE_CLASS (klass);
seq_class->complete = meta_startup_sequence_x11_complete;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_startup_sequence_x11_finalize;
object_class->set_property = meta_startup_sequence_x11_set_property;
object_class->get_property = meta_startup_sequence_x11_get_property;
seq_x11_props[PROP_SEQ_X11_SEQ] =
g_param_spec_pointer ("seq",
"Sequence",
"Sequence",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, N_SEQ_X11_PROPS,
seq_x11_props);
}
static MetaStartupSequence *
meta_startup_sequence_x11_new (SnStartupSequence *seq)
{
gint64 timestamp;
timestamp = sn_startup_sequence_get_timestamp (seq) * 1000;
return g_object_new (META_TYPE_STARTUP_SEQUENCE_X11,
"id", sn_startup_sequence_get_id (seq),
"icon-name", sn_startup_sequence_get_icon_name (seq),
"application-id", sn_startup_sequence_get_application_id (seq),
"wmclass", sn_startup_sequence_get_wmclass (seq),
"name", sn_startup_sequence_get_name (seq),
"workspace", sn_startup_sequence_get_workspace (seq),
"timestamp", timestamp,
"seq", seq,
NULL);
}
static void
sn_error_trap_push (SnDisplay *sn_display,
Display *xdisplay)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
if (display != NULL)
meta_x11_error_trap_push (display->x11_display);
}
static void
sn_error_trap_pop (SnDisplay *sn_display,
Display *xdisplay)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
if (display != NULL)
meta_x11_error_trap_pop (display->x11_display);
}
static void
meta_startup_notification_sn_event (SnMonitorEvent *event,
void *user_data)
{
MetaX11Display *x11_display = user_data;
MetaStartupNotification *sn = x11_display->display->startup_notification;
MetaStartupSequence *seq;
SnStartupSequence *sequence;
sequence = sn_monitor_event_get_startup_sequence (event);
sn_startup_sequence_ref (sequence);
switch (sn_monitor_event_get_type (event))
{
case SN_MONITOR_EVENT_INITIATED:
{
const char *wmclass;
wmclass = sn_startup_sequence_get_wmclass (sequence);
meta_topic (META_DEBUG_STARTUP,
"Received startup initiated for %s wmclass %s\n",
sn_startup_sequence_get_id (sequence),
wmclass ? wmclass : "(unset)");
seq = meta_startup_sequence_x11_new (sequence);
meta_startup_notification_add_sequence (sn, seq);
g_object_unref (seq);
}
break;
case SN_MONITOR_EVENT_COMPLETED:
{
meta_topic (META_DEBUG_STARTUP,
"Received startup completed for %s\n",
sn_startup_sequence_get_id (sequence));
seq = meta_startup_notification_lookup_sequence (sn, sn_startup_sequence_get_id (sequence));
if (seq)
{
meta_startup_sequence_complete (seq);
meta_startup_notification_remove_sequence (sn, seq);
}
}
break;
case SN_MONITOR_EVENT_CHANGED:
meta_topic (META_DEBUG_STARTUP,
"Received startup changed for %s\n",
sn_startup_sequence_get_id (sequence));
break;
case SN_MONITOR_EVENT_CANCELED:
meta_topic (META_DEBUG_STARTUP,
"Received startup canceled for %s\n",
sn_startup_sequence_get_id (sequence));
break;
end++;
}
sn_startup_sequence_unref (sequence);
*str = end;
if (value->len == 0)
{
g_string_free (value, TRUE);
return NULL;
}
return g_string_free (value, FALSE);
}
static gboolean
startup_message_parse (StartupMessage *message,
int *type,
gchar **id,
GHashTable **data)
{
const gchar *str = message->data->str;
if (strncmp (str, "new:", 4) == 0)
{
*type = MESSAGE_TYPE_NEW;
str += 4;
}
else if (strncmp (str, "remove:", 7) == 0)
{
*type = MESSAGE_TYPE_REMOVE;
str += 7;
}
else
{
return FALSE;
}
*data = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
while (str[0])
{
gchar *key, *value;
skip_whitespace (&str);
key = parse_key (&str);
if (!key)
break;
str++;
value = parse_value (&str);
if (!value)
{
g_free (key);
break;
}
g_hash_table_insert (*data, key, value);
}
*id = g_strdup (g_hash_table_lookup (*data, "ID"));
return TRUE;
}
static gboolean
startup_message_add_data (StartupMessage *message,
const gchar *data)
{
int len;
len = strnlen (data, CLIENT_MESSAGE_DATA_LENGTH);
g_string_append_len (message->data, data, len);
return (message->data->len > MAX_MESSAGE_LENGTH ||
len < CLIENT_MESSAGE_DATA_LENGTH);
}
#endif
void
meta_x11_startup_notification_init (MetaX11Display *x11_display)
{
#ifdef HAVE_STARTUP_NOTIFICATION
MetaX11StartupNotification *x11_sn;
x11_sn = g_new0 (MetaX11StartupNotification, 1);
x11_sn->sn_display = sn_display_new (x11_display->xdisplay,
sn_error_trap_push,
sn_error_trap_pop);
x11_sn->sn_context =
sn_monitor_context_new (x11_sn->sn_display,
meta_x11_display_get_screen_number (x11_display),
meta_startup_notification_sn_event,
x11_display,
NULL);
x11_sn->atom_net_startup_info_begin = XInternAtom (x11_display->xdisplay,
"_NET_STARTUP_INFO_BEGIN",
False);
x11_sn->atom_net_startup_info = XInternAtom (x11_display->xdisplay,
"_NET_STARTUP_INFO",
False);
x11_sn->messages = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) startup_message_free);
x11_sn->x11_display = x11_display;
x11_display->startup_notification = x11_sn;
#endif
}
void
meta_x11_startup_notification_release (MetaX11Display *x11_display)
{
#ifdef HAVE_STARTUP_NOTIFICATION
MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
x11_display->startup_notification = NULL;
if (x11_sn)
{
sn_monitor_context_unref (x11_sn->sn_context);
sn_display_unref (x11_sn->sn_display);
g_hash_table_unref (x11_sn->messages);
g_free (x11_sn);
}
#endif
}
static void
handle_message (MetaX11StartupNotification *x11_sn,
StartupMessage *message)
{
MetaStartupNotification *sn = x11_sn->x11_display->display->startup_notification;
MetaStartupSequence *seq;
GHashTable *data;
char *id;
int type;
if (message->data->len <= MAX_MESSAGE_LENGTH &&
g_utf8_validate (message->data->str, -1, NULL) &&
startup_message_parse (message, &type, &id, &data))
{
if (type == MESSAGE_TYPE_NEW)
{
uint64_t timestamp = 0;
int workspace = -1;
if (g_hash_table_contains (data, "DESKTOP"))
workspace = atoi (g_hash_table_lookup (data, "DESKTOP"));
if (g_hash_table_contains (data, "TIMESTAMP"))
timestamp = g_ascii_strtoull (g_hash_table_lookup (data, "TIMESTAMP"), NULL, 10);
seq = g_object_new (META_TYPE_STARTUP_SEQUENCE,
"id", id,
"icon-name", g_hash_table_lookup (data, "ICON_NAME"),
"application-id", g_hash_table_lookup (data, "APPLICATION_ID"),
"wmclass", g_hash_table_lookup (data, "WMCLASS"),
"name", g_hash_table_lookup (data, "NAME"),
"workspace", workspace,
"timestamp", timestamp,
NULL);
meta_topic (META_DEBUG_STARTUP,
"Received startup initiated for %s wmclass %s\n",
id, (gchar*) g_hash_table_lookup (data, "WMCLASS"));
meta_startup_notification_add_sequence (sn, seq);
g_object_unref (seq);
}
else if (type == MESSAGE_TYPE_REMOVE)
{
meta_topic (META_DEBUG_STARTUP,
"Received startup completed for %s\n", id);
seq = meta_startup_notification_lookup_sequence (sn, id);
if (seq)
{
meta_startup_sequence_complete (seq);
meta_startup_notification_remove_sequence (sn, seq);
}
}
g_hash_table_unref (data);
g_free (id);
}
g_hash_table_remove (x11_sn->messages, GINT_TO_POINTER (message->xwindow));
}
static gboolean
handle_startup_notification_event (MetaX11StartupNotification *x11_sn,
XClientMessageEvent *client_event)
{
StartupMessage *message;
if (client_event->message_type == x11_sn->atom_net_startup_info_begin)
{
message = startup_message_new (client_event->window);
g_hash_table_insert (x11_sn->messages,
GINT_TO_POINTER (client_event->window),
message);
if (startup_message_add_data (message, client_event->data.b))
handle_message (x11_sn, message);
return TRUE;
}
else if (client_event->message_type == x11_sn->atom_net_startup_info)
{
message = g_hash_table_lookup (x11_sn->messages,
GINT_TO_POINTER (client_event->window));
if (message)
{
if (startup_message_add_data (message, client_event->data.b))
handle_message (x11_sn, message);
return TRUE;
}
}
return FALSE;
}
gboolean
@@ -297,74 +332,8 @@ meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
if (!x11_sn)
return FALSE;
return sn_display_process_event (x11_sn->sn_display, xevent);
}
typedef void (* SetAppIdFunc) (SnLauncherContext *context,
const char *app_id);
gchar *
meta_x11_startup_notification_launch (MetaX11Display *x11_display,
GAppInfo *app_info,
uint32_t timestamp,
int workspace)
{
gchar *startup_id = NULL;
#ifdef HAVE_STARTUP_NOTIFICATION
MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
SnLauncherContext *sn_launcher;
int screen;
screen = meta_x11_display_get_screen_number (x11_display);
sn_launcher = sn_launcher_context_new (x11_sn->sn_display, screen);
sn_launcher_context_set_name (sn_launcher, g_app_info_get_name (app_info));
sn_launcher_context_set_workspace (sn_launcher, workspace);
sn_launcher_context_set_binary_name (sn_launcher,
g_app_info_get_executable (app_info));
if (G_IS_DESKTOP_APP_INFO (app_info))
{
const char *application_id;
SetAppIdFunc func = NULL;
GModule *self;
application_id =
g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (app_info));
self = g_module_open (NULL, G_MODULE_BIND_MASK);
/* This here is a terrible workaround to bypass a libsn bug that is not
* likely to get fixed at this point.
* sn_launcher_context_set_application_id is correctly defined in the
* sn-launcher.h file, but it's mistakenly called
* sn_launcher_set_application_id in the C file.
*
* We look up the symbol instead, but still prefer the correctly named
* function, if one were ever to be added.
*/
if (!g_module_symbol (self, "sn_launcher_context_set_application_id",
(gpointer *) &func))
{
g_module_symbol (self, "sn_launcher_set_application_id",
(gpointer *) &func);
}
if (func)
func (sn_launcher, application_id);
g_module_close (self);
}
sn_launcher_context_initiate (sn_launcher,
g_get_prgname (),
g_app_info_get_name (app_info),
timestamp);
startup_id = g_strdup (sn_launcher_context_get_startup_id (sn_launcher));
/* Fire and forget, we have a SnMonitor in addition */
sn_launcher_context_unref (sn_launcher);
#endif /* HAVE_STARTUP_NOTIFICATION */
return startup_id;
if (xevent->xany.type != ClientMessage)
return FALSE;
return handle_startup_notification_event (x11_sn, &xevent->xclient);
}

View File

@@ -36,9 +36,4 @@ void meta_x11_startup_notification_release (MetaX11Display *x11_display);
gboolean meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
XEvent *xevent);
gchar * meta_x11_startup_notification_launch (MetaX11Display *x11_display,
GAppInfo *app_info,
uint32_t timestamp,
int workspace);
#endif /* META_X11_STARTUP_NOTIFICATION_H */