Compare commits

..

130 Commits

Author SHA1 Message Date
Olivier Fourdan
ce808f6792 window: Really force update monitor on hot plugs
Commit 8d3e05305 ("window: Force update monitor on hot plugs") added the
flag `META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE` passed to
`update_monitor()` from `update_for_monitors_changed()`.

However, `update_for_monitors_changed()` may choose to call another code
path to `move_between_rects()` and `meta_window_move_resize_internal()`
eventually.

As `meta_window_move_resize_internal()` does not use the "force" flag,
we may still end up in case where the window->monitor is left unchanged.

To avoid that problem, add a new `MetaMoveResizeFlags` that
`update_for_monitors_changed()` can use to force the monitor update from
`meta_window_move_resize_internal()`.

Fixes: 8d3e05305 ("window: Force update monitor on hot plugs")
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/189


(cherry picked from commit fa495286a1)

(cherry picked from commit 8eabfaaa8b)
2018-11-13 09:39:53 +00:00
Jonas Ådahl
00cd99c3a7 renderer/native: Also wrap flip closures for EGLStreams
When using the EGLStream backend, the MetaRendererNative passed a
GClosure to KMS when using EGLStreams, but KMS flip callback event
handler in meta-gpu-kms.c expected a closure wrapped in a closure
container, meaning it'd instead crash when using EGLStreams. Make the
flip handler get what it expects also when using EGLStreams by wrapping
the flip closure in the container before handing it over to EGL.

https://bugzilla.gnome.org/show_bug.cgi?id=790316
(cherry picked from commit 8ee14a7cb7)
2018-10-23 18:33:53 +02:00
Jonas Ådahl
8ddbe9d98b wayland/gtk-shell: Handle requests after toplevel was unmanaged
As with xdg-toplevel, a gtk-surface can be unmanaged by the compositor
without the client knowing about it, meaning the client may still send
updates and make requests. Handle this gracefully by ignoring them. The
client needs to reset all the state anyway, if it wants to remap the
same surface.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit ca5b27baf5)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
a22cb8832d wayland/legacy-xdg-shell: Handle requests after toplevel was unmanaged
As with xdg-toplevel proper, a legacy xdg-toplevel can be unmanaged by
the compositor without the client knowing about it, meaning the client
may still send updates and make requests. Handle this gracefully by
ignoring them. The client needs to reassign the surface the legacy
xdg-toplevel role again, if it wants to remap the same surface, meaning
all state would be reset anyway.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 64df627688)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
082efaca96 wayland/legacy-xdg-shell: Cache frame callbacks if toplevel is unmanaged
A toplevel window can be unmanaged without the client knowing it (e.g. a
modal dialog being unmapped together with its parent. When this has
happened, take frame callbacks queued on a commit and cache them on the
generic surface queue. If the toplevel is to be remapped because the
surface was reassigned the toplevel role, the cached frame callbacks
will be queued on the surface actor and dispatched accordingly.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit a740f50cd7)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
80f942773a wayland/xdg-shell: Handle requests after toplevel was unmanaged
A window can be unmanaged without asking the client to do it, for
example as a side effect of a parent window being unmanaged, if the
child window was a attached dialog.

This means that the client might still make requests post updates to it
after that it was unmapped. Handle this gracefully by NULL-checking the
surface's MetaWindow pointer. We're not loosing any state due to this,
as if the client wants to map the same surface again, it needs to either
reassign it the toplevel role, or reset the xdg-toplevel, both resulting
in all state being lost anyway.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 5fd0f62a62)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
b5c2555601 wayland/xdg-shell: Cache frame callbacks if toplevel is unmanaged
A toplevel window can be unmanaged without the client knowing it (e.g. a
modal dialog being unmapped together with its parent. When this has
happened, take frame callbacks queued on a commit and cache them on the
generic surface queue. If the toplevel is to be remapped, either because
the surface was reassigned the toplevel role, or if it was reset and
remapped, the cached frame callbacks will be queued on the surface actor
and dispatched accordingly.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 80d420ff43)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
0a85e6272e wayland/xdg-shell: Cache pending frame callbacks on popup reset
A popup can be reset, and when that happens, window and actor are
destroyed, and won't be created again unless it is reassigned the
popup role.

If a client queued frame callbacks when resetting a popup, the frame
callbacks would be left in the pending state, as they were not queued on
the actor, meaning we'd hit an assert about the frame callbacks not
being handled. Fix this by caching them on the MetaWaylandSurface, so
that they either are cleaned up on destruction, or queued on the actor
would the surface be re-assigned the popup role.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 407d62943c)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
4dfe4256ae wayland/surface: Add API to cache frame callbacks
Sometimes it may be useful for roles to put callbacks in the generic
surface frame callback queue. The surface frame callback queue will
either eventually be processed on the next surface role assignment that
places the frame callbacks in a role specific queue, processed at some
other point in time by a role, or cleaned up on surface destruction.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 0ace58d05f)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
998e3279c2 wayland/xdg-shell: Queue frame callbacks on new actor after resetting
When a xdg-toplevel is reset, the window and actor are recreated, and
all state is cleared. When this happened, we earlied out from the
xdg-toplevel commit handler, which would mean that if the client had
queued frame callbacks when resetting, they'd be left in the pending
commit state, later hitting an assert as they were not handled.

Fix this by queuing the frame callbacks no the new actor, so that they
are emitted whenever the actor is eventually painted.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit d791710197)
2018-10-04 08:08:19 +00:00
Jonas Ådahl
1514880e92 window/wayland: Don't recursive indefinitely when updating monitor
When we update the main monitor, there is a rule that makes it so that
popup windows use the same main monitor as their parent. In the commit
f4d07caa38 the call that updates and
fetches the main monitor of the toplevel accidentally changed to update
from itself, causing a indefinite recursion eventually resulting in a
crash.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/279
(cherry picked from commit e191c21e04)
2018-10-03 15:48:51 +02:00
Olivier Fourdan
6ed36cd6e3 wayland: No xdg-output events without a logical monitor
To avoid a known race condition in the wl_output protocol documented in
https://phabricator.freedesktop.org/T7722, mutter delays the `wl_output`
destruction but nullify the `logical_monitor` associated with the
`wl_output` and the binding routine `bind_output()` makes sure not to
send wl_output events if the `logical_monitor` is `NULL` (see commit
1923db97).

The binding routine for `xdg_output` however does not check for such a
condition, hence if the output configuration changes while a client is
binding to xdg-output (typically Xwayland at startup), mutter would
crash while trying to access the `logical_monitor` which was nullified
by the change in configuration.

Just like `bind_output()` does for wl_output, do not send xdg-output
events if there is no `logical_monitor` yet.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/194

(cherry picked from commit 68ec9ac017)
2018-09-27 11:05:35 +02:00
Carlos Garnacho
49c06fd9b1 core: Preserve focus across decoration changes
Changes in window decoration result in the window being reparented
in and out its frame. This in turn causes unmap/map events, and
XI_FocusOut if the window happened to be focused.

In order to preserve the focused window across the decoration change,
add a flag so that the focus may be restored on MapNotify.

Closes: #273

(cherry picked from commit 8dcac664fa)
2018-09-24 16:15:11 +02:00
Olivier Fourdan
f7658ac5f0 compositor: Skip windows not visible to the compositor
The compositor will automatically unredirect the top most window which
is fully visible on screen. When unredirecting windows, it also shapes
the compositor overlay window (COW) so that other redirected windows
still shows correctly.

The function `get_top_visible_window_actor()` however will simply walks
down the window list, so if a window is placed on a layer above and
unredirected, then iconified by the client, it will still be picked up
by `get_top_visible_window_actor()` and he compositor will reckon it's
still unredirected while not in a visible state anymore, thus leaving a
black area on screen.

Make sure we skip the windows not known to the compositor while picking
the top visible window actor to avoid this issue.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/306

(cherry picked from commit 2fb3db7659)
2018-09-24 15:06:25 +02:00
Sam Spilsbury
037d9915d5 actor: Also recompute paint volume if we recently dropped effects
Otherwise we'll be stuck with the same paint volume on the last
frame of the given effect, which could be wrong.

(cherry picked from commit a8a3c1017f)
2018-09-19 14:20:46 +00:00
Sam Spilsbury
075bfc4e11 actor: Always use get_paint_volume override for active effects
If an effect is active and it overrides the paint volume, we should
always recompute the paint volume when requested and not use the
cache, since the paint volume override can change from call to
call depending on what phase of painting we are in. For instance,
if we are part way through painting effects and request the
paint volume, the paint volume should only go up to the current
effect, but in a later call to compute repaint regions, the
paint volume needs to expand to accomadate the effect.

This still involves a lot of recomputation in the case of effects -
in a later clutter version it would be worth adding an API to
allow effects to explicitly recompute and return a new the paint
volume up to the current effect as opposed to recomputing
the cached one.


(cherry picked from commit 5d19aee23a)
2018-09-19 14:20:46 +00:00
Sam Spilsbury
02e80af200 actor: Fix logic error in determining terminal effect for paint volume
Previously we were checking l->data != NULL || (l->data != NULL &&
l->data != priv->current_effect). This would continue the loop even
if l->data == priv->current_effect, since l->data != NULL, which was
not the intention of that loop.

We also don't need to check that l->data != NULL before checking if
it does not match the current_effect, since we already checked
that current_effect was non-NULL before entering the loop.


(cherry picked from commit 4270eef16e)
2018-09-19 14:20:19 +00:00
Olivier Fourdan
398f03bd0f window: unmanage dialog when clearing transient_for
On Wayland, xdg-foreign would leave a modal dialog managed even after
the imported surface is destroyed.

This is sub-optimal and this breaks the atomic relationship one would
expect between the parent and its modal dialog.

Make sure we unmanage the dialog if transient_for is unset even for
Wayland native windows.

Related: https://gitlab.gnome.org/GNOME/mutter/issues/174
Related: https://gitlab.gnome.org/GNOME/mutter/issues/221


(cherry picked from commit b443bd42ac)
2018-09-19 14:18:28 +00:00
Daniel van Vugt
d81dcd13e4 shaped-texture: Disable mipmapping during animation
This avoids overwhelming the GPU with trying to update mipmaps at a high
rate. Because doing so could easily cause a reduction in the compositor
frame rate and thus actually reduce visual quality.

In the case of a window that is constantly animating in the overview,
this reduces mutter's render time by around 20%-30%.

(cherry picked from commit c9c3283540)
2018-09-02 10:56:00 -05:00
Daniel van Vugt
5d0365991f clutter/actor: Inherit clone branch depth from parent
Children added to a parent after that parent (or its ancestors)
have already been cloned now inherit the clone branch depth of
the parent. Otherwise `clutter_actor_is_in_clone_paint` on the child
could return FALSE when it should have been returning TRUE.

(cherry picked from commit b393f3d540)
2018-09-02 10:56:00 -05:00
Carlos Garnacho
03dfcbab67 compositor: Do not optimize obscured areas away in paint volumes
This optimization was presumably added before Clutter was able to
invalidate selected regions of an actor. Paint volumes are supposed
to be invariable as long as the actor conditions don't change.
Stacking of other actors shouldn't affect the paint volume, so it's
actually wrong to optimize those areas away here.

(cherry picked from commit ec8138773a)
2018-09-02 10:56:00 -05:00
Carlos Garnacho
47505dc5f6 clutter: Plug minor leak
clutter_stage_manager_list_stages() returns a copied list, which
should be freed.


(cherry picked from commit 8cf42cd06c)
2018-08-31 15:55:45 +00:00
Florian Müllner
9d88fc8cb7 idle-monitor: Don't try to auto-start SessionManager
The interface is provided by gnome-session and not activatable.

https://gitlab.gnome.org/GNOME/mutter/issues/134


(cherry picked from commit 2319cd9c40)
2018-08-31 15:42:23 +00:00
Carlos Garnacho
17ae09ad3f core: Hide close dialog before destroying
The MetaCloseDialog implementation object may stay artifically alive
for a longer period. This was usually fine till gnome-shell commit
b03bcc85aad, as the check_alive() timeout will keep running even
though the window went unmanaged/destroyed, leading to crashes.

In order to fix this, forcibly hide the dialog if it is visible and
the window is being unmanaged, so the timeout is stopped in time.


(cherry picked from commit 6abe4703c7)
2018-08-31 15:35:25 +00:00
Daniel van Vugt
4ca83f3c47 clutter-actor: Fix uninitialized matrix multiply
`modelview` is uninitialized and the `apply` function just multiplies it.
What we really want is to initialize `modelview` so replace `apply` with
`get`.

Who knows what bugs this may have caused...


(cherry picked from commit 62c67be4c8)
2018-08-31 15:33:55 +00:00
Jonas Ådahl
b44f93ee9b idle-monitor: NULL check cached InhibitedActions property variant
We might not have a cached "InhibitedActions" property available for us,
so do as elsewhere in this file and NULL check before processing it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/130


(cherry picked from commit a3269dde95)
2018-08-31 15:32:37 +00:00
Miguel A. Vico
59d2d5ef3b wayland: Always realize buffers at surface commit time
Clients using EGLStream-backed buffers will expect the stream to be
functional after wl_surface::attach(). That means the compositor-side
stream must be created and a consumer attached to it.

To resolve the above, this change realizes buffers even when the attach
operation is deferred (e.g. synchronized subsurfaces).

https://bugzilla.gnome.org/show_bug.cgi?id=782575

(cherry picked from commit 22723ca371)
2018-08-31 17:31:23 +02:00
Miguel A. Vico
53b040be5c wayland-buffer: Create EGLStream texture at buffer_realize time
When dealing with synchronized subsurfaces, we defer buffer attachments
until the parent surface state is applied.

That causes interaction issues with EGLStream backed buffers, as the
client expects the compositor-side stream to be functional after it
requests a wl_surface::attach.

By allowing the compositor to realize buffers without attaching them, we
could resolve the issue above if we define a realized EGLStream buffer
as a functional EGLStream (EGLStream + attached consumer).

This change moves the texture consumer creation part from the attach
function to the realize one.

https://bugzilla.gnome.org/show_bug.cgi?id=782575


(cherry picked from commit edd3634bb5)
2018-08-31 15:19:27 +00:00
Miguel A. Vico
c647bd7807 renderer/native: Choose first EGL config for non-GBM backends
Commit 712ec30cd9 added the logic to only
choose EGL configs that match the GBM_FORMAT_XRGB8888 pixel format.
However, there won't be any EGL config satisfying such criteria for
non-GBM backends, such as EGLDevice.

This change will let us choose the first EGL config for the EGLDevice
backend, while still forcing GBM_FORMAT_XRGB8888 configs for the GBM
one.

Related to: https://gitlab.gnome.org/GNOME/mutter/issues/2


(cherry picked from commit 1bf2eb95b5)
2018-08-31 15:18:52 +00:00
Miguel A. Vico
9ac07b4005 wayland: Realize dmabuf buffers before trying to attach them
Commit 22723ca37 moved buffer realization to
meta_wayland_surface_commit() so that it wouldn't be part of
meta_wayland_buffer_attach().

However, creation of dmabuf buffers would call into
meta_wayland_buffer_attach() directly without realizing the buffer
first. attach() would then fail and mutter would effectively shut down
any clients using the zwp_linux_dmabuf protocol (note that if such
client was Xwayland, mutter itself would shut down as well).

Add the missing bit in order to make zwp_linux_dmabuf protocol work
again.


(cherry picked from commit 54709c16b5)
2018-08-31 15:08:06 +00:00
Carlos Garnacho
527f6ef835 ClutterActor: Preserve valid paint volumes till the next relayout/repaint
Cuts down approximately all paint volume calculations when there's
windows that redraw frequently, but don't move.

https://bugzilla.gnome.org/show_bug.cgi?id=782344


(cherry picked from commit 161d2540e6)
2018-08-31 15:03:28 +00:00
Carlos Garnacho
0b666dbeb2 compositor: Add get_paint_volume() implementation to MetaSurfaceActor
The special ::pick implementation there makes clutter fall into paths
that do require a get_paint_volume() implementation, or an infinite
area will be used.

Providing a paint volume here is easier on the invalidation mechanism.


(cherry picked from commit 94f4009882)
2018-08-31 15:02:41 +00:00
Bastien Nocera
24b87b364d monitor-manager: Cache the last known value of "lid-is-closed"
Restarting UPower will make every property of UpClient emit a "notify"
signal (as a GDBusProxy would). Avoid mutter reconfiguring the displays
when upower restarts by caching the last known value of "lid-is-closed"
and only reconfiguring the displays if it actually changed.

This fixes a black out of the screen when UPower restarts.


(cherry picked from commit 49b23c7490)
2018-08-31 14:58:57 +00:00
Bastien Nocera
15f01174ff monitor-manager: Don't throw an error if UPower isn't running
Don't try to connect to a UpClient signal if creating the client failed,
because UPower isn't running for example.


(cherry picked from commit 644a618fb1)
2018-08-31 14:58:05 +00:00
Olivier Fourdan
f45af3315d wayland: Nullify monitor resources when updating outputs
If a client asks for xdg-output before we have set the output's logical
monitor, we would end up crashing with a NULL pointer dereference.

Make sure we clear the resource's user data when marking an output as
inert on monitor change so that we don't end up with a Wayland output
without a logical monitor.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/194


(cherry picked from commit 48eaa36d41)
2018-08-31 14:54:04 +00:00
Sam Spilsbury
007864ac64 window: Return -1 if meta_window_get_monitor is called on an unmanaged window
As opposed to crashing. In this case, letting the caller deal with
it is the best policy, since this is public API.

https://bugzilla.gnome.org/show_bug.cgi?id=788834


(cherry picked from commit 8626c69c2f)
2018-08-31 14:36:36 +00:00
Sebastian Keller
f76cacd154 backends/x11: Only free cursor if it was created successfully
XcursorLibraryLoadCursor can return 'None' if the current cursor theme
is missing the requested icon. If XFreeCursor is then called on this
cursor, it generates a BadCursor error causing gnome-shell to crash.

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

(cherry picked from commit 1bfa20929b)
2018-08-29 20:40:39 -05:00
Jonas Ådahl
abe682efa0 virtual-input/evdev: Translate from button internal codes to evdev
Sending button events to a ClutterVirtualInputDevice, the API expects
button codes to be of the internal clutter type. The evdev
implementation incorrectly assumed it was already prepared evdev event
codes, which was not the case. Fix the evdev implementation to translate
from the internal representation to evdev before passing it along to
ClutterSeatEvdev.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/190

(cherry picked from commit 24aef44baf)
2018-08-29 20:40:39 -05:00
Jonas Ådahl
83b7b17b64 window: Force update monitor on hot plugs
Commit a3da4b8d5b changed updating of
window monitors to always use take affect when it was done from a
non-user operation. This could cause feed back loops when a non-user
driven operation would trigger the changing of a monitor, which itself
would trigger changing of the monitor again due to a window scale
change.

The reason for the change, was that when the window monitor changed due
to a hot plug, if it didn't actually change, eventually the window
monitor pointer would be pointing to freed memory.

Instead of force updating the monitor on all non-user operations, just
do it on hot plugs. This allows for the feedback loop preventing logic
to still do what its supposed to do, without risking dangling pointers
on hot plugs.

Related: https://gitlab.gnome.org/GNOME/mutter/issues/189
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/192

(cherry picked from commit 8d3e053059)
2018-08-29 20:40:39 -05:00
Jonas Ådahl
30266605b5 window: Pass flag to meta_window_update_monitor() instead of bool
The bool determines whether the call was directly from a user operation
or not. To add more state into the call without having to add more
boolenas, change the boolean to a flag (so far with 'none' and 'user-op'
as possible values). No functional changes were made.

https://gitlab.gnome.org/GNOME/mutter/issues/192

(cherry picked from commit f4d07caa38)
2018-08-29 20:40:39 -05:00
Carlos Garnacho
2e0d758811 clutter/x11: Implement keycode lookup from keysyms on virtual key devices
Unfortunately XKeysymToKeycode() falls short in that it coalesces keysyms
into keycodes pertaining to the first level (i.e. lowercase). Add a
ClutterKeymapX11 method (much alike its GdkKeymap counterpart) to look up
all matches for the given keysym.

Two other helper methods have been added so the virtual device can fetch
the current keyboard group, and latch modifiers for key emission. Combining
all this, the virtual device is now able to handle keycodes in further
levels.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/135

(cherry picked from commit 85284acb00)
2018-08-29 20:40:39 -05:00
Iain Lane
aa6d1614c0 monitor-manager-kms: Check if GPUs can have outputs
We need a way for mutter to exit if no available GPUs are going to work.
For example if gdm starts gnome-shell and we're using a DRM driver that
doesn't work with KMS then we should exit so that GDM can try with Xorg,
rather than operating in headless mode.

Related: https://gitlab.gnome.org/GNOME/mutter/issues/223


(cherry picked from commit deb541ef5a)
2018-08-30 01:16:40 +00:00
Iain Lane
255146e4a3 gpu-kms: Handle drmModeGetResources() failing
Avoid dereferencing the NULL return value if it fails. We still create
the MetaGpu, but we treat it as if it has no outputs.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/223


(cherry picked from commit 29cc526e2e)
2018-08-30 01:16:09 +00:00
Daniel van Vugt
2ad5a39bd0 clutter-text: Avoid clipping the wrong framebuffer
`ClutterText` painting for editable single_line_mode actors like `StEntry`
is always clipped by:

`cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height)`

So it's difficult to get the rectangle wrong. However in cases where the
target framebuffer has changed (`cogl_push_framebuffer`) such as when
updating `ClutterOffscreenEffect` we had the wrong old value of `fb`. And
so would be clipping the wrong framebuffer, effectively not clipping at all.


(cherry picked from commit b8340f1355)
2018-08-30 01:11:33 +00:00
Jonas Ådahl
ce3278b4b7 renderer/native: Check calculated transform when creating view
The "backends: Move MetaOutput::crtc field into private struct"
accidentally changed the view transform calculation code to assume that
"MetaCrtc::transform" corresponds to the transform of the CRTC; so is
not the case yet; one must calculate the transform from the logical
monitor, and check whether it is supported by the CRTC using
meta_monitor_manager_is_transform_handled(). This commit restores the
old behaviour that doesn't use MetaCrtc::transform when calculating the
view transform.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/216
2018-08-21 13:58:48 +00:00
Jonas Ådahl
0d134522d8 wayland/keyboard: Create a separate keymap shm file per resource
By using the shm file when sending the keymap to all clients, we
effectively allows any client to change the keymap, as any client has
the ability to change the content of the file. Sending a read-only file
descriptor, or making the file itself read-only before unlinking, can
be worked around by the client by using chmod(2) and open(2) on
/proc/<pid>/<fd>.

Using memfd could potentially solve this issue, but as the usage of
mmap with MAP_SHARED is wide spread among clients, such a change can
not be introduced without causing wide spread compatibility issues.

So, to avoid allowing clients to interfere with each other, create a
separate shm file for each wl_keyboard resource when sending the
keymap. We could eventually do this per client, but in most cases,
there will only be one wl_keyboard resource per client anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=784206
2018-08-17 16:21:07 +02:00
Jonas Ådahl
f4a7620dff wayland/keyboard: Indentation fix 2018-08-17 16:21:06 +02:00
Jeff Smith
a41ae88c09 backends/x11: Improve grab-device clock updates
meta_backend_x11_grab_device is performing X server clock comparison
using the MAX macro, which comes down to a simple greater-than.

Use XSERVER_TIME_IS_BEFORE, which is a better macro for X server
clock comparisons, as it accounts for 32-bit wrap-around.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/174

(cherry picked from commit 1bfa20929b)
2018-08-14 18:34:30 +02:00
Alex Villacís Lasso
1276cc97d1 renderer/native: Fallback to non-planar API if gbm_bo_get_handle_for_plane fails
Commit c0d9b08ef9 replaced the old GBM API calls
with the multi-plane GBM API. However, the call to gbm_bo_get_handle_for_plane
fails for some DRI drivers (in particular i915). Due to missing error checks,
the subsequent call to drmModeAddFB[2] fails and the screen output locks up.

This commit adds the missing error checks and falls back to the old GBM API
(non-planar) if necessary.

v5: test success of gbm_bo_get_handle_for_plane instead of errno

This commit adopts solution proposed by Daniel van Vugt to check the return
value of gbm_bo_get_handle_for_plane on plane 0 and fall back to old
non-planar method if the call fails. This removes the errno check (for
ENOSYS) that could abort if mesa ever sets a different value.

Related to: https://gitlab.gnome.org/GNOME/mutter/issues/127


(cherry picked from commit f7af32a3ea)
2018-08-13 11:13:42 +00:00
Olivier Fourdan
5b9f5329bd wayland: Clean up xwayland grabs even if surface is gone
If the surface is gone before `meta_xwayland_keyboard_grab_end()` is
called, we would bail out early leaving an empty grab, which will cause
a segfault as soon as a key is pressed later on.

Make sure we clean up the keyboard grab even if the surface is gone.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/255
(cherry picked from commit 252dd52439)
2018-08-06 15:02:05 +02:00
Jonas Ådahl
d0d8078013 monitor: Use current monitor mode to check whether active
For historical reasons meta_monitor_is_active() checked whether it is
active by checking whether the main output have a CRTC assigned and
whether that CRTC has a current mode. At a later point, the MetaMonitor
got its own mode abstraction (MetaMonitorMode), but
meta_monitor_is_active() was never updated to use this.

An issue with checking the main output's CRTC state is that, if there is
some CRTC mode combination that for some reason isn't properly detected
by the MetaMonitorMode abstraction (e.g. some tiling configuration not
yet handled), meta_monitor_is_active() would return TRUE, even though no
(abstracted) mode was set. This would cause confusion here and there,
leading to NULL pointer dereferences due to the assumption that if a
monitor is active, it has an active mode.

Instead, change meta_monitor_is_active() to directly check the current
monitor mode, and log a warning if the main output still happen to have
a CRTC with a mode assigned to it. This way, when an not undrestood CRTC
mode combination is encountered, instead of dereferencing NULL pointers,
simply assume the monitor is not active, which means that it will not be
managed or rendered by mutter at all.

https://gitlab.gnome.org/GNOME/mutter/issues/130


(cherry picked from commit 4d465eac08)
2018-07-31 11:46:02 +00:00
Florian Müllner
0a09a3c906 tests: Add "closed-transient" test
When a transient window is destroyed, the expected behavior is that
focus is passed to the ancestor if possible. This was broken for
quite a while until the previous commit, so add a test case to make
sure it doesn't happen again.

https://gitlab.gnome.org/GNOME/mutter/issues/15

(cherry-picked from commit 137f22236c)
2018-07-30 20:29:03 +02:00
Florian Müllner
137f22236c window: Explicitly exclude unmanaging window from focus again
Since commit b3b9d9e16 we no longer have to pass the unmanaging window
to make sure we don't try to focus it again, however the parameter also
influences the focus policy by giving ancestors preference over the normal
stack order.

https://gitlab.gnome.org/GNOME/mutter/issues/15

(cherry picked from commit d99442d6e6)
2018-07-30 20:25:15 +02:00
Florian Müllner
513cc535f3 window: Don't refuse to move focus to the grab window
We refuse to move focus while a grab operation is in place. While this
generally makes sense, there's no reason why the window that owns the
grab shouldn't be given the regular input focus as well - we pretty
much assume that the grab window is also the focus window anyway.

In fact there's a strong reason for allowing the focus change here:
If the grab window isn't the focus window, it probably has a modal
transient that is focused instead, and a likely reason for the focus
request is that the transient is being unmanaged and we must move
the focus elsewhere.

https://gitlab.gnome.org/GNOME/mutter/issues/15


(cherry picked from commit 148da24f95)
2018-07-30 18:18:42 +00:00
Olivier Fourdan
d74a046060 window/wayland: Always update monitor for non-user ops
meta_window_wayland_update_main_monitor() would skip the monitor update
if the difference in scale between the old and the new monitor would
cause another monitor change.

While this is suitable when the monitor change results from a user
interactively moving the surface between monitors of different scales,
this can leave dangling pointers to freed monitors when this is
triggered by a change of monitor configuration.

Make sure we update the monitor unconditionally if not from a user
operation.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/189


(cherry picked from commit a3da4b8d5b)
2018-07-30 14:52:49 +00:00
Andrea Azzarone
0c5e61a2ab monitor-manager: Filter out low screen resolutions
Avoid exporting through org.gnome.Mutter.DisplayConfig.GetCurrentState
excessively-low screen resolutions setting both a minimum width and a minimum
height. GetCurrentState is e.g. used by Gnome Control Center to build a list of
selectable resolutions.

Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=793223


(cherry picked from commit 649c26e05a)
2018-07-30 14:15:01 +00:00
Jonas Ådahl
44682a2cc5 native/gpu: Handle drmModeSetCrtc() failing gracefully
If drmModeSetCrtc() is called with no fb, mode or connectors for some
CRTC it may still fail, and we should handle that gracefully instead of
assuming it failed to set a non-disabled state.

Closes https://gitlab.gnome.org/GNOME/mutter/issues/70


(cherry picked from commit 6e953e2725)
2018-07-26 17:06:59 +00:00
Aaron Plattner
62660bbd15 gpu-kms: Don't crash if drmModeGetResources returns NULL
DRM drivers can be opened by meta_launcher_open_restricted() even if they don't
implement modesetting. However, drmModeGetResources() will return NULL.

Check whether that happened in meta_gpu_kms_new() and return with an error
instead of crashing.

Fixes #223.
2018-07-19 12:29:03 -07:00
Florian Müllner
34f5bdeea3 Bump version to 3.28.3
Update NEWS.
2018-07-18 23:12:51 +02:00
Jonas Ådahl
ca71b0eb1a monitor-manager: Add back warning messages
For some reason "backends: Remove X11 idle-monitor backend" removed
unrelated warning messages for when generated monitor configurations
that should work didn't, which also made the unit tests fail.

This commit adds them back, which also makes the tests pass again.


(cherry picked from commit d9c18fd5bb)
2018-07-18 20:21:12 +00:00
Jonas Ådahl
ca4209d88a screen-cast-src: Allow negotiating the framerate
The framerate for screen cast sources was set to variable within 1 FPS
and the framerate of the monitor being screen casted. This meant that if
the sink didn't match the framerate (e.g. had a lower max framerate),
the formats would not match and a stream would not be established.

Allow letting the sink clamp the framerate range by setting it as
'unset', allowing it to be negotiated.
2018-07-13 14:39:43 +02:00
Olivier Fourdan
3288edf677 contraints: Do not constrain modals without parent
xdg-foreign clears the `transient_for` of a modal dialog when its
imported parent is destroyed, which would later cause a crash in
`constrain_modal_dialog()` because the transient `NULL`.

So in case a modal dialog has no parent, do not try to constrain it
against its parent.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/174
(cherry picked from commit 912a6f5e3f)
2018-07-10 17:03:20 +02:00
Jonas Ådahl
fe1616668e backends: Add logical monitor -> monitor -> output -> crtc ref chain
Make it so that each logical monitor has a reference to all the
monitors that are assigned to it.

All monitors has a reference to each output that belongs to it.

Each output has a reference to any CRTC it has been assigned.

https://bugzilla.gnome.org/show_bug.cgi?id=786929


(cherry picked from commit 768ec15ea0)
2018-06-28 11:52:10 +00:00
Jonas Ådahl
7d01aec48d backends: Move MetaOutput::crtc field into private struct
No functional changes. This is only done so that changes to reference
counting can done more reliably.

https://bugzilla.gnome.org/show_bug.cgi?id=786929


(cherry picked from commit 1200182d70)
2018-06-28 11:50:37 +00:00
Marco Trevisan (Treviño)
a41d84db00 renderer-native: Don't crash if the FB surface can't be locked
(cherry picked from commit 0332b7394e)
2018-05-29 22:14:31 +00:00
Marco Trevisan (Treviño)
e73b321c2e device-manager-evdev: Add main seat to seats by default
Treat the main seat as other seats, so we don't have to handle it differently
in specific places. This was already the case before when a real device
was plugged before the startup, but not applied when hotplugging a device.


(cherry picked from commit 15f41c9f68)
2018-05-29 10:48:56 +00:00
Marco Trevisan (Treviño)
b6dc2052c3 device-manager-evdev: Free the main seat on finalize
(cherry picked from commit 2a38601b42)
2018-05-29 10:47:20 +00:00
Marco Trevisan (Treviño)
72965aaaf0 device-manager-evdev: Set and unset the stage for the main seat too
When no input devices are available on startup the device manager might be fast
enough to be constructed so that no default stage is set yet, and thus when
main seat virtual devices are created they won't have a proper stage set.
If then we plug a real device, the events that an input manager could generate
won't be associated to any stage and thus won't be processed.

We need then ensure that when we update the stage for the device manager we
(un)associate it also to the main seat devices.


(cherry picked from commit d7bdc1591f)
2018-05-29 10:46:03 +00:00
Marco Trevisan (Treviño)
2a6782dc10 clutter-device-evdev: Get devices from main seat if no real seat is set
In devices such as ARM boards there could be no input devices connected on
startup, leading to a crash when we try to process artificial events that
could be queued (as gnome-shell does when syncing pointer).

Those events still should refer to a device and, in case we don't have one
provided by libinput we should still return the core devices defined in the
main seat.


(cherry picked from commit 3e85ac8131)
2018-05-29 10:43:41 +00:00
Marco Trevisan (Treviño)
5142c8c7e7 clutter-seat-evdev: Add function to get device by id
(cherry picked from commit 5f83d9a5c8)
2018-05-29 10:43:17 +00:00
Changwoo Ryu
abc7ad8e9f wayland: Don't reset input focus on text commit
Preedit text can be active even after text commit. Resetting the input
focus will lead to unintended commit of the preedit text.

https://gitlab.gnome.org/GNOME/mutter/issues/152

Closes: #152
2018-05-26 15:26:09 +02:00
Olivier Fourdan
1a3f9a3323 frames: Allow for unknown mouse buttons
Commit 47131b1d ("frames: Handle touch events") introduced an assert to
make sure that all mouse button actions are handled in mutter.

However, mice can have a more than 5 buttons, so simply ignore the
"other" actions instead of aborting.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/160
(cherry picked from commit 473bf38753)
2018-05-25 11:35:45 +02:00
Olivier Fourdan
235c35182b wayland: update enter/leave output after effects
Compositor effects change the actor size and position, which can lead to
inconsistent output enter/leave notifications, leaving clients' surfaces
without any output set.

Update output enter/leave notifications after all compositor effects are
completed so that we give clients accurate output location.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/104
(cherry picked from commit 17a745bf81)
2018-05-22 13:01:13 +02:00
Olivier Fourdan
e4661d7870 window-actor: add new signal "effects-completed"
When using plugins, the effects will affect the MetaWindowActor size
and position.

Add a new signal "effects-completed" wired to the corresponding
MetaWindowActor which is emitted when all effects are completed so that
derived objects can be notified when all effects are completed and use
the actual size and position.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/104
(cherry picked from commit 85bbd82ae8)
2018-05-22 13:01:05 +02:00
Georges Basile Stavracas Neto
9d4c7e4e75 wayland: Compare geometries after chaining up
After 20176d03, the Wayland backend only synchronizes with the
compositor after a geometry was set, and it was different from
the current geometry.

That commit was mistakenly comparing the geometry before chaining
up, which would yield a false negative on the case where the
client didn't call set_geometry() before commit().

Fix that by caching the old geometry locally, chain up (and thus
apply the new geometry rectangle), then comparing the old and
current geometry rectangles.

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


(cherry picked from commit cf734999fb)
2018-05-18 13:53:20 +00:00
Carlos Garnacho
47131b1dad frames: Handle touch events
This is just done on wayland as it'll break horribly on X11, we let
this happen through pointer emulated events in XISelectEvents evmask
instead.

Some things had to be made slightly more generic to accomodate touch
events. The MetaFrames shall lock onto a single touch at a time, we
don't allow crazy stuff like multi-window drag nor multi-edge resizes.

https://bugzilla.gnome.org/show_bug.cgi?id=770185
2018-05-15 16:07:07 +01:00
Carlos Garnacho
51c0130645 frames: Make 1st button/motion handlers take generic events
This will ease handling of touch events through these same handlers.

https://bugzilla.gnome.org/show_bug.cgi?id=770185
2018-05-15 16:06:59 +01:00
Olivier Fourdan
2dd9fc17c1 clutter/evdev: Don't ignore CAPS lock as modifier
Mark CAPS lock as a modifier (as it should) so that when using XKB
options to change the default behaviour of CAPS lock, the new assigned
key can by used as a sticky key as well.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/112
(cherry picked from commit 6df2b7af55)
2018-05-15 10:26:29 +02:00
Olivier Fourdan
c7a38c3139 clutter/evdev: ignore injected events from IM
Input method can inject key events, which leads to multiple reported key
press/release events for a single user action.

Ignore those events as this confuses keyboard accessibility.

(cherry picked from commit c01b099dbd)
2018-05-15 10:25:51 +02:00
Olivier Fourdan
7d52be0229 wayland: Use cursor position in logical monitor
When using two monitors size by side with different scales, once the
cursor moves from one output to another one, its size changes based on
the scale of the given output.

Changing the size of the cursor can cause the cursor area to change
output again if the hotspot is not exactly at the top left corner of the
area, causing the texture of the cursor to change, which will trigger
another output change, so on and so forth causing continuous surface
enter/leave event which flood the clients and eventually kill them.

Change the logic to use only the actual cursor position to determine if
its on the given logical monitor, so that it remains immune to scale
changes induced by output scale differences.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/83
(cherry picked from commit 67917db45f)
2018-05-14 16:08:16 +02:00
Florian Müllner
41303bc01b Bump version to 3.28.2
Update NEWS.
2018-05-07 22:29:42 +02:00
Florian Müllner
0d188c3898 build: Adjust to filename changes
The meta-stage and meta-window-group headers got split into a public
and private part, but the Makefiles still reference the old files.
2018-05-07 22:29:42 +02:00
Florian Müllner
28eff93143 build: Introspect some more types
While MetaStage, MetaWindowGroup and MetaDBusDisplayConfigSkeleton don't
appear explicitly in the public API, their gtypes are still exposed via
meta_get_stage_for_screen(), meta_get_*window_group_for_screen() and
MetaMonitorManager's parent type. Newer versions of gjs will warn about
undefined properties if it encounters a gtype without introspection
information, so expose those types to shut up the warnings.

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 22:06:02 +02:00
Florian Müllner
b380aa72aa window-group: Remove undefined function declaration
Ever since the function has been made public, its name has been
meta_actor_is_untransformed() ...

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 22:06:02 +02:00
Florian Müllner
920dc9e5a1 clutter: Don't reference invalid pc in gir
Cally is built into clutter itself rather than exposed as a separate
library.

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 22:06:02 +02:00
Jonas Ådahl
32f02010ae screen-cast: Handle PipeWire errors more gracefully
Various code assumed PipeWire function calls would never fail. Some can
actually fail for real reasons, and some currently can only fail due to
OOM situations, but we should still not assume that will always be the
case.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/102


(cherry picked from commit 0f9c6aef99)
2018-05-07 19:28:27 +00:00
Jonas Ådahl
889c56c776 wayland/xdg-foreign: Fix child surface validation check
The role type should be either an xdg-shell toplevel, or a
xdg-shell unstable v6 toplevel.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/138


(cherry picked from commit 332d55f7f6)
2018-05-07 19:20:56 +00:00
Jonas Ådahl
67a4cd898e wayland/xdg-foreign: Send immediate destroy event to correct resource
The destroyed signal that was emitted if an imported surface was not
available when created, for example if the handle was invalid or
already unexported, was emitted on the wrong resource.


(cherry picked from commit 98d7024288)
2018-05-07 19:20:09 +00:00
Florian Müllner
43d6c0ea61 build: Don't fail immediately when logind is missing
We require logind for the native backend, but the backend itself is
optional. However since commit 06c357d78, we will always throw an
error if neither logind nor elogind are available, even when the
backend is disabled.

As we still support "auto" - that is, whether the native backend is
enabled depends on whether its dependencies are available - the
easiest option is to make sure we always include either elogind or
libsystemd in the dependency check rather than erring out explicitly
if neither is found.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/96


(cherry picked from commit 82564772dc)
2018-05-07 19:14:11 +00:00
Georges Basile Stavracas Neto
2872bb1f2a wayland: Check if state and size changed before calling move_resize()
The current implementation of the XdgSurface v6 protocol does not check
if the window changed before calling meta_window_wayland_move_resize().

The problem with this approach is that calling this function is a costly
operation since we enter the compositor side. In GNOME Shell case, it is
in JavaScript, which triggers a GJS trampoline. Calling this function on
every mouse movement is naturally as terrible as it could be - and is
exactly what happens now.

This commit adds the necessary checks to only call move_resize() when
the window actually changed, or when it needs to be updated.

https://bugzilla.gnome.org/show_bug.cgi?id=780292
Issue: #78
2018-05-04 15:57:57 -03:00
Georges Basile Stavracas Neto
1c00cd5ca3 wayland: Add function to query if window needs move or resize
This will be used by the next commit to determine when a window
geometry change should be ignored or not. Normally, it would be
enough to just check if the position and sizes changed.

The position, in this case, is relative to the client buffer, not
the global position. But because it is not global, there is one,
admitedly unlikely, situation where the window state is updated
while the client size and relative positions don't change.

One can trigger this by e.g. tiling the window to the half-left of
the monitor, then immediately tile it to half-right. In this case,
the window didn't change, just it's state, but nonetheless we need
to notify the compositor and run the full move/resize routines.

When that case happens, though, the MetaWindowWayland is tracking
the pending state change or a move. And this is what we need to
expose.

https://bugzilla.gnome.org/show_bug.cgi?id=780292
Issue: #78
2018-05-04 15:57:50 -03:00
Georges Basile Stavracas Neto
2919a7f25f window: Let implementations finish state changes
In the old, synchronous X.org world, we could assume that
a state change always meant a synchronizing the window
geometry right after. After firing an operation that
would change the window state, such as maximizing or
tiling the window,

With Wayland, however, this is not valid anymore, since
Wayland is asynchronous. In this scenario, we call
meta_window_move_resize_internal() twice: when the user
executes an state-changing operation, and when the server
ACKs this operation. This breaks the previous assumptions,
and as a consequence, it breaks the GNOME Shell animations
in Wayland.

The solution is giving the MetaWindow control over the time
when the window geometry is synchronized with the compositor.
That is done by introducing a new result flag. Wayland asks
for a compositor sync after receiving an ACK from the server,
while X11 asks for it right away.

Fixes #78
2018-05-04 15:57:43 -03:00
Olivier Fourdan
ca0d56a3a4 wayland: avoid a crash in is_effectively_synchronized()
To check if a subsurface is effectively synchronized, we walk the
subsurface hierarchy to look for a non-subsurface parent or a subsurface
being synchronized.

However, when client is closing, the parent surface might already be
gone, in which case we end up with a surface being NULL which causes a
NULL pointer dereference and a crash.

Check if the parent surface is NULL to avoid the crash, and consider
it's already synchronized if it is NULL to avoid further updates.

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


(cherry picked from commit 52fdd24467)
2018-05-03 17:49:26 +00:00
Jonas Ådahl
a89baa44ab native: Restore previous EGL state after blitting onto secondary GPU
Before we just set it to "none", but this was not enough since various
calls will depend on not just the context being active, but the main
rendering surface.

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


(cherry picked from commit ae26cd0774)
2018-04-25 15:24:14 +00:00
Marco Trevisan (Treviño)
7076a48bcf cogl: Do not unref a NULL object
Add return-if-fail statement to avoid deferencing NULL object


(cherry picked from commit 3104d697c0)
2018-04-25 09:09:04 +00:00
Jonas Ådahl
1b439c42d1 monitor-manager: Find active monitor when deriving global scale
When deriving the global scale directly from the current hardware state
(as done when using the X11 backend) we are inspecting the logical
state they had prior to the most recent hot plug. That means that a
primary monitor might have been disabled, and a new primary monitor may
not have been assigned yet.

Stop assuming a primary monitor has an active mode before having
reconstructed the logical state by finding some active monitor if the
old primary monitor was disabled. This avoids a crash when trying to
derive the global scale from a disabled monitor.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/130


(cherry picked from commit 0b3a1c9c31)
2018-04-25 08:58:15 +00:00
Carlos Garnacho
928a40f328 wayland: Let IM events go through
These paths implicitly relied on the forwarded IM key events having
a source_device backed by a real HW device. This assumption is no
longer held true since commit b5328c977.

Explicitly check the INPUT_METHOD flag so they are handled as they
should despite not being "real HW" events.
2018-04-24 23:59:21 +02:00
Mario Sanchez Prada
59397266ed backend: Don't center the pointers on monitor changes
As a follow up to the patch from a95cbd0a, we need to make sure
that the pointer is out of the way as well when monitors changed,
since that's the event that will prevail in some cases. Besides,
this is also consistent with what the code before a95cbd0a was,
which initialized the pointer position in the same way both in
this case and in the real_post_init() function.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/157
2018-04-24 23:14:38 +02:00
Mario Sanchez Prada
d0147591b3 backends: Don't center the pointer on initialization
Centering the pointer at startup causes undesired behaviour if
it ends up hovering over reactive elements, that might react
to that positioning, causing confusion. This is the case of
the login dialog when a list of different users is shown, as
centering the pointer at startup in that case will get the
user in the center of the screen pre-selected, which is not
the expected behaviour (i.e. pre-selecting the first one).

Fix this by simply moving the pointer out of the way, close
to the bottom-right corner, during initialization.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/157
2018-04-24 23:14:37 +02:00
Ray Strode
25c7e52ada xwayland: Don't abort if Xwayland crashes
Right now if Xwayland crashes, we crash, too.

On some level that makes sense, since we're supposed to control the
lifecycle of Xwayland, and by it crashing we've lost that control.

But practically speaking, the knock-on crash adds noise to the logs,
bug trackers, and retrace servers that only makes debugging harder.
And the crash isn't something mutter can "fix", since it's
ultimately from a bug in Xwayland anyway.

This commit makes mutter exit instead of crash if Xwayland goes away
unexpectedly.


(cherry picked from commit 2d80fd02e7)
2018-04-24 05:08:22 +00:00
Ray Strode
99d766c044 xwayland: use g_autoptr for GError in xserver_died
Right now we explicitly g_clear_error any error we find, but that
makes it tricky to return early from the function, which a
subsequent commit will want to to do.

This commit switches GError to use g_autoptr so the error clearing
happens automatically.


(cherry picked from commit bb65854065)
2018-04-24 05:07:41 +00:00
Marco Trevisan (Treviño)
fcd4c816c4 theme, frames: Use surface device scale instead of cairo_scale
Gtk now is caching the themed cairo surfaces, then as per
commit gtk@e36b629c the surface device scale is used to figure
out the current paint scaling.

Without this when using background-image's for window buttons
the -gtk-scaled icons isn't properly resized.

Fixes #99


(cherry picked from commit 4339b23dd0)
2018-04-22 20:45:29 +00:00
Carlos Garnacho
2a63a47d5a wayland: Do not reset frame list when merging pending state
In the synchronized subsurface case, the destination list may
contain other elements from previous wl_surface.commit calls.
Resetting the list will leave those dangling frame callbacks
that will lead to invalid writes when those get to be destroyed
(eg. on client shutdown).
2018-04-22 12:14:37 +02:00
Carlos Garnacho
c80e2c9ae5 clutter: Set slave=master in IM forwarded key events
The fix is twofold. On one hand, it makes sense not to relate IM (nor
any other) generated events to a HW device. On the other hand, if we
are unfortunate that an IM event is in flight when we are switching
to another TTY, it may arrive at a time when the source device is no
longer existent.
2018-04-22 12:14:37 +02:00
Bastien Nocera
d3d5eb8e1b idle-monitor: Add ResetIdletime API, for testing purposes
The ResetIdletime API can be used instead of an "XTest" binary to
programmatically reset the idle time, as if the user pressed a button on
a keyboard.

This is necessary since we stopped using the XSync extension to monitor
idletimes, as it didn't consider inhibitors as busy, and mutter's
clutter code ignores "Core Events" as generated by XTest.

This patch will require minimal changes to gnome-settings-daemon's power
test suite so that "key press" idletime resets are triggered through
this D-Bus interface rather than through XTest and a roundtrip through
the X server.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
4837cec89f backend: Reset idle when lid is opened or resuming from suspend
There's no particular reason for this code to only ever be triggered on
Wayland, and allows removing X11-specific work-arounds from
gnome-settings-daemon.

See https://bugs.freedesktop.org/show_bug.cgi?id=59576

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
32329e6c00 idle-monitor: Take idle inhibition into account
Take idle inhibitions into account for when to fire idle watches as
requested by OS components.

This should stop gnome-session and gnome-settings-daemon considering
the session idle when they have been inhibited for longer than their
timeout, for example to avoid the screensaver activating, or the
computer suspending after watching a film.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
89261be556 x11: Allow XTest and core events to reset idletime
Now that we've removed the X11 specific backend of the idle monitor,
add back a cut-down version of it for the explicit purpose of being
told about idle time resets when XTest events are used.

XTest events are usually used by test suites and remote display software
to inject events into an X11 session. We should consider somebody moving
the mouse remotely to be just as "active" as somebody moving it locally.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
e3e76d658b backends: Remove X11 idle-monitor backend
And use the old "native" backend for both X11 and Wayland. This will
allow us to share fixes between implementations without having to delve
into the XSync X11 extension code.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Florian Müllner
34644b2133 Bump version to 3.28.1
Update NEWS.
2018-04-13 19:11:57 +02:00
Carlos Garnacho
7da4e8cf14 wayland: Plug surface pending state contents leak
When moving the pending state of an effectively synchronized subsurface
so it is applied together with the parent, perform a merge of the source
MetaWaylandPendingState into the destination one, instead of simply
overwriting the struct.

The other approach had 2 kind of leaks, one that would happen everytime
a wl_surface.commit happens on a sync subsurface (both surface/buffer
damage regions are leaked). The other more unlikely one would apply on
the rest of pending state data, happening whenever the compositor gets
>1 wl_surface.commit calls on the subsurface before the parent surface
gets its own.

The function has also been renamed to use the more descriptive "merge"
term.

Related: gnome-shell#64
2018-04-13 00:10:03 +02:00
Aleksandr Mezin
23c3f8bb18 monitor-manager: fix output ids returned by GetResources
Output ID is set equal to 'i' later in the loop. But 'i' was never
incremented, so all outputs were getting the same ID (equal to
the number of CRTCs, because 'i' was reused from the previous loop).
2018-04-11 17:55:41 +00:00
Jonas Ådahl
60866e0f85 native: Disable the use of KMS modifiers by default
Make it re-enable:able by a hidden "experimental feature". To enable,
add "kms-modifiers" to the org.gnome.mutter.experimental-features
GSettings entry.

https://gitlab.gnome.org/GNOME/mutter/issues/81
2018-04-11 16:34:59 +02:00
Matej Urbančič
45c02645f3 Updated Slovenian translation 2018-04-10 17:58:12 +02:00
Benjamin Otte
e515e37a7e screen-cast: Fix compile error
Credit goes to gcc for finding this typo.


(cherry picked from commit 98dfd5b887)
2018-04-10 12:10:19 +00:00
Marco Trevisan (Treviño)
957f4ec69d theme: Scale titlebar spacing when computing x
The value is not scaled by default so it needs to be adjusted
depending on the window scaling, as it's done in other places.

Fixes: #87


(cherry picked from commit deda7a5235)
2018-04-03 20:42:28 +00:00
Marco Trevisan (Treviño)
a98eb107be theme: add ".appmenu" class to the appmenu button
So it does gtk headerbar, so mutter should do.


(cherry picked from commit 96141e28f9)
2018-04-03 20:22:52 +00:00
Daniel Stone
1851fa2bd0 renderer-native: Fall back to non-modifier GBM surfaces
If we attempt GBM surface allocation with a set of modifiers but the
allocation fails, fall back to non-modifier allocations. This fixes
startup on Pineview-based Atom systems, where KMS provides us a set of
modifiers but the GBM implementation doesn't support modifier use.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/84


(cherry picked from commit e6109cfc22)
2018-04-03 18:18:31 +00:00
Carlos Garnacho
de7d7bbf3d clutter: Apply input hints/purpose on ClutterTextInputFocus focus in
And make the ClutterText-level properties independent from the input
focus, as those properties can be set anytime, not just when the
ClutterText actor is focused.

https://gitlab.gnome.org/GNOME/mutter/issues/66

Closes: #66


(cherry picked from commit 3684f6b0ac)
2018-04-03 15:00:01 +00:00
Alberts Muktupāvels
7ac551cd05 input-settings: Fix a typo in tap-and-drag setting
(cherry picked from commit 31b5059068)
2018-03-29 14:54:00 +00:00
Olivier Fourdan
8696a79477 cursor-renderer-native: take rotation into account
Rotating an output would show duplicate cursors when the pointer is
located over an area which would be within the output if not rotated.

Make sure to swap the width/height of the output when rotated.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/85


(cherry picked from commit ebff7fd7f4)
2018-03-29 06:49:14 +00:00
Daniel van Vugt
b2f9de98d0 renderer-native: Swap then await earlier flips.
Rendering the next frame (which mostly happens as part of the flush done
in swap buffers) is a task that the GPU can complete independently of
the CPU having to wait for previous page flips. So reverse their order
to get the GPU started earlier, with the aim of greater GPU-CPU
parallelism.


(cherry picked from commit 6e415353e3)
2018-03-29 05:41:02 +00:00
Georges Basile Stavracas Neto
2da2489da5 window: Fix a small memory leak
(cherry picked from commit 63e2c0329f)
2018-03-29 05:24:08 +00:00
Yussuf Khalil
31779404f0 clutter: Avoid unnecessary relayouts in ClutterText
We can save an unnecessary relayout if the required size to fully draw the text
is equal to the currently allocated size after the underlying text buffer or
attributes that only affect the PangoLayout have changed.
2018-03-22 23:35:27 +01:00
Rasmus Thomsen
b096c0ac33 mutter: allow building with elogind
This commit allows building mutter with elogind, which is
systemd-logind extracted into a standalone package. This
allows using mutter with its native-backend ( and consequently
wayland ) enabled on distros which use init systems other than
systemd.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/46
2018-03-21 23:07:46 +01:00
Carlos Garnacho
44a7f74dcd cogl: Read pixels as per the stored format
By the looks of it, commit 95e9fa10ef was taping over an Intel DRI bug
that would make it return post-swizzling pixel data on glReadPixels().
There's been reports over time of that commit resulting in wrong colors
on other drivers, and lately Mesa >17.3 started showing the same symptoms
on Intel.

But texture swizzling works by changing parameters before fragment shaders
and reading pixels from an already drawn FBO/texture doesn't involve those.
This should thus use pixel_format_to_gl_with_target(), which will result in
correctly requesting the same pixel format than the underlying texture,
while still considering it BGRA for the upper layers in the swizzling case.

https://gitlab.gnome.org/GNOME/mutter/issues/72

Closes: #72
2018-03-21 20:37:34 +01:00
Georges Basile Stavracas Neto
3832c6b607 gpu-kms: Ignore GPUs with no connectors
Mutter recently gained the ability to deal with multiple GPUs
rendering at different displays. These GPUs would have a display
connected to them, and Mutter was adapted in order to be aware
of different GPUs and their outputs.

However, one specific edge case appeared: PRIME systems. PRIME
systems have two GPUs:

 * The integrated GPU (iGPU), usually Intel, which has connectors
   and deals with the routine load.

 * The dedicated GPU (dGPU), usually AMD or NVidia, which has no
   connectors at all and are there just to aid heavy loads.

On those systems, the dGPU is aggressively put to sleep by the
kernel to avoid energy waste. Waking it up is a costly operation.

With Mutter's adaptation to deal with multiple GPUs, Mutter began
wakening the dGPU every time some rendering had to be done. This
was causing stuttering every time the dGPU was put to sleep, and
Mutter asked it to wake up again.

To fix this situation, this commit ignores GPUs with no connectors
attached.

Issue: #77
2018-03-21 18:50:14 +00:00
Georges Basile Stavracas Neto
14b7e79d3c gpu-kms: Return NULL, not FALSE
Another small mistake spotted while working on #77. This
function returns a pointer, thus we should return NULL,
not FALSE.

Issue: #77
2018-03-21 18:50:13 +00:00
Georges Basile Stavracas Neto
e99b0b9368 monitor-manager-kms: Don't add GPU if it fails
This is a small mistake spotted while working on a solution
for #77. When a GPU fails to initialize, we're adding them
anyway, which might have pretty bad consequences when trying
to use these NULL GPUs.

Issue: #77
2018-03-21 18:50:13 +00:00
Georges Basile Stavracas Neto
de294f34bb monitor-manager-kms: Use g_autoptr for error
A minor code cleanup.
2018-03-21 18:50:13 +00:00
81 changed files with 1920 additions and 1286 deletions

39
NEWS
View File

@@ -1,34 +1,43 @@
3.29.2
3.28.3
======
* Fix size change animations on wayland [Georges; #780292]
* Handle touch events on server-side titlebars [Carlos; #770185]
* Misc. bug fixes [Florian, Olivier, Jonas, Georges; #134, #124, !96, #138,
!102, #781471, #150]
* Fix crash with unhandled mouse buttons on titlebars [Olivier; #160]
* Fix Korean Hangul support on wayland [Changwoo; #152]
* Fix crash when taking up from suspend [Jonas; #786929]
* Fix crash with parent-less modal dialogs [Olivier; #174]
* Misc. bug fixes [Olivier, Georges; #83, #112, #150, #104,
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Georges Basile Stavracas Neto,
Changwoo Ryu, Marco Trevisan (Treviño)
3.28.2
======
* Take inhibitors into account for monitoring idle [Bastien; #705942]
* Fix window animations on wayland [Georges; #780292]
* Misc. bug fixes [Mario, Jonas, Olivier, Florian; gnome-shell#157, #130,
#21, #124, !96, #138, !102, #781471]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Florian Müllner,
Georges Basile Stavracas Neto, Marco Trevisan (Treviño), Daniel van Vugt
Georges Basile Stavracas Neto, Bastien Nocera, Mario Sanchez Prada,
Ray Strode, Marco Trevisan (Treviño)
Translators:
Daniel Șerbănescu [ro], Marcos Lans [gl], Dz Chen [zh_CN]
3.29.1
3.28.1
======
* Fix various input-method regressions [Carlos, Olivier; #65, #74, #66, #112]
* Fix various input-method regressions [Carlos; #65, #74, #66]
* Fix wayland build on FreeBSD [Ting-Wei; #792280, #792717]
* Fix swapped colors in screenshots (again) [Carlos; #72]
* Allow building with elogind [Rasmus; !46]
* Consider display rotation for cursor [Olivier; #85]
* Fall back to non-modifier GBM surfaces [Daniel; #84]
* Take inhibitors into account for monitoring idle [Bastien; #705942]
* Misc. bug fixes [handsome-feng, Olivier, Mario, Jonas; !45, #83, #104,
gnome-shell#157, #130, #21]
* Disable KMS modifiers by default [Jonas; #81]
* Misc bug fixes [handsome-feng; !45]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, handsome-feng, Yussuf Khalil,
Ting-Wei Lan, Aleksandr Mezin, Alberts Muktupāvels,
Georges Basile Stavracas Neto, Bastien Nocera, Benjamin Otte,
Mario Sanchez Prada, Daniel Stone, Ray Strode, Rasmus Thomsen,
Georges Basile Stavracas Neto, Benjamin Otte, Daniel Stone, Rasmus Thomsen,
Marco Trevisan (Treviño), Daniel van Vugt
Translators:

View File

@@ -840,6 +840,8 @@ struct _ClutterActorPrivate
guint needs_compute_expand : 1;
guint needs_x_expand : 1;
guint needs_y_expand : 1;
guint needs_paint_volume_update : 1;
guint had_effects_on_last_paint_volume_update : 1;
};
enum
@@ -1092,6 +1094,11 @@ static void clutter_actor_set_child_transform_internal (ClutterActor *sel
static void clutter_actor_realize_internal (ClutterActor *self);
static void clutter_actor_unrealize_internal (ClutterActor *self);
static void clutter_actor_push_in_cloned_branch (ClutterActor *self,
gulong count);
static void clutter_actor_pop_in_cloned_branch (ClutterActor *self,
gulong count);
/* Helper macro which translates by the anchor coord, applies the
given transformation and then translates back */
#define TRANSFORM_ABOUT_ANCHOR_COORD(a,m,c,_transform) G_STMT_START { \
@@ -1504,6 +1511,8 @@ clutter_actor_real_map (ClutterActor *self)
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED);
self->priv->needs_paint_volume_update = TRUE;
stage = _clutter_actor_get_stage_internal (self);
priv->pick_id = _clutter_stage_acquire_pick_id (CLUTTER_STAGE (stage), self);
@@ -2737,6 +2746,7 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
priv->needs_width_request = TRUE;
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
priv->needs_paint_volume_update = TRUE;
/* reset the cached size requests */
memset (priv->width_requests, 0,
@@ -4285,6 +4295,9 @@ clutter_actor_remove_child_internal (ClutterActor *self,
self->priv->age += 1;
if (self->priv->in_cloned_branch)
clutter_actor_pop_in_cloned_branch (child, self->priv->in_cloned_branch);
/* if the child that got removed was visible and set to
* expand then we want to reset the parent's state in
* case the child was the only thing that was making it
@@ -8518,6 +8531,7 @@ clutter_actor_init (ClutterActor *self)
priv->needs_width_request = TRUE;
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
priv->needs_paint_volume_update = TRUE;
priv->cached_width_age = 1;
priv->cached_height_age = 1;
@@ -10084,6 +10098,9 @@ clutter_actor_allocate (ClutterActor *self,
return;
}
if (CLUTTER_ACTOR_IS_MAPPED (self))
self->priv->needs_paint_volume_update = TRUE;
if (!stage_allocation_changed)
{
/* If the actor didn't move but needs_allocation is set, we just
@@ -12902,6 +12919,9 @@ clutter_actor_add_child_internal (ClutterActor *self,
self->priv->age += 1;
if (self->priv->in_cloned_branch)
clutter_actor_push_in_cloned_branch (child, self->priv->in_cloned_branch);
/* if push_internal() has been called then we automatically set
* the flag on the actor
*/
@@ -12972,6 +12992,9 @@ clutter_actor_add_child_internal (ClutterActor *self,
child->priv->needs_height_request = TRUE;
child->priv->needs_allocation = TRUE;
if (CLUTTER_ACTOR_IS_MAPPED (child))
child->priv->needs_paint_volume_update = TRUE;
/* we only queue a relayout here, because any possible
* redraw has already been queued either by show() or
* by our call to queue_redraw() above
@@ -17463,7 +17486,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
*/
effects = _clutter_meta_group_peek_metas (priv->effects);
for (l = effects;
l != NULL || (l != NULL && l->data != priv->current_effect);
l != NULL && l->data != priv->current_effect;
l = l->next)
{
if (!_clutter_effect_get_paint_volume (l->data, pv))
@@ -17499,6 +17522,32 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
return TRUE;
}
static gboolean
_clutter_actor_has_active_paint_volume_override_effects (ClutterActor *self)
{
const GList *l;
if (self->priv->effects == NULL)
return FALSE;
/* We just need to all effects current effect to see
* if anyone wants to override the paint volume. If so, then
* we need to recompute, since the paint volume returned can
* change from call to call. */
for (l = _clutter_meta_group_peek_metas (self->priv->effects);
l != NULL;
l = l->next)
{
ClutterEffect *effect = l->data;
if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)) &&
_clutter_effect_has_custom_paint_volume (effect))
return TRUE;
}
return FALSE;
}
/* The public clutter_actor_get_paint_volume API returns a const
* pointer since we return a pointer directly to the cached
* PaintVolume associated with the actor and don't want the user to
@@ -17509,16 +17558,37 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
static ClutterPaintVolume *
_clutter_actor_get_paint_volume_mutable (ClutterActor *self)
{
gboolean has_paint_volume_override_effects;
ClutterActorPrivate *priv;
priv = self->priv;
has_paint_volume_override_effects = _clutter_actor_has_active_paint_volume_override_effects (self);
if (priv->paint_volume_valid)
clutter_paint_volume_free (&priv->paint_volume);
{
/* If effects are applied, the actor paint volume
* needs to be recomputed on each paint, since those
* paint volumes could change over the duration of the
* effect.
*
* We also need to update the paint volume if we went
* from having effects to not having effects on the last
* paint volume update. */
if (!priv->needs_paint_volume_update &&
priv->current_effect == NULL &&
!has_paint_volume_override_effects &&
!priv->had_effects_on_last_paint_volume_update)
return &priv->paint_volume;
clutter_paint_volume_free (&priv->paint_volume);
}
priv->had_effects_on_last_paint_volume_update = has_paint_volume_override_effects;
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
{
priv->paint_volume_valid = TRUE;
priv->needs_paint_volume_update = FALSE;
return &priv->paint_volume;
}
else
@@ -20688,29 +20758,31 @@ clutter_actor_get_child_transform (ClutterActor *self,
}
static void
clutter_actor_push_in_cloned_branch (ClutterActor *self)
clutter_actor_push_in_cloned_branch (ClutterActor *self,
gulong count)
{
ClutterActor *iter;
for (iter = self->priv->first_child;
iter != NULL;
iter = iter->priv->next_sibling)
clutter_actor_push_in_cloned_branch (iter);
clutter_actor_push_in_cloned_branch (iter, count);
self->priv->in_cloned_branch += 1;
self->priv->in_cloned_branch += count;
}
static void
clutter_actor_pop_in_cloned_branch (ClutterActor *self)
clutter_actor_pop_in_cloned_branch (ClutterActor *self,
gulong count)
{
ClutterActor *iter;
self->priv->in_cloned_branch -= 1;
self->priv->in_cloned_branch -= count;
for (iter = self->priv->first_child;
iter != NULL;
iter = iter->priv->next_sibling)
clutter_actor_pop_in_cloned_branch (iter);
clutter_actor_pop_in_cloned_branch (iter, count);
}
void
@@ -20726,7 +20798,7 @@ _clutter_actor_attach_clone (ClutterActor *actor,
g_hash_table_add (priv->clones, clone);
clutter_actor_push_in_cloned_branch (actor);
clutter_actor_push_in_cloned_branch (actor, 1);
}
void
@@ -20741,7 +20813,7 @@ _clutter_actor_detach_clone (ClutterActor *actor,
g_hash_table_lookup (priv->clones, clone) == NULL)
return;
clutter_actor_pop_in_cloned_branch (actor);
clutter_actor_pop_in_cloned_branch (actor, 1);
g_hash_table_remove (priv->clones, clone);

View File

@@ -9,6 +9,7 @@ gboolean _clutter_effect_pre_paint (ClutterEffect
void _clutter_effect_post_paint (ClutterEffect *effect);
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume);
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
void _clutter_effect_paint (ClutterEffect *effect,
ClutterEffectPaintFlags flags);
void _clutter_effect_pick (ClutterEffect *effect,

View File

@@ -308,6 +308,14 @@ _clutter_effect_get_paint_volume (ClutterEffect *effect,
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
}
gboolean
_clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
{
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
}
/**
* clutter_effect_queue_repaint:
* @effect: A #ClutterEffect which needs redrawing

View File

@@ -1782,7 +1782,7 @@ selection_paint (ClutterText *self)
CoglColor cogl_color = { 0, };
CoglFramebuffer *fb;
fb = _clutter_actor_get_active_framebuffer (actor);
fb = cogl_get_draw_framebuffer ();
if (G_UNLIKELY (fb == NULL))
return;
@@ -2391,13 +2391,7 @@ clutter_text_paint (ClutterActor *self)
float alloc_width;
float alloc_height;
/* FIXME: this should not be needed, but apparently the text-cache
* test unit manages to get in a situation where the active frame
* buffer is NULL
*/
fb = _clutter_actor_get_active_framebuffer (self);
if (fb == NULL)
fb = cogl_get_draw_framebuffer ();
fb = cogl_get_draw_framebuffer ();
/* Note that if anything in this paint method changes it needs to be
reflected in the get_paint_volume implementation which is tightly

View File

@@ -185,6 +185,26 @@ clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDe
NULL);
}
static int
translate_to_evdev_button (int clutter_button)
{
switch (clutter_button)
{
case CLUTTER_BUTTON_PRIMARY:
return BTN_LEFT;
case CLUTTER_BUTTON_SECONDARY:
return BTN_RIGHT;
case CLUTTER_BUTTON_MIDDLE:
return BTN_MIDDLE;
default:
/*
* For compatibility reasons, all additional buttons go after the old
* 4-7 scroll ones.
*/
return clutter_button + (BTN_LEFT - 1) - 4;
}
}
static void
clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *virtual_device,
uint64_t time_us,
@@ -194,30 +214,33 @@ clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *vir
ClutterVirtualInputDeviceEvdev *virtual_evdev =
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
int button_count;
int evdev_button;
if (time_us == CLUTTER_CURRENT_TIME)
time_us = g_get_monotonic_time ();
if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON)
evdev_button = translate_to_evdev_button (button);
if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
{
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
button);
evdev_button);
return;
}
button_count = update_button_count (virtual_evdev, button, button_state);
button_count = update_button_count (virtual_evdev, evdev_button, button_state);
if (button_count < 0 || button_count > 1)
{
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", button,
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases");
update_button_count (virtual_evdev, button, 1 - button_state);
update_button_count (virtual_evdev, evdev_button, 1 - button_state);
return;
}
clutter_seat_evdev_notify_button (virtual_evdev->seat,
virtual_evdev->device,
time_us,
button,
evdev_button,
button_state);
}

View File

@@ -110,8 +110,7 @@ clutter_input_device_xi2_finalize (GObject *object)
if (device_xi2->wacom_device)
libwacom_destroy (device_xi2->wacom_device);
if (device_xi2->group_modes)
g_array_unref (device_xi2->group_modes);
g_array_unref (device_xi2->group_modes);
#endif
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);

View File

@@ -38,6 +38,14 @@
typedef struct _ClutterKeymapX11Class ClutterKeymapX11Class;
typedef struct _DirectionCacheEntry DirectionCacheEntry;
typedef struct _ClutterKeymapKey ClutterKeymapKey;
struct _ClutterKeymapKey
{
guint keycode;
guint group;
guint level;
};
struct _DirectionCacheEntry
{
@@ -59,6 +67,7 @@ struct _ClutterKeymapX11
ClutterModifierType num_lock_mask;
ClutterModifierType scroll_lock_mask;
ClutterModifierType level3_shift_mask;
PangoDirection current_direction;
@@ -69,6 +78,7 @@ struct _ClutterKeymapX11
Atom current_group_atom;
guint current_cache_serial;
DirectionCacheEntry group_direction_cache[4];
int current_group;
#endif
guint caps_lock_state : 1;
@@ -198,6 +208,9 @@ get_xkb (ClutterKeymapX11 *keymap_x11)
if (keymap_x11->scroll_lock_mask == 0)
keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
XK_Scroll_Lock);
if (keymap_x11->level3_shift_mask == 0)
keymap_x11->level3_shift_mask = XkbKeysymToModifiers (backend_x11->xdpy,
XK_ISO_Level3_Shift);
return keymap_x11->xkb_desc;
}
@@ -469,6 +482,7 @@ static void
clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
{
keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
keymap->current_group = -1;
}
static ClutterTranslateReturn
@@ -498,7 +512,8 @@ clutter_keymap_x11_translate_event (ClutterEventTranslator *translator,
{
case XkbStateNotify:
CLUTTER_NOTE (EVENT, "Updating keyboard state");
update_direction (keymap_x11, XkbStateGroup (&xkb_event->state));
keymap_x11->current_group = XkbStateGroup (&xkb_event->state);
update_direction (keymap_x11, keymap_x11->current_group);
update_locked_mods (keymap_x11, xkb_event->state.locked_mods);
retval = CLUTTER_TRANSLATE_REMOVE;
break;
@@ -665,3 +680,164 @@ _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap)
#endif
return PANGO_DIRECTION_NEUTRAL;
}
static gboolean
clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11,
guint keyval,
ClutterKeymapKey **keys,
gint *n_keys)
{
#ifdef HAVE_XKB
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
{
XkbDescRec *xkb = get_xkb (keymap_x11);
GArray *retval;
gint keycode;
keycode = keymap_x11->min_keycode;
retval = g_array_new (FALSE, FALSE, sizeof (ClutterKeymapKey));
while (keycode <= keymap_x11->max_keycode)
{
gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
gint group = 0;
gint level = 0;
gint total_syms = XkbKeyNumSyms (xkb, keycode);
gint i = 0;
KeySym *entry;
/* entry is an array with all syms for group 0, all
* syms for group 1, etc. and for each group the
* shift level syms are in order
*/
entry = XkbKeySymsPtr (xkb, keycode);
while (i < total_syms)
{
g_assert (i == (group * max_shift_levels + level));
if (entry[i] == keyval)
{
ClutterKeymapKey key;
key.keycode = keycode;
key.group = group;
key.level = level;
g_array_append_val (retval, key);
g_assert (XkbKeySymEntry (xkb, keycode, level, group) ==
keyval);
}
++level;
if (level == max_shift_levels)
{
level = 0;
++group;
}
++i;
}
++keycode;
}
if (retval->len > 0)
{
*keys = (ClutterKeymapKey*) retval->data;
*n_keys = retval->len;
}
else
{
*keys = NULL;
*n_keys = 0;
}
g_array_free (retval, retval->len > 0 ? FALSE : TRUE);
return *n_keys > 0;
}
else
#endif
{
return FALSE;
}
}
void
clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
uint32_t level,
gboolean enable)
{
#ifdef HAVE_XKB
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
uint32_t modifiers[] = {
0,
ShiftMask,
keymap_x11->level3_shift_mask,
keymap_x11->level3_shift_mask | ShiftMask,
};
uint32_t value = 0;
if (!backend_x11->use_xkb)
return;
level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1);
if (enable)
value = modifiers[level];
else
value = 0;
XkbLatchModifiers (clutter_x11_get_default_display (),
XkbUseCoreKbd, modifiers[level],
value);
#endif
}
static uint32_t
clutter_keymap_x11_get_current_group (ClutterKeymapX11 *keymap_x11)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
XkbStateRec state_rec;
if (keymap_x11->current_group >= 0)
return keymap_x11->current_group;
XkbGetState (backend_x11->xdpy, XkbUseCoreKbd, &state_rec);
return XkbStateGroup (&state_rec);
}
gboolean
clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
guint keyval,
guint *keycode_out,
guint *level_out)
{
ClutterKeymapKey *keys;
gint i, n_keys, group;
gboolean found = FALSE;
g_return_val_if_fail (keycode_out != NULL, FALSE);
g_return_val_if_fail (level_out != NULL, FALSE);
group = clutter_keymap_x11_get_current_group (keymap_x11);
if (!clutter_keymap_x11_get_entries_for_keyval (keymap_x11, keyval, &keys, &n_keys))
return FALSE;
for (i = 0; i < n_keys && !found; i++)
{
if (keys[i].group == group)
{
*keycode_out = keys[i].keycode;
*level_out = keys[i].level;
found = TRUE;
}
}
g_free (keys);
return found;
}

View File

@@ -51,6 +51,14 @@ gboolean _clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap,
PangoDirection _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap);
gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
guint keyval,
guint *keycode_out,
guint *level_out);
void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
uint32_t level,
gboolean enable);
G_END_DECLS
#endif /* __CLUTTER_KEYMAP_X11_H__ */

View File

@@ -32,6 +32,8 @@
#include "clutter-virtual-input-device.h"
#include "x11/clutter-virtual-input-device-x11.h"
#include "x11/clutter-backend-x11.h"
#include "x11/clutter-keymap-x11.h"
struct _ClutterVirtualInputDeviceX11
{
@@ -135,11 +137,25 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
uint32_t keyval,
ClutterKeyState key_state)
{
KeyCode keycode;
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
ClutterKeymapX11 *keymap = backend_x11->keymap;
uint32_t keycode, level;
if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
{
g_warning ("No keycode found for keyval %x in current group", keyval);
return;
}
if (key_state == CLUTTER_KEY_STATE_PRESSED)
clutter_keymap_x11_latch_modifiers (keymap, level, TRUE);
keycode = XKeysymToKeycode (clutter_x11_get_default_display (), keyval);
XTestFakeKeyEvent (clutter_x11_get_default_display (),
keycode, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
(KeyCode) keycode,
key_state == CLUTTER_KEY_STATE_PRESSED, 0);
if (key_state == CLUTTER_KEY_STATE_RELEASED)
clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
}
static void

View File

@@ -1,8 +1,8 @@
AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [29])
m4_define([mutter_micro_version], [2])
m4_define([mutter_minor_version], [28])
m4_define([mutter_micro_version], [3])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])

View File

@@ -120,6 +120,10 @@
framebuffers instead of window content,
to manage HiDPI monitors. Does not
require a restart.
• “remote-desktop” — enables remote desktop support. To support
remote desktop with screen sharing,
“screen-cast” must also be enabled.
• “screen-cast” — enables screen cast support.
</description>
</key>

View File

@@ -14,16 +14,16 @@ msgid ""
msgstr ""
"Project-Id-Version: gl\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2018-03-03 13:19+0000\n"
"PO-Revision-Date: 2018-05-07 19:37+0200\n"
"Last-Translator: marcos <marcoslansgarza@gmail.com>\n"
"POT-Creation-Date: 2018-03-01 10:47+0000\n"
"PO-Revision-Date: 2018-03-03 14:18+0200\n"
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
"Language-Team: Galician\n"
"Language: gl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.6\n"
"X-Generator: Virtaal 0.7.1\n"
"X-Project-Style: gnome\n"
#: data/50-mutter-navigation.xml:6
@@ -100,7 +100,7 @@ msgstr "Cambia á xanela anterior dun aplicativo"
#: data/50-mutter-navigation.xml:70
msgid "Switch system controls"
msgstr "Cambiar entre os controis do sistema"
msgstr "Cambiar entre os controles do sistema"
#: data/50-mutter-navigation.xml:75
msgid "Switch to previous system control"
@@ -124,7 +124,7 @@ msgstr "Cambia directamente á xanela anterior do aplicativo"
#: data/50-mutter-navigation.xml:97
msgid "Switch system controls directly"
msgstr "Cambiar entre os controis do sistema directamente"
msgstr "Cambiar entre os controles do sistema directamente"
#: data/50-mutter-navigation.xml:102
msgid "Switch directly to previous system control"

556
po/ro.po
View File

@@ -4,13 +4,14 @@
# Mugurel Tudor <mugurelu@gnome.ro>, 2002-2004, 2005, 2006, 2007.
# Adi Roiban https://launchpad.net/~adiroiban, 2008, 2009
# Lucian Adrian Grijincu <lucian.grijincu@gmail.com>, 2011.
# Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>, 2015, 2018.
# Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>, 2015.
msgid ""
msgstr ""
"Project-Id-Version: metacity.HEAD.ro\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2018-04-26 07:32+0000\n"
"PO-Revision-Date: 2018-04-30 07:54+0200\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&"
"keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2015-10-21 11:43+0000\n"
"PO-Revision-Date: 2015-10-22 19:10+0200\n"
"Last-Translator: Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>\n"
"Language-Team: Gnome Romanian Translation Team\n"
"Language: ro\n"
@@ -22,256 +23,272 @@ msgstr ""
"X-Generator: Virtaal 0.7.1\n"
"X-Project-Style: gnome\n"
#: data/50-mutter-navigation.xml:6
#: ../data/50-mutter-navigation.xml.in.h:1
msgid "Navigation"
msgstr "Navigare"
#: data/50-mutter-navigation.xml:9
#: ../data/50-mutter-navigation.xml.in.h:2
msgid "Move window to workspace 1"
msgstr "Mută fereastra pe spațiul de lucru 1"
#: data/50-mutter-navigation.xml:12
#: ../data/50-mutter-navigation.xml.in.h:3
msgid "Move window to workspace 2"
msgstr "Mută fereastra pe spațiul de lucru 2"
#: data/50-mutter-navigation.xml:15
#: ../data/50-mutter-navigation.xml.in.h:4
msgid "Move window to workspace 3"
msgstr "Mută fereastra pe spațiul de lucru 3"
#: data/50-mutter-navigation.xml:18
#: ../data/50-mutter-navigation.xml.in.h:5
msgid "Move window to workspace 4"
msgstr "Mută fereastra pe spațiul de lucru 4"
#: data/50-mutter-navigation.xml:21
#: ../data/50-mutter-navigation.xml.in.h:6
msgid "Move window to last workspace"
msgstr "Mută fereastra pe spațiul de lucru anterior"
#: data/50-mutter-navigation.xml:24
#: ../data/50-mutter-navigation.xml.in.h:7
msgid "Move window one workspace to the left"
msgstr "Mută fereastra pe spațiul de lucru de la stânga"
#: ../data/50-mutter-navigation.xml.in.h:8
msgid "Move window one workspace to the right"
msgstr "Mută fereastra pe spațiul de lucru de la dreapta"
#: ../data/50-mutter-navigation.xml.in.h:9
msgid "Move window one workspace up"
msgstr "Mută fereastra pe spațiul de lucru de mai sus"
#: data/50-mutter-navigation.xml:27
#: ../data/50-mutter-navigation.xml.in.h:10
msgid "Move window one workspace down"
msgstr "Mută fereastra pe spațiul de lucru de mai jos"
#: data/50-mutter-navigation.xml:30
#: ../data/50-mutter-navigation.xml.in.h:11
msgid "Move window one monitor to the left"
msgstr "Mută fereastra cu un monitor la stânga"
#: data/50-mutter-navigation.xml:33
#: ../data/50-mutter-navigation.xml.in.h:12
msgid "Move window one monitor to the right"
msgstr "Mută fereastra un monitor la dreapta"
#: data/50-mutter-navigation.xml:36
#: ../data/50-mutter-navigation.xml.in.h:13
msgid "Move window one monitor up"
msgstr "Mută fereastra cu un monitor mai sus"
#: data/50-mutter-navigation.xml:39
#: ../data/50-mutter-navigation.xml.in.h:14
msgid "Move window one monitor down"
msgstr "Mută fereastra cu un monitor mai jos"
#: data/50-mutter-navigation.xml:43
#: ../data/50-mutter-navigation.xml.in.h:15
msgid "Switch applications"
msgstr "Comută aplicațiile"
#: data/50-mutter-navigation.xml:48
#: ../data/50-mutter-navigation.xml.in.h:16
msgid "Switch to previous application"
msgstr "Schimbă la aplicația anterioară"
#: data/50-mutter-navigation.xml:52
#: ../data/50-mutter-navigation.xml.in.h:17
msgid "Switch windows"
msgstr "Schimbă ferestre"
#: data/50-mutter-navigation.xml:57
#: ../data/50-mutter-navigation.xml.in.h:18
msgid "Switch to previous window"
msgstr "Schimbă la fereastra anterioară"
#: data/50-mutter-navigation.xml:61
#: ../data/50-mutter-navigation.xml.in.h:19
msgid "Switch windows of an application"
msgstr "Schimbă ferestrele unei aplicații"
#: data/50-mutter-navigation.xml:66
#: ../data/50-mutter-navigation.xml.in.h:20
msgid "Switch to previous window of an application"
msgstr "Schimbă la fereastra anterioară a unei aplicații"
#: data/50-mutter-navigation.xml:70
#: ../data/50-mutter-navigation.xml.in.h:21
msgid "Switch system controls"
msgstr "Schimbă comenzile de sistem"
#: data/50-mutter-navigation.xml:75
#: ../data/50-mutter-navigation.xml.in.h:22
msgid "Switch to previous system control"
msgstr "Schimbă la comanda de control anterioară"
#: data/50-mutter-navigation.xml:79
#: ../data/50-mutter-navigation.xml.in.h:23
msgid "Switch windows directly"
msgstr "Schimbă ferestrele în mod direct"
#: data/50-mutter-navigation.xml:84
#: ../data/50-mutter-navigation.xml.in.h:24
msgid "Switch directly to previous window"
msgstr "Schimbă la fereastra anterioară în mod direct"
#: data/50-mutter-navigation.xml:88
#: ../data/50-mutter-navigation.xml.in.h:25
msgid "Switch windows of an app directly"
msgstr "Comută direct ferestrele unei aplicații"
msgstr "Schimbă în mod direct ferestrele uneui aplicații "
#: data/50-mutter-navigation.xml:93
#: ../data/50-mutter-navigation.xml.in.h:26
msgid "Switch directly to previous window of an app"
msgstr "Schimbă în mod direct la fereastra anterioară a unei aplicații"
#: data/50-mutter-navigation.xml:97
#: ../data/50-mutter-navigation.xml.in.h:27
msgid "Switch system controls directly"
msgstr "Schimbă comenzile de sistem în mod direct"
#: data/50-mutter-navigation.xml:102
#: ../data/50-mutter-navigation.xml.in.h:28
msgid "Switch directly to previous system control"
msgstr "Schimbă în mod direct la o comandă de sistem anterioară"
#: data/50-mutter-navigation.xml:105
#: ../data/50-mutter-navigation.xml.in.h:29
msgid "Hide all normal windows"
msgstr "Ascunde toate ferestrele normale"
msgstr "Ascunde toate ferestrele normale "
#: data/50-mutter-navigation.xml:108
#: ../data/50-mutter-navigation.xml.in.h:30
msgid "Switch to workspace 1"
msgstr "Comută la spațiul de lucru 1"
#: data/50-mutter-navigation.xml:111
#: ../data/50-mutter-navigation.xml.in.h:31
msgid "Switch to workspace 2"
msgstr "Comută la spațiul de lucru 2"
#: data/50-mutter-navigation.xml:114
#: ../data/50-mutter-navigation.xml.in.h:32
msgid "Switch to workspace 3"
msgstr "Comută la spațiul de lucru 3"
#: data/50-mutter-navigation.xml:117
#: ../data/50-mutter-navigation.xml.in.h:33
msgid "Switch to workspace 4"
msgstr "Comută la spațiul de lucru 4"
#: data/50-mutter-navigation.xml:120
#: ../data/50-mutter-navigation.xml.in.h:34
msgid "Switch to last workspace"
msgstr "Comută la ultimul spațiu de lucru"
msgstr "Comută la ultimul spațiu de lucru "
#: data/50-mutter-navigation.xml:123
#: ../data/50-mutter-navigation.xml.in.h:35
msgid "Move to workspace left"
msgstr "Mută pe spațiul de lucru din stânga"
#: ../data/50-mutter-navigation.xml.in.h:36
msgid "Move to workspace right"
msgstr "Mută pe spațiul de lucru din dreapta"
#: ../data/50-mutter-navigation.xml.in.h:37
msgid "Move to workspace above"
msgstr "Mută pe spațiul de lucru deasupra"
#: data/50-mutter-navigation.xml:126
#: ../data/50-mutter-navigation.xml.in.h:38
msgid "Move to workspace below"
msgstr "Mută pe spațiul de lucru de jos"
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
#: ../data/50-mutter-system.xml.in.h:1
msgid "System"
msgstr "Sistem"
#: data/50-mutter-system.xml:8
#: ../data/50-mutter-system.xml.in.h:2
msgid "Show the run command prompt"
msgstr "Arată prompterul de comandă al comenzii run (rulează)"
#: data/50-mutter-system.xml:10
#: ../data/50-mutter-system.xml.in.h:3
msgid "Show the activities overview"
msgstr "Arată prezentarea generală a activităților"
#: data/50-mutter-wayland.xml:8
msgid "Restore the keyboard shortcuts"
msgstr "Restaurează scurtăturile de tastatură"
#: data/50-mutter-windows.xml:6
#: ../data/50-mutter-windows.xml.in.h:1
msgid "Windows"
msgstr "Ferestre"
#: data/50-mutter-windows.xml:8
#: ../data/50-mutter-windows.xml.in.h:2
msgid "Activate the window menu"
msgstr "Activează meniul ferestrei"
#: data/50-mutter-windows.xml:10
#: ../data/50-mutter-windows.xml.in.h:3
msgid "Toggle fullscreen mode"
msgstr "Comută modul pe tot ecranul"
#: data/50-mutter-windows.xml:12
#: ../data/50-mutter-windows.xml.in.h:4
msgid "Toggle maximization state"
msgstr "Comută starea de maximizare"
#: data/50-mutter-windows.xml:14
#: ../data/50-mutter-windows.xml.in.h:5
msgid "Maximize window"
msgstr "Maximizează fereastra"
#: data/50-mutter-windows.xml:16
#: ../data/50-mutter-windows.xml.in.h:6
msgid "Restore window"
msgstr "Restabilește fereastra"
#: data/50-mutter-windows.xml:18
#: ../data/50-mutter-windows.xml.in.h:7
msgid "Toggle shaded state"
msgstr "Comută starea de umbrire"
#: ../data/50-mutter-windows.xml.in.h:8
msgid "Close window"
msgstr "Închide fereastra"
#: data/50-mutter-windows.xml:20
#: ../data/50-mutter-windows.xml.in.h:9
msgid "Hide window"
msgstr "Ascunde fereastra"
#: data/50-mutter-windows.xml:22
#: ../data/50-mutter-windows.xml.in.h:10
msgid "Move window"
msgstr "Mută fereastra"
#: data/50-mutter-windows.xml:24
#: ../data/50-mutter-windows.xml.in.h:11
msgid "Resize window"
msgstr "Redimensionează fereastra"
#: data/50-mutter-windows.xml:27
#: ../data/50-mutter-windows.xml.in.h:12
msgid "Toggle window on all workspaces or one"
msgstr "Comută fereastra pe toate spațiile de lucru sau doar pe unul"
#: data/50-mutter-windows.xml:29
#: ../data/50-mutter-windows.xml.in.h:13
msgid "Raise window if covered, otherwise lower it"
msgstr "Ridică fereastra dacă este acoperită, altfel, coboar-o"
#: data/50-mutter-windows.xml:31
#: ../data/50-mutter-windows.xml.in.h:14
msgid "Raise window above other windows"
msgstr "Ridică fereastra deasupra celorlalte ferestre"
#: data/50-mutter-windows.xml:33
#: ../data/50-mutter-windows.xml.in.h:15
msgid "Lower window below other windows"
msgstr "Coboară fereastra sub alte ferestre"
#: data/50-mutter-windows.xml:35
#: ../data/50-mutter-windows.xml.in.h:16
msgid "Maximize window vertically"
msgstr "Maximizează fereastra pe verticală"
#: data/50-mutter-windows.xml:37
#: ../data/50-mutter-windows.xml.in.h:17
msgid "Maximize window horizontally"
msgstr "Maximizează fereastra pe orizontală"
#: data/50-mutter-windows.xml:41
#: ../data/50-mutter-windows.xml.in.h:18
msgid "View split on left"
msgstr "Împarte în stânga"
#: data/50-mutter-windows.xml:45
#: ../data/50-mutter-windows.xml.in.h:19
msgid "View split on right"
msgstr "Împarte în dreapta"
#: data/mutter.desktop.in:4
#: ../data/mutter.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#: data/org.gnome.mutter.gschema.xml.in:7
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
msgid "Modifier to use for extended window management operations"
msgstr ""
"Modificatorul folosit pentru operațiile extinse de management al ferestrelor"
#: data/org.gnome.mutter.gschema.xml.in:8
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
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."
"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. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
"Această cheie va iniția „suprapunerea”, care este o combinație între o "
"privire de ansamblu a ferestrelor și un sistem de lansare de aplicații. "
"Implicit este tasta „Windows” pe hardware PC. Este de așteptat ca această "
"legătură să fie ori stabilită la implicit sau la șirul vid."
"Această cheie va iniția „overlay”-ul, care este o combinație între o privire "
"de ansamblu a ferestrelor și un sistemul de lansare de aplicații. Implicit "
"este testa „Windows” pe hardware PC. Este de așteptat ca această cheie să "
"fie sau implicit sau setat la șirul vid."
#: data/org.gnome.mutter.gschema.xml.in:20
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
msgid "Attach modal dialogs"
msgstr "Atașează dialogurile modale"
#: data/org.gnome.mutter.gschema.xml.in:21
#: ../data/org.gnome.mutter.gschema.xml.in.h:4
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
@@ -281,12 +298,13 @@ msgstr ""
"modale apar atașate la bara de titlu a ferestrei părinte și sunt mutate "
"împreună cu fereastra părinte."
#: data/org.gnome.mutter.gschema.xml.in:30
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
#, fuzzy
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Activează mozaicul de margine la plasarea ferestrelor pe marginile ecranului"
"Activează mozaicul lateral la plasarea ferestrelor pe marginile ecranului"
#: data/org.gnome.mutter.gschema.xml.in:31
#: ../data/org.gnome.mutter.gschema.xml.in.h:6
msgid ""
"If enabled, dropping windows on vertical screen edges maximizes them "
"vertically and resizes them horizontally to cover half of the available "
@@ -297,25 +315,25 @@ msgstr ""
"pentru a acoperi jumătate din suprafața disponibilă. Plasarea ferestrelor pe "
"marginea de sus a ecranului le maximizează complet."
#: data/org.gnome.mutter.gschema.xml.in:40
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
msgid "Workspaces are managed dynamically"
msgstr "Spațiile de lucru sunt gestionate în mod dinamic"
#: data/org.gnome.mutter.gschema.xml.in:41
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
msgid ""
"Determines whether workspaces are managed dynamically or whether theres a "
"Determines whether workspaces are managed dynamically or whether there's a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
"Determină dacă spațiile de lucru sunt administrate dinamic sau dacă există "
"un număr static de spații de lucru (determinat de cheia num-workspaces din "
"org.gnome.desktop.wm.preferences)"
"Determină dacă spațiile de lucru sunt gestionate în mod dinamic sau dacă "
"există un număr static de spații de lucru (determinată de cheia num-"
"workspaces” din ”org.gnome.desktop.wm.preferences)"
#: data/org.gnome.mutter.gschema.xml.in:50
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
msgid "Workspaces only on primary"
msgstr "Spații de lucru doar pe ecranul principal"
#: data/org.gnome.mutter.gschema.xml.in:51
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
@@ -324,11 +342,11 @@ msgstr ""
"ferestrele de pe toate monitoarele sau doar pentru ferestrele de pe "
"monitorul principal."
#: data/org.gnome.mutter.gschema.xml.in:59
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
msgid "No tab popup"
msgstr "Fără popup pentru tab"
#: data/org.gnome.mutter.gschema.xml.in:60
#: ../data/org.gnome.mutter.gschema.xml.in.h:12
msgid ""
"Determines whether the use of popup and highlight frame should be disabled "
"for window cycling."
@@ -336,40 +354,42 @@ msgstr ""
"Determină dacă utilizarea unui popup sau a unui cadrul evidențiat ar trebui "
"să fie dezactivată pentru rotirea ferestrelor."
#: data/org.gnome.mutter.gschema.xml.in:68
#: ../data/org.gnome.mutter.gschema.xml.in.h:13
msgid "Delay focus changes until the pointer stops moving"
msgstr ""
"Întârzie schimbările de focalizare până când cursorul încetează să se miște"
#: data/org.gnome.mutter.gschema.xml.in:69
#: ../data/org.gnome.mutter.gschema.xml.in.h:14
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."
"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 ""
"Dacă este stabilit ca adevărat, iar modul de focalizare este ori „neglijent” "
"ori „maus”, atunci focalizarea nu va fi schimbată imediat la intrarea într-o "
"fereastră, ci doar după ce indicatorul nu se mai mișcă."
"Dacă este activat iar modul de focalizare este „alunecos” sau „maus”, "
"focalizarea nu va fi schimbată imediat după intrarea în câmpul unei "
"ferestre, ci doar după ce pointerul încetează să se miște."
#: data/org.gnome.mutter.gschema.xml.in:79
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
#, fuzzy
msgid "Draggable border width"
msgstr "Lățimea marginii ce poate fi plasată"
msgstr "Lățimea margini ce poate fi acționată"
#: data/org.gnome.mutter.gschema.xml.in:80
#: ../data/org.gnome.mutter.gschema.xml.in.h:16
#, fuzzy
msgid ""
"The amount of total draggable borders. If the themes visible borders are "
"The amount of total draggable borders. If the theme's visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
"Numărul total de margini ce pot fi plasate. Dacă marginile vizibile ale "
"temei nu sunt suficiente, vor fi adăugate margini invizibile pentru a "
"respecta această valoare."
"Numărul marginilor ce pot fi acționate. Dacă marginile vizibile ale temei "
"sunt insuficiente vor fi adăugate margini invizibile pentru a completa "
"aceast număr."
#: data/org.gnome.mutter.gschema.xml.in:89
#: ../data/org.gnome.mutter.gschema.xml.in.h:17
msgid "Auto maximize nearly monitor sized windows"
msgstr ""
"Maximizează automat ferestrele de dimensiune apropiată de cea a monitorului"
#: data/org.gnome.mutter.gschema.xml.in:90
#: ../data/org.gnome.mutter.gschema.xml.in.h:18
msgid ""
"If enabled, new windows that are initially the size of the monitor "
"automatically get maximized."
@@ -377,11 +397,11 @@ msgstr ""
"Dacă este activată, ferestrele noi care sunt inițial de mărimea monitorului "
"sunt maximizate în mod automat."
#: data/org.gnome.mutter.gschema.xml.in:98
#: ../data/org.gnome.mutter.gschema.xml.in.h:19
msgid "Place new windows in the center"
msgstr "Plasează ferestre noi în centru"
#: data/org.gnome.mutter.gschema.xml.in:99
#: ../data/org.gnome.mutter.gschema.xml.in.h:20
msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
@@ -389,262 +409,107 @@ msgstr ""
"Când este adevărat, ferestrele noi vor fi plasate în centrul ecranului activ "
"al monitorului."
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Activează funcționalitățile experimentale"
#: 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. • “remote-desktop” — "
"enables remote desktop support. To support remote desktop with screen "
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
"screen cast support."
msgstr ""
"Pentru a activa funcționalitățile experimentale, adăugați cuvântul cheie al "
"funcționalității la listă. Dacă funcționalitatea necesită sau nu repornirea "
"compunătorului depinde de funcționalitatea dată. Nu este necesar ca "
"funcționalitatea experimentală să fie încă disponibilă, sau configurabilă. "
"Nu vă așteptați să adăugați ceva la această configurare care va rezista "
"timpului. Cuvintele cheie posibile în mod curent: • “scale-monitor-"
"framebuffer” — face ca mutter să treacă implicit la aranjarea monitoarelor "
"logice într-un spațiu logic de coordonate pixel, în timpul scalării de "
"framebuffer-uri de monitor în locul conținutului ferestrei, pentru a "
"gestiona monitoare HiDPI. Nu necesită o repornire. • “remote-desktop” — "
"activează suportul pentru desktop la distanță. Pentru a suporta desktop la "
"distanță cu partajarea ecranului, trebuie să fie activat și „screen-cast”. • "
"“screen-cast” — activează suportul pentru înregistrarea ecranului."
#: data/org.gnome.mutter.gschema.xml.in:145
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
msgid "Select window from tab popup"
msgstr "Selectează fereastra din popup-ul tabului"
#: data/org.gnome.mutter.gschema.xml.in:150
#: ../data/org.gnome.mutter.gschema.xml.in.h:22
msgid "Cancel tab popup"
msgstr "Elimină popup-ul pentru tab"
#: data/org.gnome.mutter.gschema.xml.in:155
msgid "Switch monitor configurations"
msgstr "Comută configurațiile de monitor"
#: data/org.gnome.mutter.gschema.xml.in:160
msgid "Rotates the built-in monitor configuration"
msgstr "Rotește configurarea de monitor integrat"
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
msgid "Switch to VT 1"
msgstr "Comută la terminalul virtual 1"
#: data/org.gnome.mutter.wayland.gschema.xml.in:10
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
msgid "Switch to VT 2"
msgstr "Comută la terminalul virtual 2"
#: data/org.gnome.mutter.wayland.gschema.xml.in:14
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
msgid "Switch to VT 3"
msgstr "Comută la terminalul virtual 3"
#: data/org.gnome.mutter.wayland.gschema.xml.in:18
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
msgid "Switch to VT 4"
msgstr "Comută la terminalul virtual 4"
#: data/org.gnome.mutter.wayland.gschema.xml.in:22
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
msgid "Switch to VT 5"
msgstr "Comută la terminalul virtual 5"
#: data/org.gnome.mutter.wayland.gschema.xml.in:26
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
msgid "Switch to VT 6"
msgstr "Comută la terminalul virtual 6"
#: data/org.gnome.mutter.wayland.gschema.xml.in:30
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
msgid "Switch to VT 7"
msgstr "Comută la terminalul virtual 7"
#: data/org.gnome.mutter.wayland.gschema.xml.in:34
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
msgid "Switch to VT 8"
msgstr "Comută la terminalul virtual 8"
#: data/org.gnome.mutter.wayland.gschema.xml.in:38
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
msgid "Switch to VT 9"
msgstr "Comută la terminalul virtual 9"
#: data/org.gnome.mutter.wayland.gschema.xml.in:42
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
msgid "Switch to VT 10"
msgstr "Comută la terminalul virtual 10"
#: data/org.gnome.mutter.wayland.gschema.xml.in:46
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
msgid "Switch to VT 11"
msgstr "Comută la terminalul virtual 11"
#: data/org.gnome.mutter.wayland.gschema.xml.in:50
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
msgid "Switch to VT 12"
msgstr "Comută la terminalul virtual 12"
#: data/org.gnome.mutter.wayland.gschema.xml.in:54
msgid "Re-enable shortcuts"
msgstr "Reactivează scurtăturile"
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
msgid "Allow grabs with Xwayland"
msgstr "Permite capturi de tastatură cu Xwayland"
#: 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 ""
"Permite capturile de tastatură emise de aplicațiile X11 care rulează în "
"Xwayland să fie luate în considerare. Pentru ca o captură X11 să fie luată "
"în considerare în Wayland, clientul trebuie ori să trimită un mesaj specific "
"ClientMessage X11 la fereastra root ori să se numere printre aplicațiile "
"permise în cheia „xwayland-grab-access-rules”."
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
msgid "Xwayland applications allowed to issue keyboard grabs"
msgstr "Aplicațiile Xwayland sunt permise de a emite capturi de tastatură"
#: 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 ""
"Listează numele resurselor sau clasa resurselor ale ferestrelor X11 permise "
"sau nepermise să emită capturi de tastatură X11 în Xwayland. Numele resursei "
"sau clasa resursei a unei ferestre X11 date pot fi obținute utilizând "
"comanda „xprop WM_CLASS*. Metacaracterele „*” și jokerii „?” în valori sunt "
"suportați. Valorile care încep cu „!” sunt adăugate în lista de interziceri, "
"care are prioritate peste lista de permisiuni, pentru a revoca aplicații din "
"lista de sistem implicită. Lista de sistem implicită include următoarele "
"aplicații: „@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Utilizatorii pot să "
"întrerupă o captură existentă prin utilizarea scurtăturii de tastatură "
"specifice definite de tasta de stabilire a combinațiilor de taste „restore-"
"shortcuts”."
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2325
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Comutator de mod (grupul %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2348
msgid "Switch monitor"
msgstr "Comută monitorul"
#: src/backends/meta-input-settings.c:2350
msgid "Show on-screen help"
msgstr "Arată ajutorul virtual"
#: src/backends/meta-monitor-manager.c:903
#: ../src/backends/meta-monitor-manager.c:500
msgid "Built-in display"
msgstr "Afișaj integrat"
#: src/backends/meta-monitor-manager.c:926
#: ../src/backends/meta-monitor-manager.c:526
msgid "Unknown"
msgstr "Necunoscut"
#: src/backends/meta-monitor-manager.c:928
#: ../src/backends/meta-monitor-manager.c:528
msgid "Unknown Display"
msgstr "Afișaj necunoscut"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:936
#: ../src/backends/meta-monitor-manager.c:536
#, c-format
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:456
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr ""
"Un alt administrator de ferestre de compunere rulează deja pe ecranul %i pe "
"Un alt administrator de ferestre compozit rulează deja pe ecranul %i pe "
"afișajul „%s”."
#: src/core/bell.c:194
#: ../src/core/bell.c:185
msgid "Bell event"
msgstr "Eveniment sonor"
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "Nu s-a putut deschide afișajul sistemului de ferestre X „%s”\n"
#: src/core/main.c:190
msgid "Disable connection to session manager"
msgstr "Dezactivează conexiunea la administratorul de sesiune"
#: src/core/main.c:196
msgid "Replace the running window manager"
msgstr "Înlocuiește administratorul de ferestre curent"
#: src/core/main.c:202
msgid "Specify session management ID"
msgstr "Specifică ID-ul administrării de sesiune"
#: src/core/main.c:207
msgid "X Display to use"
msgstr "Ecranul X ce va fi folosit"
#: src/core/main.c:213
msgid "Initialize session from savefile"
msgstr "Inițializează sesiunea din fișierul salvat"
#: src/core/main.c:219
msgid "Make X calls synchronous"
msgstr "Realizează apelurile X sincron"
#: src/core/main.c:226
msgid "Run as a wayland compositor"
msgstr "Rulează ca un compunător wayland"
#: src/core/main.c:232
msgid "Run as a nested compositor"
msgstr "Rulează ca un compunător imbricat"
#: src/core/main.c:240
msgid "Run as a full display server, rather than nested"
msgstr "Rulează ca server de afișare și nu ca server imbricat"
#: src/core/main.c:246
msgid "Run with X11 backend"
msgstr "Rulează cu backend X11"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#: ../src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "„%s” nu răspunde."
#: src/core/meta-close-dialog-default.c:149
#: ../src/core/delete.c:129
msgid "Application is not responding."
msgstr "Aplicația nu răspunde."
#: src/core/meta-close-dialog-default.c:154
#: ../src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@@ -652,95 +517,112 @@ msgstr ""
"Puteți alege între a aștepta pentru câteva secunde ca aplicația să continue "
"sau a forța terminarea aplicației."
#: src/core/meta-close-dialog-default.c:161
msgid "_Force Quit"
msgstr "_Forțează închiderea"
#: src/core/meta-close-dialog-default.c:161
#: ../src/core/delete.c:141
msgid "_Wait"
msgstr "_Așteaptă"
#: src/core/mutter.c:39
#: ../src/core/delete.c:141
msgid "_Force Quit"
msgstr "_Forțează închiderea"
#: ../src/core/display.c:563
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Nu s-a putut deschide afișajul X Window System „%s”\n"
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
msgstr "Dezactivează conexiunea la administratorul de sesiune"
#: ../src/core/main.c:182
msgid "Replace the running window manager"
msgstr "Înlocuiește administratorul de ferestre curent"
#: ../src/core/main.c:188
msgid "Specify session management ID"
msgstr "Specifică ID-ul administrării de sesiune"
#: ../src/core/main.c:193
msgid "X Display to use"
msgstr "Ecranul X ce va fi folosit"
#: ../src/core/main.c:199
msgid "Initialize session from savefile"
msgstr "Inițializează sesiunea din fișierul salvat"
#: ../src/core/main.c:205
msgid "Make X calls synchronous"
msgstr "Realizează apelurile X sincron"
#: ../src/core/main.c:212
msgid "Run as a wayland compositor"
msgstr "Rulează ca compozitor wayland"
#: ../src/core/main.c:220
msgid "Run as a full display server, rather than nested"
msgstr "Rulează ca server de afișare și nu ca server imbricat"
#: ../src/core/mutter.c:39
#, c-format
msgid ""
"mutter %s\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Drepturi de autor (C) 2001-%d Havoc Pennington, Red Hat, Inc., și alții\n"
"Drepturi de autor (C) 2001--%d Havoc Pennington, Red Hat, Inc., și alții\n"
"Acesta este software liber; consultați codul sursă pentru condițiile de "
"copiere.\n"
"Nu există NICIO garanție; nici pentru COMERCIALIZARE sau UTILIZAREA ÎNTR-UN "
"Nu există NICI O garanție; nici pentru COMERCIALIZARE sau UTILIZAREA ÎNTR-UN "
"SCOP ANUME.\n"
#: src/core/mutter.c:53
#: ../src/core/mutter.c:53
msgid "Print version"
msgstr "Afișează versiunea"
#: src/core/mutter.c:59
#: ../src/core/mutter.c:59
msgid "Mutter plugin to use"
msgstr "Modul Mutter de utilizat"
#: src/core/prefs.c:1997
#: ../src/core/prefs.c:2050
#, c-format
msgid "Workspace %d"
msgstr "Spațiu de lucru %d"
#: src/core/screen.c:583
#: ../src/core/screen.c:526
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
"replace the current window manager."
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Afișajul „%s” are deja un administrator de ferestre; încercați să utilizați "
"Afișajul „%s” are deja un administrator de ferestre; încercați să folosiți "
"opțiunea --replace (înlocuiește) pentru a înlocui administratorul de "
"ferestre curent."
"ferestre actual."
#: src/core/screen.c:668
#: ../src/core/screen.c:608
#, c-format
msgid "Screen %d on display %s is invalid\n"
msgstr "Ecranul %d de pe afișajul „%s” nu este valid\n"
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Ecranul %d pe afișajul „%s” este invalid\n"
#: src/core/util.c:120
#: ../src/core/util.c:118
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter a fost compilat fără suport pentru modul detaliat\n"
#: src/wayland/meta-wayland-tablet-pad.c:567
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Comutator de mod: modul %d"
#: src/x11/session.c:1818
#: ../src/x11/session.c:1815
msgid ""
"These windows do not support save current setup and will have to be "
"restarted manually next time you log in."
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
msgstr ""
"Aceste ferestre nu suportă „salvează configurarea curentă” și vor trebui "
"repornite manual următoarea dată când vă veți autentifica."
#: src/x11/window-props.c:559
#: ../src/x11/window-props.c:549
#, c-format
msgid "%s (on %s)"
msgstr "%s (pe %s)"
#~ msgid "Move window one workspace to the left"
#~ msgstr "Mută fereastra pe spațiul de lucru de la stânga"
#~ msgid "Move window one workspace to the right"
#~ msgstr "Mută fereastra pe spațiul de lucru de la dreapta"
#~ msgid "Move to workspace left"
#~ msgstr "Mută pe spațiul de lucru din stânga"
#~ msgid "Move to workspace right"
#~ msgstr "Mută pe spațiul de lucru din dreapta"
#~ msgid "Toggle shaded state"
#~ msgstr "Comută starea de umbrire"
#~ msgid "Switch to workspace on the left of the current workspace"
#~ msgstr "Schimbă cu spațiul de lucru din stânga celui actual"

View File

@@ -1,6 +1,6 @@
# translation of mutter.po to zh_CN
# Simplified Chinese translation of mutter.
# Copyright (C) 2012-2018 mutter's COPYRIGHT HOLDER
# This file is distributed under the same license as the mutter package.
# Copyright (C) 2002, 2003, 2004, 2009, 2010 Free Software Foundation, Inc.
# Sun G11n <gnome_int_l10n@ireland.sun.com>, 2002.
# He Qiangqiang <carton@linux.net.cn>, 2002
# Xiong Jiang <jxiong@offtopic.org>, 2003
@@ -11,24 +11,22 @@
# Lele Long <schemacs@gmail.com>, 2011.
# YunQiang Su <wzssyqa@gmail.com>, 2011, 2012.
# Tong Hui <tonghuix@gmail.com>, 2014.
# Mandy Wang <wangmychn@gmail.com>, 2017.
# Mingcong Bai <jeffbai@aosc.xyz>, 2017.
# Dingzhong Chen <wsxy162@gmail.com>, 2017, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2018-02-09 13:01+0000\n"
"PO-Revision-Date: 2018-02-16 22:22+0800\n"
"Last-Translator: Dingzhong Chen <wsxy162@gmail.com>\n"
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-02-03 10:06+0000\n"
"PO-Revision-Date: 2017-01-04 21:52+0800\n"
"Last-Translator: Mandy Wang <wangmychn@gmail.com>\n"
"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Gtranslator 2.91.7\n"
"X-Generator: Poedit 1.8.7.1\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@@ -55,118 +53,134 @@ msgid "Move window to last workspace"
msgstr "将窗口移到最后一个工作区"
#: data/50-mutter-navigation.xml:24
msgid "Move window one workspace to the left"
msgstr "将窗口左移一个工作区"
#: data/50-mutter-navigation.xml:27
msgid "Move window one workspace to the right"
msgstr "将窗口右移一个工作区"
#: data/50-mutter-navigation.xml:30
msgid "Move window one workspace up"
msgstr "将窗口上移一个工作区"
#: data/50-mutter-navigation.xml:27
#: data/50-mutter-navigation.xml:33
msgid "Move window one workspace down"
msgstr "将窗口下移一个工作区"
#: data/50-mutter-navigation.xml:30
#: data/50-mutter-navigation.xml:36
msgid "Move window one monitor to the left"
msgstr "将窗口左移一个显示器"
#: data/50-mutter-navigation.xml:33
#: data/50-mutter-navigation.xml:39
msgid "Move window one monitor to the right"
msgstr "将窗口右移一个显示器"
#: data/50-mutter-navigation.xml:36
#: data/50-mutter-navigation.xml:42
msgid "Move window one monitor up"
msgstr "将窗口上移一个显示器"
#: data/50-mutter-navigation.xml:39
#: data/50-mutter-navigation.xml:45
msgid "Move window one monitor down"
msgstr "将窗口下移一个显示器"
#: data/50-mutter-navigation.xml:43
#: data/50-mutter-navigation.xml:49
msgid "Switch applications"
msgstr "切换应用程序"
#: data/50-mutter-navigation.xml:48
#: data/50-mutter-navigation.xml:54
msgid "Switch to previous application"
msgstr "切换到前一个应用程序"
#: data/50-mutter-navigation.xml:52
#: data/50-mutter-navigation.xml:58
msgid "Switch windows"
msgstr "切换窗口"
#: data/50-mutter-navigation.xml:57
#: data/50-mutter-navigation.xml:63
msgid "Switch to previous window"
msgstr "切换到前一个窗口"
#: data/50-mutter-navigation.xml:61
#: data/50-mutter-navigation.xml:67
msgid "Switch windows of an application"
msgstr "在应用程序的窗口之间切换窗口"
#: data/50-mutter-navigation.xml:66
#: data/50-mutter-navigation.xml:72
msgid "Switch to previous window of an application"
msgstr "切换到一个应用程序的前一个窗口"
#: data/50-mutter-navigation.xml:70
#: data/50-mutter-navigation.xml:76
msgid "Switch system controls"
msgstr "切换系统控制"
#: data/50-mutter-navigation.xml:75
#: data/50-mutter-navigation.xml:81
msgid "Switch to previous system control"
msgstr "切换到前一个系统控制"
#: data/50-mutter-navigation.xml:79
#: data/50-mutter-navigation.xml:85
msgid "Switch windows directly"
msgstr "直接切换窗口"
#: data/50-mutter-navigation.xml:84
#: data/50-mutter-navigation.xml:90
msgid "Switch directly to previous window"
msgstr "直接切换到前一个窗口"
#: data/50-mutter-navigation.xml:88
#: data/50-mutter-navigation.xml:94
msgid "Switch windows of an app directly"
msgstr "在应用程序窗口间直接移动焦点"
#: data/50-mutter-navigation.xml:93
#: data/50-mutter-navigation.xml:99
msgid "Switch directly to previous window of an app"
msgstr "直接切换到一个应用程序的前一个窗口"
#: data/50-mutter-navigation.xml:97
#: data/50-mutter-navigation.xml:103
msgid "Switch system controls directly"
msgstr "直接切换系统控制"
#: data/50-mutter-navigation.xml:102
#: data/50-mutter-navigation.xml:108
msgid "Switch directly to previous system control"
msgstr "直接切换到前一个系统控制"
#: data/50-mutter-navigation.xml:105
#: data/50-mutter-navigation.xml:111
msgid "Hide all normal windows"
msgstr "隐藏所有正常窗口"
#: data/50-mutter-navigation.xml:108
#: data/50-mutter-navigation.xml:114
msgid "Switch to workspace 1"
msgstr "切换到工作区 1"
#: data/50-mutter-navigation.xml:111
#: data/50-mutter-navigation.xml:117
msgid "Switch to workspace 2"
msgstr "切换到工作区 2"
#: data/50-mutter-navigation.xml:114
#: data/50-mutter-navigation.xml:120
msgid "Switch to workspace 3"
msgstr "切换到工作区 3"
#: data/50-mutter-navigation.xml:117
#: data/50-mutter-navigation.xml:123
msgid "Switch to workspace 4"
msgstr "切换到工作区 4"
#: data/50-mutter-navigation.xml:120
#: data/50-mutter-navigation.xml:126
msgid "Switch to last workspace"
msgstr "切换到最后一个工作区"
#: data/50-mutter-navigation.xml:123
#: data/50-mutter-navigation.xml:129
msgid "Move to workspace left"
msgstr "移动到左侧工作区"
#: data/50-mutter-navigation.xml:132
msgid "Move to workspace right"
msgstr "移动到右侧工作区"
#: data/50-mutter-navigation.xml:135
msgid "Move to workspace above"
msgstr "移动到上层工作区"
#: data/50-mutter-navigation.xml:126
#: data/50-mutter-navigation.xml:138
msgid "Move to workspace below"
msgstr "移动到下层工作区"
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
#: data/50-mutter-system.xml:6
msgid "System"
msgstr "系统"
@@ -176,11 +190,7 @@ 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 "还原键盘快捷键"
msgstr "显示活动大纲"
#: data/50-mutter-windows.xml:6
msgid "Windows"
@@ -207,50 +217,54 @@ msgid "Restore window"
msgstr "恢复窗口"
#: data/50-mutter-windows.xml:18
msgid "Toggle shaded state"
msgstr "切换卷起状态"
#: data/50-mutter-windows.xml:20
msgid "Close window"
msgstr "关闭窗口"
#: data/50-mutter-windows.xml:20
#: data/50-mutter-windows.xml:22
msgid "Hide window"
msgstr "隐藏窗口"
#: data/50-mutter-windows.xml:22
#: data/50-mutter-windows.xml:24
msgid "Move window"
msgstr "移动窗口"
#: data/50-mutter-windows.xml:24
#: data/50-mutter-windows.xml:26
msgid "Resize window"
msgstr "改变窗口大小"
#: data/50-mutter-windows.xml:27
#: data/50-mutter-windows.xml:29
msgid "Toggle window on all workspaces or one"
msgstr "在位于所有或仅一个工作区的窗口间切换"
#: data/50-mutter-windows.xml:29
#: data/50-mutter-windows.xml:31
msgid "Raise window if covered, otherwise lower it"
msgstr "如果窗口被其他窗口遮盖,则提升它,否则降低它"
#: data/50-mutter-windows.xml:31
#: data/50-mutter-windows.xml:33
msgid "Raise window above other windows"
msgstr "将窗口提升到其它窗口之上"
#: data/50-mutter-windows.xml:33
#: data/50-mutter-windows.xml:35
msgid "Lower window below other windows"
msgstr "将窗口降低到其它窗口之下"
#: data/50-mutter-windows.xml:35
#: data/50-mutter-windows.xml:37
msgid "Maximize window vertically"
msgstr "垂直最大化窗口"
#: data/50-mutter-windows.xml:37
#: data/50-mutter-windows.xml:39
msgid "Maximize window horizontally"
msgstr "水平最大化窗口"
#: data/50-mutter-windows.xml:41
#: data/50-mutter-windows.xml:43
msgid "View split on left"
msgstr "在左侧查看分割"
#: data/50-mutter-windows.xml:45
#: data/50-mutter-windows.xml:47
msgid "View split on right"
msgstr "在右侧查看分割"
@@ -264,10 +278,10 @@ msgstr "用于修改窗口点击动作的修饰键 met"
#: 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."
"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. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
"这个键指出的“覆盖”是一种混合窗口概述和应用程序运行的系统。默认要求使用 "
"“Super 键”。可能使用默认或者空白。"
@@ -304,12 +318,12 @@ msgstr "动态管理工作区"
#: data/org.gnome.mutter.gschema.xml.in:41
msgid ""
"Determines whether workspaces are managed dynamically or whether theres a "
"Determines whether workspaces are managed dynamically or whether there's a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
"决定工作区动态管理还是静态数量的工作区由 org.gnome.desktop.wm.preferences "
"的 num-workspaces 键确定。"
"决定工作区动态管理还是静态数量的工作区(由 org.gnome.desktop.wm.preferences "
"的 num-workspaces 键确定)。"
# 或者 只在主显示器上显示工作区
#: data/org.gnome.mutter.gschema.xml.in:50
@@ -339,9 +353,9 @@ 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."
"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 ""
"如果为 true而聚焦模式为“sloppy”或“mouse”那么进入某个窗口时焦点将不会立即"
"改变,而是等到光标停止移动之后。"
@@ -352,7 +366,7 @@ msgstr "可拖拽的边界宽度"
#: data/org.gnome.mutter.gschema.xml.in:80
msgid ""
"The amount of total draggable borders. If the themes visible borders are "
"The amount of total draggable borders. If the theme's visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
"可拖拽的边界总数。如果主题的可见边界不足,将添加不可见的边界来满足此值。"
@@ -377,50 +391,14 @@ msgid ""
"screen of the monitor."
msgstr "为 true 时,新窗口将总是置于此显示器已激活屏幕的中央。"
#: 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. • “remote-desktop” — "
"enables remote desktop support. To support remote desktop with screen "
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
"screen cast support."
msgstr ""
"要启用实验性特性,请将如下特性关键字添加到列表中。特性是否要求重启合成器取决"
"于特性本身。实验性特性不需启用即可配置和使用。请不要将实验性特性作为未来保障"
"的基础。当前可用的关键字:• “monitor-config-manager” — 使用新的监视器配置系"
"统,用于替代老的系统。启用此特性将打开一个上级配置 API 以用于配置应用程序,并"
"可提供基于每屏幕的逻辑缩放功能。• “scale-monitor-framebuffer” — 让 Mutter 默"
"认基于像素座标排布多屏幕,并同时缩放监视器帧缓冲器而不是窗口内容,以便管理 "
"HiDPI 监视器。该特性不需要重启来生效。• “remote-desktop” — 启用远程桌面支持。"
"要支持远程桌面共享还需要设置“screen-cast”。 • “screen-cast” — 启用屏幕广播"
"支持。"
#: data/org.gnome.mutter.gschema.xml.in:145
#: data/org.gnome.mutter.gschema.xml.in:120
msgid "Select window from tab popup"
msgstr "从 Tab 轮换弹出界面选择窗口"
#: data/org.gnome.mutter.gschema.xml.in:150
#: data/org.gnome.mutter.gschema.xml.in:125
msgid "Cancel tab popup"
msgstr "取消 Tab 轮换弹出"
#: data/org.gnome.mutter.gschema.xml.in:155
msgid "Switch monitor configurations"
msgstr "切换显示器配置"
#: data/org.gnome.mutter.gschema.xml.in:160
msgid "Rotates the built-in monitor configuration"
msgstr "旋转内置显示器配置"
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
msgid "Switch to VT 1"
msgstr "切换到 VT 1"
@@ -469,183 +447,127 @@ msgstr "切换到 VT 11"
msgid "Switch to VT 12"
msgstr "切换到 VT 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 "允许用 Xwayland 捕获"
#: 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 ""
"允许考虑运行在 Xwayland 中的 X11 应用程序发起的键盘捕获。在 Wayland 下,为了"
"将 X11 捕获考虑在内,客户端也必须发送一个指定的 X11 ClientMessage 到根窗口,"
"或是包含进“xwayland-grab-access-rules”键成为其中一个白名单应用程序。"
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
msgid "Xwayland applications allowed to issue keyboard grabs"
msgstr "允许发起键盘捕获的 Xwayland 应用程序"
#: 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 ""
"Xwayland 下允许或不允许发起 X11 键盘捕获的 X11 窗口,其资源名或资源类的列表。"
"给定 X11 窗口的资源名或资源类可以使用“xprop WM_CLASS”命令获取。支持在键值中使"
"用通配符“*”和“?”。以“!”开头的键值会列入黑名单,它们的优先级高于白名单,用来撤"
"销默认系统列表中的应用程序。默认系统列表包含了下列应用程"
"序:“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” 用户可以使用键绑定键“restore-"
"shortcuts”定义的键盘快捷键来中断进行中的捕获。"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2260
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "模式切换(组别 %d"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2283
#: src/backends/meta-input-settings.c:1861
msgid "Switch monitor"
msgstr "切换显示器"
#: src/backends/meta-input-settings.c:2285
#: src/backends/meta-input-settings.c:1863
msgid "Show on-screen help"
msgstr "显示在屏帮助"
#: src/backends/meta-monitor-manager.c:900
#: src/backends/meta-monitor-manager.c:515
msgid "Built-in display"
msgstr "内置显示器"
#: src/backends/meta-monitor-manager.c:923
#: src/backends/meta-monitor-manager.c:538
msgid "Unknown"
msgstr "未知"
#: src/backends/meta-monitor-manager.c:925
#: src/backends/meta-monitor-manager.c:540
msgid "Unknown Display"
msgstr "未知的 Display"
#. 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:548
#, c-format
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:471
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr "显示器 %2$s 的屏幕 %1$i 上已有另外一个混成窗口管理器正在运行。"
#: src/core/bell.c:194
msgid "Bell event"
msgstr "响铃事件"
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "无法打开 X Window System 显示器“%s”\n"
#: src/core/main.c:190
msgid "Disable connection to session manager"
msgstr "禁止连接到会话管理器"
#: src/core/main.c:196
msgid "Replace the running window manager"
msgstr "替换正在运行的窗口管理器"
#: src/core/main.c:202
msgid "Specify session management ID"
msgstr "指定会话管理 ID"
#: src/core/main.c:207
msgid "X Display to use"
msgstr "要使用的 X Display"
#: src/core/main.c:213
msgid "Initialize session from savefile"
msgstr "从保存文件中初始化会话"
#: src/core/main.c:219
msgid "Make X calls synchronous"
msgstr "使 X 调用同步"
#: src/core/main.c:226
msgid "Run as a wayland compositor"
msgstr "作为 wayland 混成管理器运行"
#: src/core/main.c:232
msgid "Run as a nested compositor"
msgstr "作为嵌套混成器运行"
#: src/core/main.c:240
msgid "Run as a full display server, rather than nested"
msgstr "以完整显示服务器方式运行,而不是以嵌套方式"
#: src/core/main.c:246
msgid "Run with X11 backend"
msgstr "以 X11 后端运行"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#: src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "“%s” 未响应。"
#: src/core/meta-close-dialog-default.c:149
#: src/core/delete.c:129
msgid "Application is not responding."
msgstr "应用程序未响应。"
#: src/core/meta-close-dialog-default.c:154
#: src/core/delete.c:134
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/delete.c:141
msgid "_Wait"
msgstr "等待(_W)"
#: src/core/delete.c:141
msgid "_Force Quit"
msgstr "强制退出(_F)"
#: src/core/meta-close-dialog-default.c:161
msgid "_Wait"
msgstr "等待(_W)"
#: src/core/display.c:590
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "无法打开 X Window System 显示器“%s”\n"
#: src/core/main.c:182
msgid "Disable connection to session manager"
msgstr "禁止连接到会话管理器"
#: src/core/main.c:188
msgid "Replace the running window manager"
msgstr "替换正在运行的窗口管理器"
#: src/core/main.c:194
msgid "Specify session management ID"
msgstr "指定会话管理 ID"
#: src/core/main.c:199
msgid "X Display to use"
msgstr "要使用的 X Display"
#: src/core/main.c:205
msgid "Initialize session from savefile"
msgstr "从保存文件中初始化会话"
#: src/core/main.c:211
msgid "Make X calls synchronous"
msgstr "使 X 调用同步"
#: src/core/main.c:218
msgid "Run as a wayland compositor"
msgstr "作为 wayland 混成管理器运行"
#: src/core/main.c:224
msgid "Run as a nested compositor"
msgstr "作为嵌套混成器运行"
#: src/core/main.c:232
msgid "Run as a full display server, rather than nested"
msgstr "以完整显示服务器方式运行,而不是以嵌套方式"
#: src/core/mutter.c:39
#, c-format
msgid ""
"mutter %s\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., 以及其他\n"
"本软件为自由软件版权条款请参见源码\n"
"不存在任何保证即便是对商业性或者特定目的的适应性也不作保证。\n"
"版权所有 (C) 2001-%d Havoc Pennington, Red Hat, Inc., 以及其他\n"
"本软件为自由软件版权条款请参见源码\n"
"不存在任何保证即便是对商业性或者特定目的的适应性也不作保证。\n"
#: src/core/mutter.c:53
msgid "Print version"
@@ -660,54 +582,41 @@ msgstr "要使用的 Mutter 插件"
msgid "Workspace %d"
msgstr "工作区 %d"
#: src/core/screen.c:583
#: src/core/screen.c:521
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
"replace the current window manager."
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Display“%s”已经有一个窗口管理器请尝试使用 --replace 选项替换当前的窗口管理"
"器。"
#: src/core/screen.c:668
#: src/core/screen.c:606
#, c-format
msgid "Screen %d on display %s is invalid\n"
msgid "Screen %d on display '%s' is invalid\n"
msgstr "显示“%2$s”上的屏幕 %1$d 无效\n"
#: src/core/util.c:120
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter 编译的时候没有加入详细模式的支持\n"
#: src/wayland/meta-wayland-tablet-pad.c:567
#: src/wayland/meta-wayland-tablet-pad.c:595
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "模式切换:%d 模式"
#: src/x11/session.c:1818
#: src/x11/session.c:1815
msgid ""
"These windows do not support save current setup and will have to be "
"restarted manually next time you log in."
msgstr "这些窗口不支持“保存当前设置”,并且在您下次登录时,必须手动重启它们。"
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
msgstr ""
"这些窗口不支持 &quot;保存当前设置 &quot; 您在下次登录时,必须手动重启动它"
"们。"
#: src/x11/window-props.c:559
#: src/x11/window-props.c:548
#, c-format
msgid "%s (on %s)"
msgstr "%s于 %s"
#~ msgid "Move window one workspace to the left"
#~ msgstr "将窗口左移一个工作区"
#~ msgid "Move window one workspace to the right"
#~ msgstr "将窗口右移一个工作区"
#~ msgid "Move to workspace left"
#~ msgstr "移动到左侧工作区"
#~ msgid "Move to workspace right"
#~ msgstr "移动到右侧工作区"
#~ msgid "Toggle shaded state"
#~ msgstr "切换卷起状态"
msgstr "%s (于 %s)"
#~ msgid "Failed to scan themes directory: %s\n"
#~ msgstr "扫描主题目录失败:%s\n"

View File

@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: metacity 3.3.4\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2018-06-07 13:00+0000\n"
"PO-Revision-Date: 2018-06-09 11:26+0800\n"
"POT-Creation-Date: 2018-03-01 18:57+0000\n"
"PO-Revision-Date: 2018-03-03 15:20+0800\n"
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
"Language: zh_TW\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 2.0.8\n"
"X-Generator: Poedit 2.0.6\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@@ -379,27 +379,32 @@ msgid ""
"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."
"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — "
"enables remote desktop support. To support remote desktop with screen "
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
"screen cast support."
msgstr ""
"若要啟用實驗性功能,請將功能關鍵字加入列表中。置於該功能是否須要重新啟動混成"
"器則視給予的功能而定。任何實驗性功能不一定能用、或是可以調整設定。請不要預期"
"在此設定中加入的任何東西未來都能存在。目前可用的關鍵字有: • “scale-monitor-"
"framebuffer” — 讓 mutter 預設採用邏輯像素座標空間的配置邏輯螢幕,而縮放螢幕 "
"framebuffer 則取代視窗內容以管理 HiDPI 螢幕。不須要重新啟動。"
"framebuffer 則取代視窗內容以管理 HiDPI 螢幕。不須要重新啟動。 • “remote-"
"desktop” — 啟用遠端桌面支援。若要支援遠端桌面的螢幕分享則必須也啟用“screen-"
"cast”。• “screen-cast” — 啟用螢幕投放支援。"
#: data/org.gnome.mutter.gschema.xml.in:141
#: data/org.gnome.mutter.gschema.xml.in:145
msgid "Select window from tab popup"
msgstr "從分頁彈出項選擇視窗"
#: data/org.gnome.mutter.gschema.xml.in:146
#: data/org.gnome.mutter.gschema.xml.in:150
msgid "Cancel tab popup"
msgstr "取消分頁彈出項"
#: data/org.gnome.mutter.gschema.xml.in:151
#: data/org.gnome.mutter.gschema.xml.in:155
msgid "Switch monitor configurations"
msgstr "切換螢幕組態"
#: data/org.gnome.mutter.gschema.xml.in:156
#: data/org.gnome.mutter.gschema.xml.in:160
msgid "Rotates the built-in monitor configuration"
msgstr "旋轉切換內建螢幕組態"
@@ -515,22 +520,22 @@ msgstr "切換螢幕"
msgid "Show on-screen help"
msgstr "顯示螢幕求助"
#: src/backends/meta-monitor-manager.c:903
#: src/backends/meta-monitor-manager.c:900
msgid "Built-in display"
msgstr "內建顯示"
#: src/backends/meta-monitor-manager.c:926
#: src/backends/meta-monitor-manager.c:923
msgid "Unknown"
msgstr "不明"
#: src/backends/meta-monitor-manager.c:928
#: src/backends/meta-monitor-manager.c:925
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:936
#: src/backends/meta-monitor-manager.c:933
#, c-format
msgid "%s %s"
msgstr "%s %s"

View File

@@ -14,6 +14,7 @@ stackingdir = $(pkgdatadir)/tests/stacking
dist_stacking_DATA = \
tests/stacking/basic-x11.metatest \
tests/stacking/basic-wayland.metatest \
tests/stacking/closed-transient.metatest \
tests/stacking/minimized.metatest \
tests/stacking/mixed-windows.metatest \
tests/stacking/set-parent.metatest \

View File

@@ -418,6 +418,28 @@ meta_backend_create_input_settings (MetaBackend *backend)
return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend);
}
#ifdef HAVE_REMOTE_DESKTOP
static gboolean
is_screen_cast_enabled (MetaBackend *backend)
{
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCREEN_CAST);
}
static gboolean
is_remote_desktop_enabled (MetaBackend *backend)
{
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP);
}
#endif /* HAVE_REMOTE_DESKTOP */
static void
meta_backend_real_post_init (MetaBackend *backend)
{
@@ -451,8 +473,10 @@ meta_backend_real_post_init (MetaBackend *backend)
#ifdef HAVE_REMOTE_DESKTOP
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
priv->screen_cast = meta_screen_cast_new (priv->dbus_session_watcher);
priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher);
if (is_screen_cast_enabled (backend))
priv->screen_cast = meta_screen_cast_new (priv->dbus_session_watcher);
if (is_remote_desktop_enabled (backend))
priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher);
#endif /* HAVE_REMOTE_DESKTOP */
if (!meta_monitor_manager_is_headless (priv->monitor_manager))
@@ -544,6 +568,26 @@ meta_backend_class_init (MetaBackendClass *klass)
stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
}
static void
experimental_features_changed (MetaSettings *settings,
MetaExperimentalFeature old_experimental_features,
MetaBackend *backend)
{
#ifdef HAVE_REMOTE_DESKTOP
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
if (is_screen_cast_enabled (backend) && !priv->screen_cast)
priv->screen_cast = meta_screen_cast_new (priv->dbus_session_watcher);
else if (!is_screen_cast_enabled (backend))
g_clear_object (&priv->screen_cast);
if (is_remote_desktop_enabled (backend) && !priv->remote_desktop)
priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher);
else if (!is_remote_desktop_enabled (backend))
g_clear_object (&priv->remote_desktop);
#endif /* HAVE_REMOTE_DESKTOP */
}
static MetaMonitorManager *
meta_backend_create_monitor_manager (MetaBackend *backend,
GError **error)
@@ -626,6 +670,9 @@ meta_backend_initable_init (GInitable *initable,
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->settings = meta_settings_new (backend);
g_signal_connect (priv->settings, "experimental-features-changed",
G_CALLBACK (experimental_features_changed),
backend);
priv->egl = g_object_new (META_TYPE_EGL, NULL);

View File

@@ -263,8 +263,11 @@ meta_idle_monitor_init (MetaIdleMonitor *monitor)
v = g_dbus_proxy_get_cached_property (monitor->session_proxy,
"InhibitedActions");
monitor->inhibited = g_variant_get_uint32 (v) & GSM_INHIBITOR_FLAG_IDLE;
g_variant_unref (v);
if (v)
{
monitor->inhibited = g_variant_get_uint32 (v) & GSM_INHIBITOR_FLAG_IDLE;
g_variant_unref (v);
}
}
/**

View File

@@ -100,11 +100,12 @@ static MetaMonitorTransform
derive_monitor_transform (MetaMonitor *monitor)
{
MetaOutput *main_output;
MetaMonitorTransform transform;
main_output = meta_monitor_get_main_output (monitor);
transform = meta_output_get_assigned_crtc (main_output)->transform;
return meta_monitor_crtc_to_logical_transform (monitor,
main_output->crtc->transform);
return meta_monitor_crtc_to_logical_transform (monitor, transform);
}
MetaLogicalMonitor *
@@ -145,7 +146,7 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
is_presentation = logical_monitor->is_presentation;
logical_monitor->monitors = g_list_append (logical_monitor->monitors,
monitor);
g_object_ref (monitor));
for (l = logical_monitor->monitors; l; l = l->next)
{
@@ -157,10 +158,12 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
for (l_output = outputs; l_output; l_output = l_output->next)
{
MetaOutput *output = l_output->data;
MetaCrtc *crtc;
is_presentation = is_presentation && output->is_presentation;
if (output->crtc)
output->crtc->logical_monitor = logical_monitor;
crtc = meta_output_get_assigned_crtc (output);
if (crtc)
crtc->logical_monitor = logical_monitor;
}
}
@@ -220,7 +223,7 @@ foreach_crtc (MetaMonitor *monitor,
ForeachCrtcData *data = user_data;
data->func (data->logical_monitor,
monitor_crtc_mode->output->crtc,
meta_output_get_assigned_crtc (monitor_crtc_mode->output),
data->user_data);
return TRUE;
@@ -254,13 +257,17 @@ meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor)
}
static void
meta_logical_monitor_finalize (GObject *object)
meta_logical_monitor_dispose (GObject *object)
{
MetaLogicalMonitor *logical_monitor = META_LOGICAL_MONITOR (object);
g_list_free (logical_monitor->monitors);
if (logical_monitor->monitors)
{
g_list_free_full (logical_monitor->monitors, g_object_unref);
logical_monitor->monitors = NULL;
}
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->finalize (object);
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->dispose (object);
}
static void
@@ -268,7 +275,7 @@ meta_logical_monitor_class_init (MetaLogicalMonitorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_logical_monitor_finalize;
object_class->dispose = meta_logical_monitor_dispose;
}
gboolean

View File

@@ -486,7 +486,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
}
}
}
@@ -531,7 +531,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}
}

View File

@@ -181,6 +181,7 @@ struct _MetaMonitorManager
GnomePnpIds *pnp_ids;
UpClient *up_client;
gboolean lid_is_closed;
gulong experimental_features_changed_handler_id;

View File

@@ -351,7 +351,13 @@ lid_is_closed_changed (UpClient *client,
gpointer user_data)
{
MetaMonitorManager *manager = user_data;
gboolean lid_is_closed;
lid_is_closed = up_client_get_lid_is_closed (manager->up_client);
if (lid_is_closed == manager->lid_is_closed)
return;
manager->lid_is_closed = lid_is_closed;
meta_monitor_manager_lid_is_closed_changed (manager);
}
@@ -361,7 +367,7 @@ meta_monitor_manager_real_is_lid_closed (MetaMonitorManager *manager)
if (!manager->up_client)
return FALSE;
return up_client_get_lid_is_closed (manager->up_client);
return manager->lid_is_closed;
}
gboolean
@@ -585,6 +591,8 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
&error))
{
g_clear_object (&config);
g_warning ("Failed to use linear monitor configuration: %s",
error->message);
g_clear_error (&error);
}
else
@@ -602,6 +610,8 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
&error))
{
g_clear_object (&config);
g_warning ("Failed to use fallback monitor configuration: %s",
error->message);
g_clear_error (&error);
}
else
@@ -729,8 +739,12 @@ meta_monitor_manager_constructed (GObject *object)
if (manager_class->is_lid_closed == meta_monitor_manager_real_is_lid_closed)
{
manager->up_client = up_client_new ();
g_signal_connect_object (manager->up_client, "notify::lid-is-closed",
G_CALLBACK (lid_is_closed_changed), manager, 0);
if (manager->up_client)
{
g_signal_connect_object (manager->up_client, "notify::lid-is-closed",
G_CALLBACK (lid_is_closed_changed), manager, 0);
manager->lid_is_closed = up_client_get_lid_is_closed (manager->up_client);
}
}
g_signal_connect_object (manager, "notify::power-save-mode",
@@ -1041,6 +1055,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GVariantBuilder crtcs, modes, clones, properties;
GBytes *edid;
char *edid_file;
MetaCrtc *crtc;
int crtc_index;
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
@@ -1134,8 +1149,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
output->tile_info.tile_h));
}
crtc_index = output->crtc ? g_list_index (combined_crtcs, output->crtc)
: -1;
crtc = meta_output_get_assigned_crtc (output);
crtc_index = crtc ? g_list_index (combined_crtcs, crtc) : -1;
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
i, /* ID */
(gint64)output->winsys_id,
@@ -1318,9 +1333,13 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
GVariantBuilder mode_properties_builder;
MetaCrtcModeFlag mode_flags;
if (!meta_monitor_mode_should_be_advertised (monitor_mode))
continue;
mode_id = meta_monitor_mode_get_id (monitor_mode);
meta_monitor_mode_get_resolution (monitor_mode,
&mode_width, &mode_height);
refresh_rate = meta_monitor_mode_get_refresh_rate (monitor_mode);
preferred_scale =
@@ -2903,11 +2922,7 @@ meta_monitor_manager_get_monitor_for_connector (MetaMonitorManager *manager,
if (meta_monitor_is_active (monitor) &&
g_str_equal (connector, meta_monitor_get_connector (monitor)))
{
MetaOutput *main_output = meta_monitor_get_main_output (monitor);
return main_output->crtc->logical_monitor->number;
}
return meta_monitor_get_logical_monitor (monitor)->number;
}
return -1;

View File

@@ -203,11 +203,9 @@ meta_monitor_get_main_output (MetaMonitor *monitor)
gboolean
meta_monitor_is_active (MetaMonitor *monitor)
{
MetaOutput *output;
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
output = meta_monitor_get_main_output (monitor);
return output->crtc && output->crtc->current_mode;
return !!priv->current_mode;
}
gboolean
@@ -385,6 +383,21 @@ meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor,
return new_transform;
}
static void
meta_monitor_dispose (GObject *object)
{
MetaMonitor *monitor = META_MONITOR (object);
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
if (priv->outputs)
{
g_list_free_full (priv->outputs, g_object_unref);
priv->outputs = NULL;
}
G_OBJECT_CLASS (meta_monitor_parent_class)->dispose (object);
}
static void
meta_monitor_finalize (GObject *object)
{
@@ -393,7 +406,6 @@ meta_monitor_finalize (GObject *object)
g_hash_table_destroy (priv->mode_ids);
g_list_free_full (priv->modes, (GDestroyNotify) meta_monitor_mode_free);
g_clear_pointer (&priv->outputs, g_list_free);
meta_monitor_spec_free (priv->spec);
G_OBJECT_CLASS (meta_monitor_parent_class)->finalize (object);
@@ -412,6 +424,7 @@ meta_monitor_class_init (MetaMonitorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_monitor_dispose;
object_class->finalize = meta_monitor_finalize;
}
@@ -493,6 +506,7 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
for (i = 0; i < output->n_modes; i++)
{
MetaCrtcMode *crtc_mode = output->modes[i];
MetaCrtc *crtc;
MetaMonitorMode *mode;
gboolean replace;
@@ -526,7 +540,9 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
if (crtc_mode == output->preferred_mode)
monitor_priv->preferred_mode = mode;
if (output->crtc && crtc_mode == output->crtc->current_mode)
crtc = meta_output_get_assigned_crtc (output);
if (crtc && crtc_mode == crtc->current_mode)
monitor_priv->current_mode = mode;
}
}
@@ -545,7 +561,7 @@ meta_monitor_normal_new (MetaGpu *gpu,
monitor_priv->gpu = gpu;
monitor_priv->outputs = g_list_append (NULL, output);
monitor_priv->outputs = g_list_append (NULL, g_object_ref (output));
monitor_priv->winsys_id = output->winsys_id;
meta_monitor_generate_spec (monitor);
@@ -568,13 +584,15 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
MetaOutput *output;
MetaCrtc *crtc;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
*layout = (MetaRectangle) {
.x = output->crtc->rect.x,
.y = output->crtc->rect.y,
.width = output->crtc->rect.width,
.height = output->crtc->rect.height
.x = crtc->rect.x,
.y = crtc->rect.y,
.width = crtc->rect.width,
.height = crtc->rect.height
};
}
@@ -658,7 +676,8 @@ add_tiled_monitor_outputs (MetaGpu *gpu,
g_warn_if_fail (output->subpixel_order ==
monitor_tiled->origin_output->subpixel_order);
monitor_priv->outputs = g_list_append (monitor_priv->outputs, output);
monitor_priv->outputs = g_list_append (monitor_priv->outputs,
g_object_ref (output));
}
}
@@ -764,12 +783,13 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
{
MetaOutput *output = l->data;
MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
MetaCrtc *crtc;
crtc = meta_output_get_assigned_crtc (output);
if (monitor_crtc_mode->crtc_mode &&
(!output->crtc ||
output->crtc->current_mode != monitor_crtc_mode->crtc_mode))
(!crtc || crtc->current_mode != monitor_crtc_mode->crtc_mode))
return FALSE;
else if (!monitor_crtc_mode->crtc_mode && output->crtc)
else if (!monitor_crtc_mode->crtc_mode && crtc)
return FALSE;
}
@@ -1217,14 +1237,16 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
for (l = monitor_priv->outputs; l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *crtc;
if (!output->crtc)
crtc = meta_output_get_assigned_crtc (output);
if (!crtc)
continue;
min_x = MIN (output->crtc->rect.x, min_x);
min_y = MIN (output->crtc->rect.y, min_y);
max_x = MAX (output->crtc->rect.x + output->crtc->rect.width, max_x);
max_y = MAX (output->crtc->rect.y + output->crtc->rect.height, max_y);
min_x = MIN (crtc->rect.x, min_x);
min_y = MIN (crtc->rect.y, min_y);
max_x = MAX (crtc->rect.x + crtc->rect.width, max_x);
max_y = MAX (crtc->rect.y + crtc->rect.height, max_y);
}
*layout = (MetaRectangle) {
@@ -1318,10 +1340,14 @@ meta_monitor_get_spec (MetaMonitor *monitor)
MetaLogicalMonitor *
meta_monitor_get_logical_monitor (MetaMonitor *monitor)
{
MetaOutput *output = meta_monitor_get_main_output (monitor);
MetaOutput *output;
MetaCrtc *crtc;
if (output->crtc)
return output->crtc->logical_monitor;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
if (crtc)
return crtc->logical_monitor;
else
return NULL;
}
@@ -1381,6 +1407,18 @@ meta_monitor_get_current_mode (MetaMonitor *monitor)
return priv->current_mode;
}
static gboolean
is_current_mode_known (MetaMonitor *monitor)
{
MetaOutput *output;
MetaCrtc *crtc;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
return meta_monitor_is_active (monitor) == (crtc && crtc->current_mode);
}
void
meta_monitor_derive_current_mode (MetaMonitor *monitor)
{
@@ -1400,6 +1438,8 @@ meta_monitor_derive_current_mode (MetaMonitor *monitor)
}
priv->current_mode = current_mode;
g_warn_if_fail (is_current_mode_known (monitor));
}
void
@@ -1523,6 +1563,22 @@ meta_monitor_calculate_mode_scale (MetaMonitor *monitor,
return calculate_scale (monitor, monitor_mode);
}
static gboolean
is_logical_size_large_enough (gint width, gint height)
{
return width >= MINIMUM_LOGICAL_WIDTH &&
height >= MINIMUM_LOGICAL_HEIGHT;
}
gboolean
meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode)
{
g_return_val_if_fail (monitor_mode != NULL, FALSE);
return is_logical_size_large_enough (monitor_mode->spec.width,
monitor_mode->spec.height);
}
static float
get_closest_scale_factor_for_resolution (float width,
float height,
@@ -1543,8 +1599,7 @@ get_closest_scale_factor_for_resolution (float width,
if (scale < MINIMUM_SCALE_FACTOR ||
scale > MAXIMUM_SCALE_FACTOR ||
floorf (scaled_w) < MINIMUM_LOGICAL_WIDTH ||
floorf (scaled_h) < MINIMUM_LOGICAL_HEIGHT)
!is_logical_size_large_enough (floorf (scaled_w), floorf (scaled_h)))
goto out;
if (floorf (scaled_w) == scaled_w && floorf (scaled_h) == scaled_h)

View File

@@ -219,6 +219,8 @@ gboolean meta_monitor_mode_foreach_output (MetaMonitor *monitor,
gpointer user_data,
GError **error);
gboolean meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode);
MetaMonitorSpec * meta_monitor_spec_clone (MetaMonitorSpec *monitor_id);
gboolean meta_monitor_spec_equals (MetaMonitorSpec *monitor_id,

View File

@@ -21,7 +21,13 @@
#include "backends/meta-output.h"
G_DEFINE_TYPE (MetaOutput, meta_output, G_TYPE_OBJECT)
typedef struct _MetaOutputPrivate
{
/* The CRTC driving this output, NULL if the output is not enabled */
MetaCrtc *crtc;
} MetaOutputPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT)
MetaGpu *
meta_output_get_gpu (MetaOutput *output)
@@ -29,6 +35,44 @@ meta_output_get_gpu (MetaOutput *output)
return output->gpu;
}
void
meta_output_assign_crtc (MetaOutput *output,
MetaCrtc *crtc)
{
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
g_assert (crtc);
g_set_object (&priv->crtc, crtc);
}
void
meta_output_unassign_crtc (MetaOutput *output)
{
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
g_clear_object (&priv->crtc);
}
MetaCrtc *
meta_output_get_assigned_crtc (MetaOutput *output)
{
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
return priv->crtc;
}
static void
meta_output_dispose (GObject *object)
{
MetaOutput *output = META_OUTPUT (object);
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
g_clear_object (&priv->crtc);
G_OBJECT_CLASS (meta_output_parent_class)->dispose (object);
}
static void
meta_output_finalize (GObject *object)
{
@@ -58,5 +102,6 @@ meta_output_class_init (MetaOutputClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_output_dispose;
object_class->finalize = meta_output_finalize;
}

View File

@@ -64,9 +64,6 @@ struct _MetaOutput
MetaGpu *gpu;
/* The CRTC driving this output, NULL if the output is not enabled */
MetaCrtc *crtc;
/* The low-level ID of this output, used to apply back configuration */
glong winsys_id;
char *name;
@@ -122,4 +119,11 @@ G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
MetaGpu * meta_output_get_gpu (MetaOutput *output);
void meta_output_assign_crtc (MetaOutput *output,
MetaCrtc *crtc);
void meta_output_unassign_crtc (MetaOutput *output);
MetaCrtc * meta_output_get_assigned_crtc (MetaOutput *output);
#endif /* META_OUTPUT_H */

View File

@@ -360,9 +360,9 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
":", spa_type->format_video.format, "I", spa_type->video_format.BGRx,
":", spa_type->format_video.size, "R", &SPA_RECTANGLE (width, height),
":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
":", spa_type->format_video.max_framerate, "Fr", &max_framerate,
PROP_RANGE (&min_framerate,
&max_framerate));
":", spa_type->format_video.max_framerate, "Fru", &max_framerate,
PROP_RANGE (&min_framerate,
&max_framerate));
pw_stream_add_listener (pipewire_stream,
&priv->pipewire_stream_listener,

View File

@@ -31,7 +31,9 @@ typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1),
META_EXPERIMENTAL_FEATURE_SCREEN_CAST = (1 << 1),
META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP = (1 << 2),
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 3),
} MetaExperimentalFeature;
#define META_TYPE_SETTINGS (meta_settings_get_type ())

View File

@@ -260,8 +260,13 @@ experimental_features_handler (GVariant *features_variant,
g_variant_iter_init (&features_iter, features_variant);
while (g_variant_iter_loop (&features_iter, "s", &feature))
{
/* So far no experimental features defined. */
if (g_str_equal (feature, "scale-monitor-framebuffer"))
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "screen-cast"))
features |= META_EXPERIMENTAL_FEATURE_SCREEN_CAST;
else if (g_str_equal (feature, "remote-desktop"))
features |= META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP;
else if (g_str_equal (feature, "kms-modifiers"))
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
else

View File

@@ -291,6 +291,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
data->in_cursor_renderer_native;
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaCrtc *crtc;
MetaMonitorTransform transform;
ClutterRect scaled_crtc_rect;
float scale;
@@ -330,6 +331,8 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
},
};
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
if (priv->has_hw_cursor &&
clutter_rect_intersection (&scaled_crtc_rect,
&data->in_local_cursor_rect,
@@ -340,7 +343,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
float crtc_cursor_x, crtc_cursor_y;
set_crtc_cursor (data->in_cursor_renderer_native,
monitor_crtc_mode->output->crtc,
crtc,
data->in_cursor_sprite);
gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor));
@@ -350,7 +353,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
scaled_crtc_rect.origin.y) * scale;
drmModeMoveCursor (kms_fd,
monitor_crtc_mode->output->crtc->crtc_id,
crtc->crtc_id,
roundf (crtc_cursor_x),
roundf (crtc_cursor_y));
@@ -358,8 +361,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
}
else
{
set_crtc_cursor (data->in_cursor_renderer_native,
monitor_crtc_mode->output->crtc, NULL);
set_crtc_cursor (data->in_cursor_renderer_native, crtc, NULL);
}
return TRUE;

View File

@@ -68,8 +68,11 @@ struct _MetaGpuKms
int max_buffer_height;
gboolean page_flips_not_supported;
gboolean resources_init_failed_before;
};
G_DEFINE_QUARK (MetaGpuKmsError, meta_gpu_kms_error)
G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
static gboolean
@@ -110,8 +113,10 @@ get_crtc_drm_connectors (MetaGpu *gpu,
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *assigned_crtc;
if (output->crtc == crtc)
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc == crtc)
g_array_append_val (connectors_array, output->winsys_id);
}
@@ -146,7 +151,10 @@ meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
connectors, n_connectors,
mode) != 0)
{
g_warning ("Failed to set CRTC mode %s: %m", crtc->current_mode->name);
if (mode)
g_warning ("Failed to set CRTC mode %s: %m", crtc->current_mode->name);
else
g_warning ("Failed to disable CRTC");
g_free (connectors);
return FALSE;
}
@@ -191,8 +199,10 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *assigned_crtc;
if (output->crtc == crtc)
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc == crtc)
{
connected_crtc_found = TRUE;
break;
@@ -719,20 +729,34 @@ init_outputs (MetaGpuKms *gpu_kms,
setup_output_clones (gpu);
}
static void
meta_kms_resources_init (MetaKmsResources *resources,
int fd)
static gboolean
meta_kms_resources_init (MetaKmsResources *resources,
int fd,
GError **error)
{
drmModeRes *drm_resources;
unsigned int i;
drm_resources = drmModeGetResources (fd);
if (!drm_resources)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"Calling drmModeGetResources() failed");
return FALSE;
}
resources->resources = drm_resources;
resources->n_encoders = (unsigned int) drm_resources->count_encoders;
resources->encoders = g_new (drmModeEncoder *, resources->n_encoders);
for (i = 0; i < resources->n_encoders; i++)
resources->encoders[i] = drmModeGetEncoder (fd, drm_resources->encoders[i]);
return TRUE;
}
static void
@@ -744,7 +768,7 @@ meta_kms_resources_release (MetaKmsResources *resources)
drmModeFreeEncoder (resources->encoders[i]);
g_free (resources->encoders);
drmModeFreeResources (resources->resources);
g_clear_pointer (&resources->resources, drmModeFreeResources);
}
static gboolean
@@ -755,8 +779,18 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
MetaMonitorManager *monitor_manager =
meta_gpu_get_monitor_manager (gpu);
MetaKmsResources resources;
g_autoptr (GError) local_error = NULL;
meta_kms_resources_init (&resources, gpu_kms->fd);
if (!meta_kms_resources_init (&resources, gpu_kms->fd, &local_error))
{
if (!gpu_kms->resources_init_failed_before)
{
g_warning ("meta_kms_resources_init failed: %s, assuming we have no outputs",
local_error->message);
gpu_kms->resources_init_failed_before = TRUE;
}
return TRUE;
}
gpu_kms->max_buffer_width = resources.resources->max_width;
gpu_kms->max_buffer_height = resources.resources->max_height;
@@ -769,6 +803,8 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
are freed by the platform-independent layer. */
free_resources (gpu_kms);
g_assert (resources.resources->count_connectors > 0);
init_connectors (gpu_kms, resources.resources);
init_modes (gpu_kms, resources.resources);
init_crtcs (gpu_kms, &resources);
@@ -779,6 +815,12 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
return TRUE;
}
gboolean
meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms)
{
return gpu_kms->n_connectors > 0;
}
MetaGpuKms *
meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
const char *kms_file_path,
@@ -792,12 +834,47 @@ meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
GSource *source;
MetaKmsSource *kms_source;
MetaGpuKms *gpu_kms;
drmModeRes *drm_resources;
guint n_connectors;
int kms_fd;
kms_fd = meta_launcher_open_restricted (launcher, kms_file_path, error);
if (kms_fd == -1)
return NULL;
/* Some GPUs might have no connectors, for example dedicated GPUs on PRIME (hybrid) laptops.
* These GPUs cannot render anything on separate screens, and they are aggressively switched
* off by the kernel.
*
* If we add these PRIME GPUs to the GPU list anyway, Mutter keeps awakening the secondary GPU,
* and doing this causes a considerable stuttering. These GPUs are usually put to sleep again
* after ~2s without a workload.
*
* For now, to avoid this situation, only create the MetaGpuKms when the GPU has any connectors.
*/
drm_resources = drmModeGetResources (kms_fd);
if (!drm_resources)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No resources");
meta_launcher_close_restricted (launcher, kms_fd);
return NULL;
}
n_connectors = drm_resources->count_connectors;
drmModeFreeResources (drm_resources);
if (n_connectors == 0)
{
g_set_error (error,
META_GPU_KMS_ERROR,
META_GPU_KMS_ERROR_NO_CONNECTORS,
"No connectors available in this GPU. This is probably a dedicated GPU in a hybrid setup.");
meta_launcher_close_restricted (launcher, kms_fd);
return NULL;
}
gpu_kms = g_object_new (META_TYPE_GPU_KMS,
"monitor-manager", monitor_manager_kms,
NULL);
@@ -807,6 +884,8 @@ meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
drmSetClientCap (gpu_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
meta_gpu_kms_read_current (META_GPU (gpu_kms), NULL);
source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource));
kms_source = (MetaKmsSource *) source;
kms_source->fd_tag = g_source_add_unix_fd (source,

View File

@@ -29,6 +29,14 @@
#include "backends/meta-gpu.h"
#include "backends/native/meta-monitor-manager-kms.h"
typedef enum
{
META_GPU_KMS_ERROR_NO_CONNECTORS,
} MetaGpuKmsError;
#define META_GPU_KMS_ERROR (meta_gpu_kms_error_quark ())
GQuark meta_gpu_kms_error_quark (void);
#define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ())
G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu)
@@ -53,6 +61,8 @@ gboolean meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
int y,
uint32_t fb_id);
gboolean meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms);
gboolean meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
MetaCrtc *crtc);

View File

@@ -188,7 +188,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
}
}
@@ -249,7 +249,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}
}
@@ -642,10 +642,12 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
GError **error)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable);
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
const char *subsystems[2] = { "drm", NULL };
GList *gpu_paths;
g_autofree char *primary_gpu_path = NULL;
GList *l;
gboolean can_have_outputs;
manager_kms->udev = g_udev_client_new (subsystems);
@@ -681,8 +683,11 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, &secondary_error);
if (!gpu_kms)
{
g_warning ("Failed to open secondary gpu '%s': %s",
gpu_path, secondary_error->message);
if (g_error_matches (secondary_error, META_GPU_KMS_ERROR, META_GPU_KMS_ERROR_NO_CONNECTORS))
g_message ("Ignoring GPU %s due to the lack of connectors", gpu_path);
else
g_warning ("Failed to open secondary gpu '%s': %s", gpu_path, secondary_error->message);
continue;
}
@@ -691,6 +696,24 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
}
g_list_free_full (gpu_paths, g_free);
can_have_outputs = FALSE;
for (l = meta_monitor_manager_get_gpus (manager); l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;
if (meta_gpu_kms_can_have_outputs (gpu_kms))
{
can_have_outputs = TRUE;
break;
}
}
if (!can_have_outputs)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"No GPUs with outputs found");
return FALSE;
}
return TRUE;
}

View File

@@ -64,11 +64,13 @@ typedef struct _MetaOutputKms
void
meta_output_kms_set_underscan (MetaOutput *output)
{
if (!output->crtc)
MetaCrtc *crtc;
crtc = meta_output_get_assigned_crtc (output);
if (!crtc)
return;
meta_crtc_kms_set_underscan (output->crtc,
output->is_underscanning);
meta_crtc_kms_set_underscan (crtc, output->is_underscanning);
}
void
@@ -600,14 +602,14 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
if (crtc->crtc_id == output_kms->current_encoder->crtc_id)
{
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
break;
}
}
}
else
{
output->crtc = NULL;
meta_output_unassign_crtc (output);
}
if (old_output)

View File

@@ -993,14 +993,29 @@ meta_renderer_native_choose_egl_config (CoglDisplay *cogl_display,
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaBackend *backend = meta_get_backend ();
MetaEgl *egl = meta_backend_get_egl (backend);
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
EGLDisplay egl_display = cogl_renderer_egl->edpy;
return choose_egl_config_from_gbm_format (egl,
egl_display,
attributes,
GBM_FORMAT_XRGB8888,
out_config,
error);
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
return choose_egl_config_from_gbm_format (egl,
egl_display,
attributes,
GBM_FORMAT_XRGB8888,
out_config,
error);
#ifdef HAVE_EGL_DEVICE
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
return meta_egl_choose_first_config (egl,
egl_display,
attributes,
out_config,
error);
#endif
}
return FALSE;
}
static gboolean
@@ -1612,12 +1627,23 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
return FALSE;
}
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
if (gbm_bo_get_handle_for_plane (next_bo, 0).s32 == -1)
{
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
handles[i] = gbm_bo_get_handle_for_plane (next_bo, i).u32;
offsets[i] = gbm_bo_get_offset (next_bo, i);
modifiers[i] = gbm_bo_get_modifier (next_bo);
/* Failed to fetch handle to plane, falling back to old method */
strides[0] = gbm_bo_get_stride (next_bo);
handles[0] = gbm_bo_get_handle (next_bo).u32;
offsets[0] = 0;
modifiers[0] = DRM_FORMAT_MOD_INVALID;
}
else
{
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
{
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
handles[i] = gbm_bo_get_handle_for_plane (next_bo, i).u32;
offsets[i] = gbm_bo_get_offset (next_bo, i);
modifiers[i] = gbm_bo_get_modifier (next_bo);
}
}
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
@@ -2094,6 +2120,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
EGLDisplay egl_display = renderer_gpu_data->egl_display;
MetaMonitor *monitor;
MetaOutput *output;
MetaCrtc *crtc;
EGLConfig egl_config;
EGLStreamKHR egl_stream;
EGLSurface egl_surface;
@@ -2117,6 +2144,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
/*
* An "logical_monitor" may have multiple outputs/crtcs in case its tiled,
@@ -2124,7 +2152,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
* lets pass the first one.
*/
output_attribs[0] = EGL_DRM_CRTC_EXT;
output_attribs[1] = output->crtc->crtc_id;
output_attribs[1] = crtc->crtc_id;
output_attribs[2] = EGL_NONE;
if (!meta_egl_get_output_layers (egl, egl_display,
@@ -2722,9 +2750,12 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaCrtc *crtc;
MetaMonitorTransform crtc_transform;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
crtc = meta_output_get_assigned_crtc (main_output);
crtc_transform =
meta_monitor_logical_to_crtc_transform (main_monitor,
logical_monitor->transform);
@@ -2735,7 +2766,7 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
*/
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
crtc,
crtc_transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
@@ -2912,10 +2943,11 @@ meta_renderer_native_set_property (GObject *object,
}
static gboolean
create_secondary_egl_config (MetaEgl *egl,
EGLDisplay egl_display,
EGLConfig *egl_config,
GError **error)
create_secondary_egl_config (MetaEgl *egl,
MetaRendererNativeMode mode,
EGLDisplay egl_display,
EGLConfig *egl_config,
GError **error)
{
EGLint attributes[] = {
EGL_RED_SIZE, 1,
@@ -2928,12 +2960,26 @@ create_secondary_egl_config (MetaEgl *egl,
EGL_NONE
};
return choose_egl_config_from_gbm_format (egl,
egl_display,
attributes,
GBM_FORMAT_XRGB8888,
egl_config,
error);
switch (mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
return choose_egl_config_from_gbm_format (egl,
egl_display,
attributes,
GBM_FORMAT_XRGB8888,
egl_config,
error);
#ifdef HAVE_EGL_DEVICE
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
return meta_egl_choose_first_config (egl,
egl_display,
attributes,
egl_config,
error);
#endif
}
return FALSE;
}
static EGLContext
@@ -2977,7 +3023,8 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
EGLContext egl_context;
char **missing_gl_extensions;
if (!create_secondary_egl_config (egl,egl_display, &egl_config, error))
if (!create_secondary_egl_config (egl, renderer_gpu_data->mode, egl_display,
&egl_config, error))
return FALSE;
egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error);

View File

@@ -547,8 +547,9 @@ meta_backend_x11_grab_device (MetaBackend *backend,
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
int ret;
if (timestamp != CurrentTime)
timestamp = MAX (timestamp, priv->latest_evtime);
if (timestamp != CurrentTime &&
XSERVER_TIME_IS_BEFORE (timestamp, priv->latest_evtime))
timestamp = priv->latest_evtime;
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);

View File

@@ -225,8 +225,10 @@ is_crtc_assignment_changed (MetaCrtc *crtc,
for (j = 0; j < crtc_info->outputs->len; j++)
{
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
MetaCrtc *assigned_crtc;
if (output->crtc != crtc)
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc != crtc)
return TRUE;
}
@@ -243,6 +245,7 @@ is_output_assignment_changed (MetaOutput *output,
MetaOutputInfo **output_infos,
unsigned int n_output_infos)
{
MetaCrtc *assigned_crtc;
gboolean output_is_found = FALSE;
unsigned int i;
@@ -265,8 +268,10 @@ is_output_assignment_changed (MetaOutput *output,
output_is_found = TRUE;
}
assigned_crtc = meta_output_get_assigned_crtc (output);
if (!output_is_found)
return output->crtc != NULL;
return assigned_crtc != NULL;
for (i = 0; i < n_crtc_infos; i++)
{
@@ -279,7 +284,7 @@ is_output_assignment_changed (MetaOutput *output,
((MetaOutput**) crtc_info->outputs->pdata)[j];
if (crtc_info_output == output &&
crtc_info->crtc == output->crtc)
crtc_info->crtc == assigned_crtc)
return FALSE;
}
}
@@ -455,7 +460,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
output_ids[j] = output->winsys_id;
}
@@ -521,7 +526,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}

View File

@@ -97,10 +97,13 @@ output_set_underscanning_xrandr (MetaOutput *output,
* make the border configurable. */
if (underscanning)
{
MetaCrtc *crtc;
uint32_t border_value;
crtc = meta_output_get_assigned_crtc (output);
prop = XInternAtom (xdisplay, "underscan hborder", False);
border_value = output->crtc->current_mode->width * 0.05;
border_value = crtc->current_mode->width * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) output->winsys_id,
@@ -109,7 +112,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
1, &border_value);
prop = XInternAtom (xdisplay, "underscan vborder", False);
border_value = output->crtc->current_mode->height * 0.05;
border_value = crtc->current_mode->height * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) output->winsys_id,
@@ -737,14 +740,14 @@ output_get_crtcs (MetaOutput *output,
}
output->n_possible_crtcs = n_actual_crtcs;
output->crtc = NULL;
meta_output_unassign_crtc (output);
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
{
MetaCrtc *crtc = l->data;
if ((XID) crtc->crtc_id == xrandr_output->crtc)
{
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
break;
}
}

View File

@@ -113,7 +113,7 @@ draw_crtc (MetaMonitor *monitor,
CoglTexture *texture = data->texture;
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
MetaOutput *output = monitor_crtc_mode->output;
MetaCrtc *crtc = output->crtc;
MetaCrtc *crtc;
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
MetaMonitorTransform view_transform;
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
@@ -129,6 +129,8 @@ draw_crtc (MetaMonitor *monitor,
texture_width = cogl_texture_get_width (texture);
texture_height = cogl_texture_get_height (texture);
crtc = meta_output_get_assigned_crtc (output);
clutter_stage_view_get_layout (data->view, &view_layout);
sample_x = crtc->rect.x - view_layout.x;
sample_y = crtc->rect.y - view_layout.y;

View File

@@ -50,20 +50,22 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaCrtc *crtc;
MetaMonitorTransform crtc_transform;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
crtc = meta_output_get_assigned_crtc (main_output);
crtc_transform =
meta_monitor_logical_to_crtc_transform (main_monitor,
logical_monitor->transform);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
* always have the same transform assigned to them.
*/
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
crtc,
crtc_transform))
return META_MONITOR_TRANSFORM_NORMAL;
else

View File

@@ -798,6 +798,7 @@ meta_compositor_hide_window (MetaCompositor *compositor,
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
meta_window_actor_hide (window_actor, effect);
meta_stack_tracker_queue_sync_stack (compositor->display->screen->stack_tracker);
}
void
@@ -944,6 +945,9 @@ get_top_visible_window_actor (MetaCompositor *compositor)
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
MetaRectangle buffer_rect;
if (!window->visible_to_compositor)
continue;
meta_window_get_buffer_rect (window, &buffer_rect);
if (meta_rectangle_overlap (&compositor->display->screen->rect,

View File

@@ -694,46 +694,11 @@ effective_unobscured_region (MetaShapedTexture *self)
return priv->unobscured_region;
}
static gboolean
get_unobscured_bounds (MetaShapedTexture *self,
cairo_rectangle_int_t *unobscured_bounds)
{
cairo_region_t *unobscured_region = effective_unobscured_region (self);
if (unobscured_region)
{
cairo_region_get_extents (unobscured_region, unobscured_bounds);
return TRUE;
}
else
return FALSE;
}
static gboolean
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
ClutterActorBox box;
cairo_rectangle_int_t unobscured_bounds;
if (!clutter_actor_has_allocation (actor))
return FALSE;
clutter_actor_get_allocation_box (actor, &box);
if (get_unobscured_bounds (self, &unobscured_bounds))
{
box.x1 = MAX (unobscured_bounds.x, box.x1);
box.x2 = MIN (unobscured_bounds.x + unobscured_bounds.width, box.x2);
box.y1 = MAX (unobscured_bounds.y, box.y1);
box.y2 = MIN (unobscured_bounds.y + unobscured_bounds.height, box.y2);
}
box.x2 = MAX (box.x2, box.x1);
box.y2 = MAX (box.y2, box.y1);
clutter_paint_volume_union_box (volume, &box);
return TRUE;
return clutter_paint_volume_set_from_allocation (volume, actor);
}
void

View File

@@ -101,6 +101,13 @@ meta_surface_actor_pick (ClutterActor *actor,
clutter_actor_paint (child);
}
static gboolean
meta_surface_actor_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, actor);
}
static void
meta_surface_actor_dispose (GObject *object)
{
@@ -120,6 +127,7 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
object_class->dispose = meta_surface_actor_dispose;
actor_class->pick = meta_surface_actor_pick;
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
G_TYPE_FROM_CLASS (object_class),

View File

@@ -450,7 +450,7 @@ meta_window_actor_update_surface (MetaWindowActor *self)
#ifdef HAVE_WAYLAND
if (window->surface)
surface_actor = meta_wayland_surface_get_actor (window->surface);
surface_actor = window->surface->surface_actor;
else
#endif
if (!meta_is_wayland_compositor ())

View File

@@ -886,7 +886,8 @@ constrain_modal_dialog (MetaWindow *window,
MetaRectangle child_rect, parent_rect;
gboolean constraint_already_satisfied;
if (!meta_window_is_attached_dialog (window) ||
if (!parent ||
!meta_window_is_attached_dialog (window) ||
meta_window_get_placement_rule (window))
return TRUE;

View File

@@ -105,6 +105,12 @@ meta_window_ensure_frame (MetaWindow *window)
/* FIXME handle this error */
meta_error_trap_pop (window->display);
/* Ensure focus is restored after the unmap/map events triggered
* by XReparentWindow().
*/
if (meta_window_has_focus (window))
window->restore_focus_on_map = TRUE;
/* stick frame to the window */
window->frame = frame;
@@ -194,6 +200,12 @@ meta_window_destroy_frame (MetaWindow *window)
meta_ui_frame_unmanage (frame->ui_frame);
/* Ensure focus is restored after the unmap/map events triggered
* by XReparentWindow().
*/
if (meta_window_has_focus (window))
window->restore_focus_on_map = TRUE;
meta_display_unregister_x_window (window->display,
frame->xwindow);

View File

@@ -417,7 +417,7 @@ check_for_wayland_session_type (void)
*
* If no flag is passed that forces the compositor type, the compositor type
* is determined first from the logind session type, or if that fails, from the
* XDG_SESSION_TYPE environment variable.
* XDG_SESSION_TYPE enviornment variable.
*
* If no flag is passed that forces the backend type, the backend type is
* determined given the compositor type. If the compositor is a Wayland

View File

@@ -1394,7 +1394,9 @@ meta_screen_update_cursor (MetaScreen *screen)
XDefineCursor (display->xdisplay, screen->xroot, xcursor);
XFlush (display->xdisplay);
XFreeCursor (display->xdisplay, xcursor);
if (xcursor)
XFreeCursor (display->xdisplay, xcursor);
}
void

View File

@@ -82,6 +82,7 @@ typedef enum
META_MOVE_RESIZE_UNMAXIMIZE = 1 << 6,
META_MOVE_RESIZE_FORCE_MOVE = 1 << 7,
META_MOVE_RESIZE_WAYLAND_STATE_CHANGED = 1 << 8,
META_MOVE_RESIZE_FORCE_UPDATE_MONITOR = 1 << 9,
} MetaMoveResizeFlags;
typedef enum
@@ -121,6 +122,13 @@ typedef enum
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 1 << 5,
} MetaPlacementConstraintAdjustment;
typedef enum _MetaWindowUpdateMonitorFlags
{
META_WINDOW_UPDATE_MONITOR_FLAGS_NONE = 0,
META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP = 1 << 0,
META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE = 1 << 1,
} MetaWindowUpdateMonitorFlags;
typedef struct _MetaPlacementRule
{
MetaRectangle anchor_rect;
@@ -409,6 +417,9 @@ struct _MetaWindow
/* whether or not the window is from a program running on another machine */
guint is_remote : 1;
/* whether focus should be restored on map */
guint restore_focus_on_map : 1;
/* if non-NULL, the bounds of the window frame */
cairo_region_t *frame_bounds;
@@ -549,8 +560,8 @@ struct _MetaWindowClass
cairo_surface_t **icon,
cairo_surface_t **mini_icon);
uint32_t (*get_client_pid) (MetaWindow *window);
void (*update_main_monitor) (MetaWindow *window,
gboolean user_op);
void (*update_main_monitor) (MetaWindow *window,
MetaWindowUpdateMonitorFlags flags);
void (*main_monitor_changed) (MetaWindow *window,
const MetaLogicalMonitor *old);
void (*force_restore_shortcuts) (MetaWindow *window,
@@ -768,8 +779,8 @@ void meta_window_activate_full (MetaWindow *window,
MetaLogicalMonitor * meta_window_calculate_main_logical_monitor (MetaWindow *window);
MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window);
void meta_window_update_monitor (MetaWindow *window,
gboolean user_op);
void meta_window_update_monitor (MetaWindow *window,
MetaWindowUpdateMonitorFlags flags);
void meta_window_set_urgent (MetaWindow *window,
gboolean urgent);

View File

@@ -119,6 +119,7 @@ static gboolean queue_calc_showing_func (MetaWindow *window,
void *data);
static void meta_window_move_between_rects (MetaWindow *window,
MetaMoveResizeFlags move_resize_flags,
const MetaRectangle *old_area,
const MetaRectangle *new_area);
@@ -1469,7 +1470,9 @@ meta_window_unmanage (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"Focusing default window since we're unmanaging %s\n",
window->desc);
meta_workspace_focus_default_window (window->screen->active_workspace, NULL, timestamp);
meta_workspace_focus_default_window (window->screen->active_workspace,
window,
timestamp);
}
else
{
@@ -3750,11 +3753,15 @@ maybe_move_attached_dialog (MetaWindow *window,
*
* Gets index of the monitor that this window is on.
*
* Return Value: The index of the monitor in the screens monitor list
* Return Value: The index of the monitor in the screens monitor list, or -1
* if the window has been recently unmanaged and does not have a monitor.
*/
int
meta_window_get_monitor (MetaWindow *window)
{
if (!window->monitor)
return -1;
return window->monitor->number;
}
@@ -3802,7 +3809,8 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
{
meta_window_update_monitor (window, FALSE);
meta_window_update_monitor (window,
META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
return;
}
@@ -3832,23 +3840,25 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
* monitors changed and the same index could be refereing
* to a different monitor. */
meta_window_move_between_rects (window,
META_MOVE_RESIZE_FORCE_UPDATE_MONITOR,
&old->rect,
&new->rect);
}
else
{
meta_window_update_monitor (window, FALSE);
meta_window_update_monitor (window,
META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
}
}
void
meta_window_update_monitor (MetaWindow *window,
gboolean user_op)
meta_window_update_monitor (MetaWindow *window,
MetaWindowUpdateMonitorFlags flags)
{
const MetaLogicalMonitor *old;
old = window->monitor;
META_WINDOW_GET_CLASS (window)->update_main_monitor (window, user_op);
META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags);
if (old != window->monitor)
{
meta_window_on_all_workspaces_changed (window);
@@ -3862,7 +3872,8 @@ meta_window_update_monitor (MetaWindow *window,
* That should be handled by explicitly moving the window before changing the
* workspace.
*/
if (meta_prefs_get_workspaces_only_on_primary () && user_op &&
if (meta_prefs_get_workspaces_only_on_primary () &&
flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP &&
meta_window_is_on_primary_monitor (window) &&
window->screen->active_workspace != window->workspace)
meta_window_change_workspace (window, window->screen->active_workspace);
@@ -3905,6 +3916,7 @@ meta_window_move_resize_internal (MetaWindow *window,
MetaRectangle constrained_rect;
MetaMoveResizeResultFlags result = 0;
gboolean moved_or_resized = FALSE;
MetaWindowUpdateMonitorFlags update_monitor_flags;
g_return_if_fail (!window->override_redirect);
@@ -4005,13 +4017,19 @@ meta_window_move_resize_internal (MetaWindow *window,
did_placement);
}
update_monitor_flags = META_WINDOW_UPDATE_MONITOR_FLAGS_NONE;
if (flags & META_MOVE_RESIZE_USER_ACTION)
update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP;
if (flags & META_MOVE_RESIZE_FORCE_UPDATE_MONITOR)
update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE;
if (window->monitor)
{
guint old_output_winsys_id;
old_output_winsys_id = window->monitor->winsys_id;
meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
meta_window_update_monitor (window, update_monitor_flags);
if (old_output_winsys_id != window->monitor->winsys_id &&
flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION)
@@ -4019,7 +4037,7 @@ meta_window_move_resize_internal (MetaWindow *window,
}
else
{
meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
meta_window_update_monitor (window, update_monitor_flags);
}
if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
@@ -4063,6 +4081,7 @@ meta_window_move_frame (MetaWindow *window,
static void
meta_window_move_between_rects (MetaWindow *window,
MetaMoveResizeFlags move_resize_flags,
const MetaRectangle *old_area,
const MetaRectangle *new_area)
{
@@ -4086,7 +4105,12 @@ meta_window_move_between_rects (MetaWindow *window,
window->saved_rect.x = window->unconstrained_rect.x;
window->saved_rect.y = window->unconstrained_rect.y;
meta_window_move_resize_now (window);
meta_window_move_resize_internal (window,
move_resize_flags |
META_MOVE_RESIZE_MOVE_ACTION |
META_MOVE_RESIZE_RESIZE_ACTION,
NorthWestGravity,
window->unconstrained_rect);
}
/**
@@ -4147,14 +4171,14 @@ meta_window_move_to_monitor (MetaWindow *window,
window->unconstrained_rect.height == 0 ||
!meta_rectangle_overlap (&window->unconstrained_rect, &old_area))
{
meta_window_move_between_rects (window, NULL, &new_area);
meta_window_move_between_rects (window, 0, NULL, &new_area);
}
else
{
if (monitor == window->monitor->number)
return;
meta_window_move_between_rects (window, &old_area, &new_area);
meta_window_move_between_rects (window, 0, &old_area, &new_area);
}
window->preferred_output_winsys_id = window->monitor->winsys_id;
@@ -4615,11 +4639,15 @@ meta_window_focus (MetaWindow *window,
g_return_if_fail (!window->override_redirect);
/* This is a oneshot flag */
window->restore_focus_on_map = FALSE;
meta_topic (META_DEBUG_FOCUS,
"Setting input focus to window %s, input: %d take_focus: %d\n",
window->desc, window->input, window->take_focus);
if (window->display->grab_window &&
window->display->grab_window != window &&
window->display->grab_window->all_keys_grabbed &&
!window->display->grab_window->unmanaging)
{
@@ -4734,7 +4762,7 @@ set_workspace_state (MetaWindow *window,
/* queue a move_resize since changing workspaces may change
* the relevant struts
*/
if (!window->override_redirect && window != window->display->grab_window)
if (!window->override_redirect)
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
meta_window_current_workspace_changed (window);
@@ -7927,7 +7955,15 @@ meta_window_set_transient_for (MetaWindow *window,
}
}
}
else if (window->attached && parent == NULL)
{
guint32 timestamp;
timestamp =
meta_display_get_current_time_roundtrip (window->display);
meta_window_unmanage (window, timestamp);
return;
}
/* We know this won't create a reference cycle because we check for loops */
g_clear_object (&window->transient_for);
window->transient_for = parent ? g_object_ref (parent) : NULL;

View File

@@ -209,7 +209,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
}
}
}
@@ -255,7 +255,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}
}

View File

@@ -449,22 +449,24 @@ check_current_monitor_mode (MetaMonitor *monitor,
CheckMonitorModeData *data = user_data;
MetaMonitorManager *monitor_manager = data->monitor_manager;
MetaOutput *output;
MetaCrtc *crtc;
output = output_from_winsys_id (monitor_manager,
data->expect_crtc_mode_iter->output);
crtc = meta_output_get_assigned_crtc (output);
if (data->expect_crtc_mode_iter->crtc_mode == -1)
{
g_assert_null (output->crtc);
g_assert_null (crtc);
}
else
{
MetaLogicalMonitor *logical_monitor;
g_assert_nonnull (output->crtc);
g_assert (monitor_crtc_mode->crtc_mode == output->crtc->current_mode);
g_assert_nonnull (crtc);
g_assert (monitor_crtc_mode->crtc_mode == crtc->current_mode);
logical_monitor = output->crtc->logical_monitor;
logical_monitor = crtc->logical_monitor;
g_assert_nonnull (logical_monitor);
}
@@ -553,6 +555,7 @@ check_logical_monitor (MonitorTestCase *test_case,
for (l_output = outputs; l_output; l_output = l_output->next)
{
MetaOutput *output = l_output->data;
MetaCrtc *crtc;
if (output->is_primary)
{
@@ -560,8 +563,8 @@ check_logical_monitor (MonitorTestCase *test_case,
primary_output = output;
}
g_assert (!output->crtc ||
output->crtc->logical_monitor == logical_monitor);
crtc = meta_output_get_assigned_crtc (output);
g_assert (!crtc || crtc->logical_monitor == logical_monitor);
g_assert_cmpint (logical_monitor->is_presentation,
==,
output->is_presentation);
@@ -983,7 +986,8 @@ create_monitor_test_setup (MonitorTestCase *test_case,
output = g_object_new (META_TYPE_OUTPUT, NULL);
output->crtc = crtc;
if (crtc)
meta_output_assign_crtc (output, crtc);
output->winsys_id = i;
output->name = (is_laptop_panel ? g_strdup_printf ("eDP-%d",
++n_laptop_panels)

View File

@@ -0,0 +1,19 @@
new_client 1 wayland
create 1/1
show 1/1
new_client 2 wayland
create 2/1
show 2/1
create 1/2
show 1/2
set_parent 1/2 1
wait
assert_stacking 1/1 2/1 1/2
destroy 1/2
wait
assert_stacking 2/1 1/1

View File

@@ -664,8 +664,17 @@ meta_pointer_confinement_wayland_maybe_warp (MetaPointerConfinementWayland *self
}
static void
surface_actor_geometry_changed (MetaSurfaceActorWayland *surface_actor,
MetaPointerConfinementWayland *self)
surface_actor_allocation_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaPointerConfinementWayland *self)
{
meta_pointer_confinement_wayland_maybe_warp (self);
}
static void
surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaPointerConfinementWayland *self)
{
meta_pointer_confinement_wayland_maybe_warp (self);
}
@@ -690,9 +699,14 @@ meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
confinement->constraint = constraint;
surface = meta_wayland_pointer_constraint_get_surface (constraint);
g_signal_connect_object (meta_wayland_surface_get_actor (surface),
"geometry-changed",
G_CALLBACK (surface_actor_geometry_changed),
g_signal_connect_object (surface->surface_actor,
"notify::allocation",
G_CALLBACK (surface_actor_allocation_notify),
confinement,
0);
g_signal_connect_object (surface->surface_actor,
"notify::position",
G_CALLBACK (surface_actor_position_notify),
confinement,
0);
if (surface->window)

View File

@@ -30,70 +30,34 @@
#include "wayland/meta-wayland-surface.h"
#include "wayland/meta-window-wayland.h"
typedef struct _MetaWaylandActorSurfacePrivate MetaWaylandActorSurfacePrivate;
struct _MetaWaylandActorSurfacePrivate
{
MetaSurfaceActor *actor;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandActorSurface,
meta_wayland_actor_surface,
META_TYPE_WAYLAND_SURFACE_ROLE)
static void
meta_wayland_actor_surface_constructed (GObject *object)
{
G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->constructed (object);
meta_wayland_actor_surface_reset_actor (META_WAYLAND_ACTOR_SURFACE (object));
}
static void
meta_wayland_actor_surface_dispose (GObject *object)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (object));
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
if (priv->actor)
{
g_signal_handlers_disconnect_by_func (priv->actor,
meta_wayland_surface_notify_geometry_changed,
surface);
clutter_actor_set_reactive (CLUTTER_ACTOR (priv->actor), FALSE);
g_clear_object (&priv->actor);
}
G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->dispose (object);
}
G_DEFINE_ABSTRACT_TYPE (MetaWaylandActorSurface,
meta_wayland_actor_surface,
META_TYPE_WAYLAND_SURFACE_ROLE)
static void
meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
GList *l;
MetaSurfaceActorWayland *surface_actor =
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
&surface->pending_frame_callback_list);
wl_list_init (&surface->pending_frame_callback_list);
for (l = surface->subsurfaces; l; l = l->next)
{
ClutterActor *subsurface_actor =
CLUTTER_ACTOR (meta_wayland_surface_get_actor (l->data));
clutter_actor_add_child (CLUTTER_ACTOR (priv->actor), subsurface_actor);
}
}
static void
queue_surface_actor_frame_callbacks (MetaSurfaceActorWayland *surface_actor,
MetaWaylandPendingState *pending)
void
meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
MetaWaylandPendingState *pending)
{
MetaWaylandSurfaceRole *surface_role =
META_WAYLAND_SURFACE_ROLE (actor_surface);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaSurfaceActorWayland *surface_actor =
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
&pending->frame_callback_list);
wl_list_init (&pending->frame_callback_list);
@@ -130,8 +94,6 @@ meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *actor_surfa
static void
meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor_surface)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (actor_surface);
MetaWaylandSurfaceRole *surface_role =
META_WAYLAND_SURFACE_ROLE (actor_surface);
MetaWaylandSurface *surface =
@@ -141,7 +103,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
double actor_scale;
GList *l;
surface_actor = priv->actor;
surface_actor = surface->surface_actor;
stex = meta_surface_actor_get_texture (surface_actor);
actor_scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
@@ -203,16 +165,13 @@ static void
meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
MetaWaylandActorSurface *actor_surface =
META_WAYLAND_ACTOR_SURFACE (surface_role);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurface *toplevel_surface;
queue_surface_actor_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
pending);
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
toplevel_surface = meta_wayland_surface_get_toplevel (surface);
if (!toplevel_surface || !toplevel_surface->window)
@@ -225,9 +184,9 @@ static gboolean
meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
MetaLogicalMonitor *logical_monitor)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
ClutterActor *actor = CLUTTER_ACTOR (priv->actor);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
float x, y, width, height;
cairo_rectangle_int_t actor_rect;
cairo_region_t *region;
@@ -271,10 +230,6 @@ meta_wayland_actor_surface_class_init (MetaWaylandActorSurfaceClass *klass)
{
MetaWaylandSurfaceRoleClass *surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_wayland_actor_surface_constructed;
object_class->dispose = meta_wayland_actor_surface_dispose;
surface_role_class->assigned = meta_wayland_actor_surface_assigned;
surface_role_class->commit = meta_wayland_actor_surface_commit;
@@ -283,41 +238,3 @@ meta_wayland_actor_surface_class_init (MetaWaylandActorSurfaceClass *klass)
klass->sync_actor_state = meta_wayland_actor_surface_real_sync_actor_state;
}
MetaSurfaceActor *
meta_wayland_actor_surface_get_actor (MetaWaylandActorSurface *actor_surface)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (actor_surface);
return priv->actor;
}
void
meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surface)
{
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (actor_surface);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (actor_surface));
if (priv->actor)
{
g_signal_handlers_disconnect_by_func (priv->actor,
meta_wayland_surface_notify_geometry_changed,
surface);
g_object_unref (priv->actor);
}
priv->actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
g_signal_connect_swapped (priv->actor, "notify::allocation",
G_CALLBACK (meta_wayland_surface_notify_geometry_changed),
surface);
g_signal_connect_swapped (priv->actor, "notify::position",
G_CALLBACK (meta_wayland_surface_notify_geometry_changed),
surface);
g_signal_connect_swapped (priv->actor, "notify::mapped",
G_CALLBACK (meta_wayland_surface_notify_geometry_changed),
surface);
}

View File

@@ -40,7 +40,7 @@ void meta_wayland_actor_surface_sync_actor_state (MetaWaylandActorSurface *actor
double meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *actor_surface);
MetaSurfaceActor * meta_wayland_actor_surface_get_actor (MetaWaylandActorSurface *actor_surface);
void meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surface);
void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
MetaWaylandPendingState *pending);
#endif /* META_WAYLAND_ACTOR_SURFACE_H */

View File

@@ -88,13 +88,13 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource)
return buffer;
}
static gboolean
gboolean
meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer)
{
return buffer->type != META_WAYLAND_BUFFER_TYPE_UNKNOWN;
}
static gboolean
gboolean
meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
{
EGLint format;
@@ -123,8 +123,17 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
stream = meta_wayland_egl_stream_new (buffer, NULL);
if (stream)
{
CoglTexture2D *texture;
texture = meta_wayland_egl_stream_create_texture (stream, NULL);
if (!texture)
return FALSE;
buffer->egl_stream.stream = stream;
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
buffer->texture = COGL_TEXTURE (texture);
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
return TRUE;
}
@@ -314,18 +323,6 @@ egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
g_assert (stream);
if (!buffer->texture)
{
CoglTexture2D *texture;
texture = meta_wayland_egl_stream_create_texture (stream, error);
if (!texture)
return FALSE;
buffer->texture = COGL_TEXTURE (texture);
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
}
if (!meta_wayland_egl_stream_attach (stream, error))
return FALSE;
@@ -340,13 +337,11 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
if (!meta_wayland_buffer_is_realized (buffer))
{
if (!meta_wayland_buffer_realize (buffer))
{
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"Unknown buffer type");
return FALSE;
}
/* The buffer should have been realized at surface commit time */
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"Unknown buffer type");
return FALSE;
}
switch (buffer->type)

View File

@@ -68,6 +68,8 @@ G_DECLARE_FINAL_TYPE (MetaWaylandBuffer, meta_wayland_buffer,
META, WAYLAND_BUFFER, GObject);
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
GError **error);
CoglTexture * meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer);

View File

@@ -1083,7 +1083,6 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
MetaWaylandDragGrab *drag_grab;
ClutterPoint pos, surface_pos;
ClutterModifierType modifiers;
MetaSurfaceActor *surface_actor;
data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
@@ -1101,9 +1100,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
wl_resource_add_destroy_listener (surface->resource,
&drag_grab->drag_origin_listener);
surface_actor = meta_wayland_surface_get_actor (surface);
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface_actor)),
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
seat->pointer->grab_x,
seat->pointer->grab_y,
&surface_pos.x, &surface_pos.y);
@@ -1124,22 +1121,19 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
if (icon_surface)
{
ClutterActor *drag_origin_actor;
drag_grab->drag_surface = icon_surface;
drag_grab->drag_icon_listener.notify = destroy_data_device_icon;
wl_resource_add_destroy_listener (icon_surface->resource,
&drag_grab->drag_icon_listener);
drag_origin_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (drag_grab->drag_origin));
drag_grab->feedback_actor = meta_dnd_actor_new (drag_origin_actor,
drag_grab->feedback_actor = meta_dnd_actor_new (CLUTTER_ACTOR (drag_grab->drag_origin->surface_actor),
drag_grab->drag_start_x,
drag_grab->drag_start_y);
meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
0, 0);
clutter_actor_add_child (drag_grab->feedback_actor, drag_origin_actor);
clutter_actor_add_child (drag_grab->feedback_actor,
CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor));
clutter_input_device_get_coords (seat->pointer->device, NULL, &pos);
meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),

View File

@@ -365,6 +365,7 @@ buffer_params_create_common (struct wl_client *client,
dma_buf, NULL);
buffer = meta_wayland_buffer_from_resource (buffer_resource);
meta_wayland_buffer_realize (buffer);
if (!meta_wayland_buffer_attach (buffer, &error))
{
if (buffer_id == 0)

View File

@@ -71,15 +71,13 @@ gtk_surface_set_dbus_properties (struct wl_client *client,
{
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = gtk_surface->surface;
MetaWindow *window;
/* Broken client, let it die instead of us */
if (!surface->window)
{
meta_warning ("meta-wayland-surface: set_dbus_properties called with invalid window!\n");
return;
}
window = surface->window;
if (!window)
return;
meta_window_set_gtk_dbus_properties (surface->window,
meta_window_set_gtk_dbus_properties (window,
application_id,
unique_bus_name,
app_menu_path,
@@ -94,12 +92,17 @@ gtk_surface_set_modal (struct wl_client *client,
{
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = gtk_surface->surface;
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (gtk_surface->is_modal)
return;
gtk_surface->is_modal = TRUE;
meta_window_set_type (surface->window, META_WINDOW_MODAL_DIALOG);
meta_window_set_type (window, META_WINDOW_MODAL_DIALOG);
}
static void
@@ -108,12 +111,17 @@ gtk_surface_unset_modal (struct wl_client *client,
{
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = gtk_surface->surface;
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (!gtk_surface->is_modal)
return;
gtk_surface->is_modal = FALSE;
meta_window_set_type (surface->window, META_WINDOW_NORMAL);
meta_window_set_type (window, META_WINDOW_NORMAL);
}
static void
@@ -123,8 +131,9 @@ gtk_surface_present (struct wl_client *client,
{
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = gtk_surface->surface;
MetaWindow *window = surface->window;
MetaWindow *window;
window = surface->window;
if (!window)
return;

View File

@@ -89,7 +89,7 @@ unbind_resource (struct wl_resource *resource)
}
static int
create_anonymous_file (off_t size,
create_anonymous_file (off_t size,
GError **error)
{
static const char template[] = "mutter-shared-XXXXXX";
@@ -126,35 +126,66 @@ create_anonymous_file (off_t size,
return -1;
}
static void
send_keymap (MetaWaylandKeyboard *keyboard,
struct wl_resource *resource)
{
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
GError *error = NULL;
int fd;
char *keymap_area;
if (!xkb_info->keymap_string)
return;
fd = create_anonymous_file (xkb_info->keymap_size, &error);
if (fd < 0)
{
g_warning ("Creating a keymap file for %lu bytes failed: %s",
(unsigned long) xkb_info->keymap_size,
error->message);
g_clear_error (&error);
return;
}
keymap_area = mmap (NULL, xkb_info->keymap_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (keymap_area == MAP_FAILED)
{
g_warning ("Failed to mmap() %lu bytes\n",
(unsigned long) xkb_info->keymap_size);
close (fd);
return;
}
strcpy (keymap_area, xkb_info->keymap_string);
munmap (keymap_area, xkb_info->keymap_size);
wl_keyboard_send_keymap (resource,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
fd,
keyboard->xkb_info.keymap_size);
close (fd);
}
static void
inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard)
{
struct wl_resource *keyboard_resource;
wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
{
wl_keyboard_send_keymap (keyboard_resource,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
keyboard->xkb_info.keymap_fd,
keyboard->xkb_info.keymap_size);
}
send_keymap (keyboard, keyboard_resource);
wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
{
wl_keyboard_send_keymap (keyboard_resource,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
keyboard->xkb_info.keymap_fd,
keyboard->xkb_info.keymap_size);
}
send_keymap (keyboard, keyboard_resource);
}
static void
meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
struct xkb_keymap *keymap)
{
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
GError *error = NULL;
char *keymap_str;
size_t previous_size;
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
if (keymap == NULL)
{
@@ -162,60 +193,24 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
return;
}
g_clear_pointer (&xkb_info->keymap_string, g_free);
xkb_keymap_unref (xkb_info->keymap);
xkb_info->keymap = xkb_keymap_ref (keymap);
meta_wayland_keyboard_update_xkb_state (keyboard);
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
if (keymap_str == NULL)
xkb_info->keymap_string =
xkb_keymap_get_as_string (xkb_info->keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
if (!xkb_info->keymap_string)
{
g_warning ("failed to get string version of keymap");
g_warning ("Failed to get string version of keymap");
return;
}
previous_size = xkb_info->keymap_size;
xkb_info->keymap_size = strlen (keymap_str) + 1;
if (xkb_info->keymap_fd >= 0)
close (xkb_info->keymap_fd);
xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error);
if (xkb_info->keymap_fd < 0)
{
g_warning ("creating a keymap file for %lu bytes failed: %s",
(unsigned long) xkb_info->keymap_size,
error->message);
g_clear_error (&error);
goto err_keymap_str;
}
if (xkb_info->keymap_area)
munmap (xkb_info->keymap_area, previous_size);
xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size,
PROT_READ | PROT_WRITE,
MAP_SHARED, xkb_info->keymap_fd, 0);
if (xkb_info->keymap_area == MAP_FAILED)
{
g_warning ("failed to mmap() %lu bytes\n",
(unsigned long) xkb_info->keymap_size);
goto err_dev_zero;
}
strcpy (xkb_info->keymap_area, keymap_str);
free (keymap_str);
xkb_info->keymap_size = strlen (xkb_info->keymap_string) + 1;
inform_clients_of_new_keymap (keyboard);
notify_modifiers (keyboard);
return;
err_dev_zero:
close (xkb_info->keymap_fd);
xkb_info->keymap_fd = -1;
err_keymap_str:
free (keymap_str);
return;
}
static xkb_mod_mask_t
@@ -707,28 +702,12 @@ meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard)
maybe_restore_numlock_state (keyboard);
}
static void
meta_wayland_xkb_info_init (MetaWaylandXkbInfo *xkb_info)
{
xkb_info->keymap_fd = -1;
}
static void
meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
{
g_clear_pointer (&xkb_info->keymap, xkb_keymap_unref);
g_clear_pointer (&xkb_info->state, xkb_state_unref);
if (xkb_info->keymap_area)
{
munmap (xkb_info->keymap_area, xkb_info->keymap_size);
xkb_info->keymap_area = NULL;
}
if (xkb_info->keymap_fd >= 0)
{
close (xkb_info->keymap_fd);
xkb_info->keymap_fd = -1;
}
g_clear_pointer (&xkb_info->keymap_string, g_free);
}
void
@@ -1001,10 +980,7 @@ meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
wl_resource_set_implementation (resource, &keyboard_interface,
keyboard, unbind_resource);
wl_keyboard_send_keymap (resource,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
keyboard->xkb_info.keymap_fd,
keyboard->xkb_info.keymap_size);
send_keymap (keyboard, resource);
notify_key_repeat_for_resource (keyboard, resource);
@@ -1050,8 +1026,6 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard)
wl_list_init (&keyboard->resource_list);
wl_list_init (&keyboard->focus_resource_list);
meta_wayland_xkb_info_init (&keyboard->xkb_info);
keyboard->default_grab.interface = &default_keyboard_grab_interface;
keyboard->default_grab.keyboard = keyboard;
keyboard->grab = &keyboard->default_grab;

View File

@@ -74,9 +74,8 @@ typedef struct
{
struct xkb_keymap *keymap;
struct xkb_state *state;
int keymap_fd;
size_t keymap_size;
char *keymap_area;
char *keymap_string;
} MetaWaylandXkbInfo;
struct _MetaWaylandKeyboard

View File

@@ -185,6 +185,11 @@ zxdg_toplevel_v6_set_parent (struct wl_client *client,
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *transient_for = NULL;
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (parent_resource)
{
@@ -194,7 +199,7 @@ zxdg_toplevel_v6_set_parent (struct wl_client *client,
transient_for = parent_surface->window;
}
meta_window_set_transient_for (surface->window, transient_for);
meta_window_set_transient_for (window, transient_for);
}
static void
@@ -203,11 +208,16 @@ zxdg_toplevel_v6_set_title (struct wl_client *client,
const char *title)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (!g_utf8_validate (title, -1, NULL))
title = "";
meta_window_set_title (surface->window, title);
meta_window_set_title (window, title);
}
static void
@@ -216,11 +226,16 @@ zxdg_toplevel_v6_set_app_id (struct wl_client *client,
const char *app_id)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (!g_utf8_validate (app_id, -1, NULL))
app_id = "";
meta_window_set_wm_class (surface->window, app_id, app_id);
meta_window_set_wm_class (window, app_id, app_id);
}
static void
@@ -233,15 +248,20 @@ zxdg_toplevel_v6_show_window_menu (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
int monitor_scale;
window = surface->window;
if (!window)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL))
return;
monitor_scale = surface->window->monitor->scale;
meta_window_show_menu (surface->window, META_WINDOW_MENU_WM,
surface->window->buffer_rect.x + (x * monitor_scale),
surface->window->buffer_rect.y + (y * monitor_scale));
monitor_scale = window->monitor->scale;
meta_window_show_menu (window, META_WINDOW_MENU_WM,
window->buffer_rect.x + (x * monitor_scale),
window->buffer_rect.y + (y * monitor_scale));
}
static void
@@ -252,8 +272,13 @@ zxdg_toplevel_v6_move (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
gfloat x, y;
window = surface->window;
if (!window)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
return;
@@ -292,9 +317,14 @@ zxdg_toplevel_v6_resize (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
gfloat x, y;
MetaGrabOp grab_op;
window = surface->window;
if (!window)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
return;
@@ -309,6 +339,11 @@ zxdg_toplevel_v6_set_max_size (struct wl_client *client,
int32_t height)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (width < 0 || height < 0)
{
@@ -331,6 +366,11 @@ zxdg_toplevel_v6_set_min_size (struct wl_client *client,
int32_t height)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (width < 0 || height < 0)
{
@@ -351,9 +391,14 @@ zxdg_toplevel_v6_set_maximized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_force_placement (surface->window, TRUE);
meta_window_maximize (surface->window, META_MAXIMIZE_BOTH);
window = surface->window;
if (!window)
return;
meta_window_force_placement (window, TRUE);
meta_window_maximize (window, META_MAXIMIZE_BOTH);
}
static void
@@ -361,8 +406,13 @@ zxdg_toplevel_v6_unset_maximized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH);
window = surface->window;
if (!window)
return;
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
}
static void
@@ -371,15 +421,20 @@ zxdg_toplevel_v6_set_fullscreen (struct wl_client *client,
struct wl_resource *output_resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (output_resource)
{
MetaWaylandOutput *output = wl_resource_get_user_data (output_resource);
if (output)
meta_window_move_to_monitor (surface->window, output->logical_monitor->number);
meta_window_move_to_monitor (window, output->logical_monitor->number);
}
meta_window_make_fullscreen (surface->window);
meta_window_make_fullscreen (window);
}
static void
@@ -387,8 +442,13 @@ zxdg_toplevel_v6_unset_fullscreen (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_unmake_fullscreen (surface->window);
window = surface->window;
if (!window)
return;
meta_window_unmake_fullscreen (window);
}
static void
@@ -396,8 +456,13 @@ zxdg_toplevel_v6_set_minimized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_minimize (surface->window);
window = surface->window;
if (!window)
return;
meta_window_minimize (window);
}
static const struct zxdg_toplevel_v6_interface meta_wayland_zxdg_toplevel_v6_interface = {
@@ -598,11 +663,18 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window = surface->window;
MetaWindow *window;
MetaRectangle window_geometry;
MetaRectangle old_geometry;
gboolean geometry_changed;
window = surface->window;
if (!window)
{
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
return;
}
old_geometry = xdg_surface_priv->geometry;
surface_role_class =

View File

@@ -365,12 +365,38 @@ meta_wayland_output_new (MetaWaylandCompositor *compositor,
}
static void
nullify_logical_monitor (gpointer key,
gpointer value,
gpointer data)
make_output_resources_inert (MetaWaylandOutput *wayland_output)
{
GList *l;
for (l = wayland_output->resources; l; l = l->next)
{
struct wl_resource *output_resource = l->data;
wl_resource_set_user_data (output_resource, NULL);
}
g_list_free (wayland_output->resources);
wayland_output->resources = NULL;
for (l = wayland_output->xdg_output_resources; l; l = l->next)
{
struct wl_resource *xdg_output_resource = l->data;
wl_resource_set_user_data (xdg_output_resource, NULL);
}
g_list_free (wayland_output->xdg_output_resources);
wayland_output->xdg_output_resources = NULL;
}
static void
make_output_inert (gpointer key,
gpointer value,
gpointer data)
{
MetaWaylandOutput *wayland_output = value;
wayland_output->logical_monitor = NULL;
make_output_resources_inert (wayland_output);
}
static gboolean
@@ -420,7 +446,7 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
wayland_output);
}
g_hash_table_foreach (compositor->outputs, nullify_logical_monitor, NULL);
g_hash_table_foreach (compositor->outputs, make_output_inert, NULL);
g_timeout_add_seconds (10, delayed_destroy_outputs, compositor->outputs);
return new_table;
@@ -449,23 +475,7 @@ meta_wayland_output_finalize (GObject *object)
/* Make sure the wl_output destructor doesn't try to access MetaWaylandOutput
* after we have freed it.
*/
for (l = wayland_output->resources; l; l = l->next)
{
struct wl_resource *output_resource = l->data;
wl_resource_set_user_data (output_resource, NULL);
}
g_list_free (wayland_output->resources);
for (l = wayland_output->xdg_output_resources; l; l = l->next)
{
struct wl_resource *xdg_output_resource = l->data;
wl_resource_set_user_data (xdg_output_resource, NULL);
}
g_list_free (wayland_output->xdg_output_resources);
make_output_resources_inert (wayland_output);
G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object);
}
@@ -582,6 +592,9 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
wayland_output->xdg_output_resources =
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
if (!wayland_output->logical_monitor)
return;
send_xdg_output_events (xdg_output_resource,
wayland_output,
wayland_output->logical_monitor,

View File

@@ -72,8 +72,6 @@ struct _MetaWaylandCompositor
MetaWaylandSeat *seat;
MetaWaylandTabletManager *tablet_manager;
GHashTable *scheduled_surface_associations;
};
#endif /* META_WAYLAND_PRIVATE_H */

View File

@@ -83,7 +83,7 @@ meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface,
meta_wayland_surface_role_get_surface (surface_role);
meta_wayland_surface_set_window (surface, window);
meta_window_update_monitor (window, FALSE);
meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE);
}
void

View File

@@ -54,7 +54,7 @@ G_DEFINE_TYPE (MetaWaylandSubsurface,
static void
sync_actor_subsurface_state (MetaWaylandSurface *surface)
{
ClutterActor *actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
MetaWindow *toplevel_window;
int geometry_scale;
int x, y;
@@ -99,8 +99,8 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
GSList *it;
MetaWaylandSurface *parent = surface->sub.parent;
ClutterActor *parent_actor =
clutter_actor_get_parent (CLUTTER_ACTOR (meta_wayland_surface_get_actor (parent)));
ClutterActor *surface_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
clutter_actor_get_parent (CLUTTER_ACTOR (parent->surface_actor));
ClutterActor *surface_actor = CLUTTER_ACTOR (surface->surface_actor);
for (it = surface->sub.pending_placement_ops; it; it = it->next)
{
@@ -113,7 +113,7 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
continue;
}
sibling_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (op->sibling));
sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
switch (op->placement)
{
@@ -234,7 +234,7 @@ meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass)
static void
unparent_actor (MetaWaylandSurface *surface)
{
ClutterActor *actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
ClutterActor *parent_actor;
parent_actor = clutter_actor_get_parent (actor);
@@ -471,13 +471,10 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
&surface->sub.parent_destroy_listener);
parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
if (meta_wayland_surface_get_actor (parent))
{
clutter_actor_add_child (CLUTTER_ACTOR (meta_wayland_surface_get_actor (parent)),
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)));
}
clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
CLUTTER_ACTOR (surface->surface_actor));
clutter_actor_set_reactive (CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)), TRUE);
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
}
static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {

View File

@@ -105,7 +105,6 @@ enum {
SURFACE_CONFIGURE,
SURFACE_SHORTCUTS_INHIBITED,
SURFACE_SHORTCUTS_RESTORED,
SURFACE_GEOMETRY_CHANGED,
N_SURFACE_SIGNALS
};
@@ -129,6 +128,18 @@ meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface
static MetaWaylandSurface *
meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role);
static void
surface_actor_mapped_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface);
static void
surface_actor_allocation_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface);
static void
surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface);
static void
window_position_changed (MetaWindow *window,
MetaWaylandSurface *surface);
@@ -301,7 +312,7 @@ surface_process_damage (MetaWaylandSurface *surface,
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (scaled_region, i, &rect);
meta_surface_actor_process_damage (meta_wayland_surface_get_actor (surface),
meta_surface_actor_process_damage (surface->surface_actor,
rect.x, rect.y,
rect.width, rect.height);
}
@@ -591,6 +602,15 @@ parent_surface_state_applied (gpointer data,
meta_wayland_subsurface_parent_state_applied (subsurface);
}
void
meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
MetaWaylandPendingState *pending)
{
wl_list_insert_list (&surface->pending_frame_callback_list,
&pending->frame_callback_list);
wl_list_init (&pending->frame_callback_list);
}
void
meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
MetaWaylandPendingState *pending)
@@ -644,14 +664,14 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
goto cleanup;
}
if (switched_buffer && meta_wayland_surface_get_actor (surface))
if (switched_buffer)
{
MetaShapedTexture *stex;
CoglTexture *texture;
CoglSnippet *snippet;
gboolean is_y_inverted;
stex = meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface));
stex = meta_surface_actor_get_texture (surface->surface_actor);
texture = meta_wayland_buffer_get_texture (pending->buffer);
snippet = meta_wayland_buffer_create_snippet (pending->buffer);
is_y_inverted = meta_wayland_buffer_is_y_inverted (pending->buffer);
@@ -675,9 +695,8 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
if (pending->scale > 0)
surface->scale = pending->scale;
if (meta_wayland_surface_get_actor (surface) &&
(!cairo_region_is_empty (pending->surface_damage) ||
!cairo_region_is_empty (pending->buffer_damage)))
if (!cairo_region_is_empty (pending->surface_damage) ||
!cairo_region_is_empty (pending->buffer_damage))
surface_process_damage (surface,
pending->surface_damage,
pending->buffer_damage);
@@ -712,13 +731,7 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
}
else
{
/* Since there is no role assigned to the surface yet, keep frame
* callbacks queued until a role is assigned and we know how
* the surface will be drawn.
*/
wl_list_insert_list (&surface->pending_frame_callback_list,
&pending->frame_callback_list);
wl_list_init (&pending->frame_callback_list);
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
if (pending->newly_attached)
{
@@ -752,6 +765,10 @@ cleanup:
static void
meta_wayland_surface_commit (MetaWaylandSurface *surface)
{
if (surface->pending->buffer &&
!meta_wayland_buffer_is_realized (surface->pending->buffer))
meta_wayland_buffer_realize (surface->pending->buffer);
/*
* If this is a sub-surface and it is in effective synchronous mode, only
* cache the pending surface state until either one of the following two
@@ -1139,7 +1156,7 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
surface->window = window;
clutter_actor_set_reactive (CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)), !!window);
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), !!window);
sync_drag_dest_funcs (surface);
if (was_unmapped)
@@ -1167,6 +1184,16 @@ wl_surface_destructor (struct wl_resource *resource)
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_mapped_notify,
surface);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_allocation_notify,
surface);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_position_notify,
surface);
g_clear_object (&surface->role);
/* If we still have a window at the time of destruction, that means that
@@ -1192,6 +1219,8 @@ wl_surface_destructor (struct wl_resource *resource)
if (surface->input_region)
cairo_region_destroy (surface->input_region);
g_object_unref (surface->surface_actor);
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
g_hash_table_foreach (surface->outputs_to_destroy_notify_id, surface_output_disconnect_signal, surface);
@@ -1213,6 +1242,30 @@ wl_surface_destructor (struct wl_resource *resource)
meta_wayland_compositor_repick (compositor);
}
static void
surface_actor_mapped_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
surface_actor_allocation_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
window_position_changed (MetaWindow *window,
MetaWaylandSurface *surface)
@@ -1227,6 +1280,21 @@ window_actor_effects_completed (MetaWindowActor *window_actor,
meta_wayland_surface_update_outputs_recursively (surface);
}
void
meta_wayland_surface_create_surface_actor (MetaWaylandSurface *surface)
{
MetaSurfaceActor *surface_actor;
surface_actor = meta_surface_actor_wayland_new (surface);
surface->surface_actor = g_object_ref_sink (surface_actor);
}
void
meta_wayland_surface_clear_surface_actor (MetaWaylandSurface *surface)
{
g_clear_object (&surface->surface_actor);
}
MetaWaylandSurface *
meta_wayland_surface_create (MetaWaylandCompositor *compositor,
struct wl_client *client,
@@ -1241,15 +1309,28 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id);
wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor);
surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
wl_list_init (&surface->pending_frame_callback_list);
g_signal_connect_object (surface->surface_actor,
"notify::allocation",
G_CALLBACK (surface_actor_allocation_notify),
surface, 0);
g_signal_connect_object (surface->surface_actor,
"notify::position",
G_CALLBACK (surface_actor_position_notify),
surface, 0);
g_signal_connect_object (surface->surface_actor,
"notify::mapped",
G_CALLBACK (surface_actor_mapped_notify),
surface, 0);
sync_drag_dest_funcs (surface);
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
meta_wayland_compositor_notify_surface_id (compositor, id, surface);
return surface;
}
@@ -1432,7 +1513,7 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface,
else
{
ClutterActor *actor =
CLUTTER_ACTOR (meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface)));
CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor));
clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy);
*sx /= surface->scale;
@@ -1448,7 +1529,7 @@ meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface,
float *y)
{
ClutterActor *actor =
CLUTTER_ACTOR (meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface)));
CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor));
ClutterVertex sv = {
.x = sx * surface->scale,
.y = sy * surface->scale,
@@ -1465,10 +1546,6 @@ static void
meta_wayland_surface_init (MetaWaylandSurface *surface)
{
surface->pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL);
g_signal_connect (surface, "geometry-changed",
G_CALLBACK (meta_wayland_surface_update_outputs_recursively),
NULL);
}
static void
@@ -1515,13 +1592,6 @@ meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
surface_signals[SURFACE_GEOMETRY_CHANGED] =
g_signal_new ("geometry-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
@@ -1729,18 +1799,3 @@ meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
}
MetaSurfaceActor *
meta_wayland_surface_get_actor (MetaWaylandSurface *surface)
{
if (!surface->role || !META_IS_WAYLAND_ACTOR_SURFACE (surface->role))
return NULL;
return meta_wayland_actor_surface_get_actor (META_WAYLAND_ACTOR_SURFACE (surface->role));
}
void
meta_wayland_surface_notify_geometry_changed (MetaWaylandSurface *surface)
{
g_signal_emit (surface, surface_signals[SURFACE_GEOMETRY_CHANGED], 0);
}

View File

@@ -137,6 +137,7 @@ struct _MetaWaylandSurface
/* Generic stuff */
struct wl_resource *resource;
MetaWaylandCompositor *compositor;
MetaSurfaceActor *surface_actor;
MetaWaylandSurfaceRole *role;
MetaWindow *window;
cairo_region_t *input_region;
@@ -230,6 +231,10 @@ void meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurf
void meta_wayland_surface_set_window (MetaWaylandSurface *surface,
MetaWindow *window);
void meta_wayland_surface_create_surface_actor (MetaWaylandSurface *surface);
void meta_wayland_surface_clear_surface_actor (MetaWaylandSurface *surface);
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
int new_x,
int new_y,
@@ -256,6 +261,9 @@ MetaWaylandSurface *meta_wayland_surface_get_toplevel (MetaWaylandSurface *surfa
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
void meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
MetaWaylandPendingState *pending);
void meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface);
void meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
@@ -298,8 +306,4 @@ void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
MetaWaylandSeat *seat);
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);
void meta_wayland_surface_notify_geometry_changed (MetaWaylandSurface *surface);
#endif

View File

@@ -632,13 +632,10 @@ meta_wayland_tablet_tool_get_relative_coordinates (MetaWaylandTabletTool *tool,
wl_fixed_t *sx,
wl_fixed_t *sy)
{
MetaSurfaceActor *surface_actor;
float xf, yf;
surface_actor = meta_wayland_surface_get_actor (surface);
clutter_event_get_coords (event, &xf, &yf);
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface_actor)),
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
xf, yf, &xf, &yf);
*sx = wl_fixed_from_double (xf) / surface->scale;

View File

@@ -191,6 +191,11 @@ xdg_toplevel_set_parent (struct wl_client *client,
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *transient_for = NULL;
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (parent_resource)
{
@@ -200,7 +205,7 @@ xdg_toplevel_set_parent (struct wl_client *client,
transient_for = parent_surface->window;
}
meta_window_set_transient_for (surface->window, transient_for);
meta_window_set_transient_for (window, transient_for);
}
static void
@@ -209,11 +214,16 @@ xdg_toplevel_set_title (struct wl_client *client,
const char *title)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (!g_utf8_validate (title, -1, NULL))
title = "";
meta_window_set_title (surface->window, title);
meta_window_set_title (window, title);
}
static void
@@ -222,11 +232,16 @@ xdg_toplevel_set_app_id (struct wl_client *client,
const char *app_id)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (!g_utf8_validate (app_id, -1, NULL))
app_id = "";
meta_window_set_wm_class (surface->window, app_id, app_id);
meta_window_set_wm_class (window, app_id, app_id);
}
static void
@@ -239,15 +254,20 @@ xdg_toplevel_show_window_menu (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
int monitor_scale;
window = surface->window;
if (!window)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL))
return;
monitor_scale = surface->window->monitor->scale;
meta_window_show_menu (surface->window, META_WINDOW_MENU_WM,
surface->window->buffer_rect.x + (x * monitor_scale),
surface->window->buffer_rect.y + (y * monitor_scale));
monitor_scale = window->monitor->scale;
meta_window_show_menu (window, META_WINDOW_MENU_WM,
window->buffer_rect.x + (x * monitor_scale),
window->buffer_rect.y + (y * monitor_scale));
}
static void
@@ -258,8 +278,13 @@ xdg_toplevel_move (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
float x, y;
window = surface->window;
if (!window)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
return;
@@ -298,9 +323,14 @@ xdg_toplevel_resize (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
gfloat x, y;
MetaGrabOp grab_op;
window = surface->window;
if (!window)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
return;
@@ -357,7 +387,11 @@ xdg_toplevel_set_maximized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window = surface->window;
MetaWindow *window;
window = surface->window;
if (!window)
return;
meta_window_force_placement (window, TRUE);
meta_window_maximize (window, META_MAXIMIZE_BOTH);
@@ -368,8 +402,13 @@ xdg_toplevel_unset_maximized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH);
window = surface->window;
if (!window)
return;
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
}
static void
@@ -378,6 +417,11 @@ xdg_toplevel_set_fullscreen (struct wl_client *client,
struct wl_resource *output_resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
window = surface->window;
if (!window)
return;
if (output_resource)
{
@@ -385,12 +429,12 @@ xdg_toplevel_set_fullscreen (struct wl_client *client,
if (output)
{
meta_window_move_to_monitor (surface->window,
meta_window_move_to_monitor (window,
output->logical_monitor->number);
}
}
meta_window_make_fullscreen (surface->window);
meta_window_make_fullscreen (window);
}
static void
@@ -398,8 +442,13 @@ xdg_toplevel_unset_fullscreen (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_unmake_fullscreen (surface->window);
window = surface->window;
if (!window)
return;
meta_window_unmake_fullscreen (window);
}
static void
@@ -407,8 +456,13 @@ xdg_toplevel_set_minimized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
MetaWindow *window;
meta_window_minimize (surface->window);
window = surface->window;
if (!window)
return;
meta_window_minimize (window);
}
static const struct xdg_toplevel_interface meta_wayland_xdg_toplevel_interface = {
@@ -624,13 +678,25 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
MetaRectangle old_geometry;
gboolean geometry_changed;
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
window = surface->window;
if (!window)
{
meta_wayland_xdg_surface_reset (xdg_surface);
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
return;
}
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
{
MetaWaylandActorSurface *actor_surface =
META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
meta_wayland_xdg_surface_reset (xdg_surface);
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
pending);
return;
}
window = surface->window;
old_geometry = xdg_surface_priv->geometry;
surface_role_class =
@@ -712,8 +778,9 @@ meta_wayland_xdg_toplevel_reset (MetaWaylandXdgSurface *xdg_surface)
surface = meta_wayland_surface_role_get_surface (surface_role);
meta_wayland_surface_destroy_window (surface);
meta_wayland_surface_clear_surface_actor (surface);
meta_wayland_actor_surface_reset_actor (META_WAYLAND_ACTOR_SURFACE (surface_role));
meta_wayland_surface_create_surface_actor (surface);
window = meta_window_wayland_new (meta_get_display (), surface);
meta_wayland_shell_surface_set_window (shell_surface, window);
@@ -956,6 +1023,7 @@ meta_wayland_xdg_popup_commit (MetaWaylandSurfaceRole *surface_role,
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
{
meta_wayland_xdg_surface_reset (xdg_surface);
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
return;
}

View File

@@ -46,7 +46,6 @@
#include "meta-wayland-inhibit-shortcuts.h"
#include "meta-wayland-inhibit-shortcuts-dialog.h"
#include "meta-xwayland-grab-keyboard.h"
#include "meta-xwayland.h"
static MetaWaylandCompositor _meta_wayland_compositor;
static char *_display_name_override;
@@ -307,8 +306,6 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
{
memset (compositor, 0, sizeof (MetaWaylandCompositor));
wl_list_init (&compositor->frame_callbacks);
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
}
void
@@ -485,62 +482,3 @@ meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor)
{
wl_display_flush_clients (compositor->wayland_display);
}
static void on_scheduled_association_unmanaged (MetaWindow *window,
gpointer user_data);
static void
meta_wayland_compositor_remove_surface_association (MetaWaylandCompositor *compositor,
int id)
{
MetaWindow *window;
window = g_hash_table_lookup (compositor->scheduled_surface_associations,
GINT_TO_POINTER (id));
if (window)
{
g_signal_handlers_disconnect_by_func (window,
on_scheduled_association_unmanaged,
GINT_TO_POINTER (id));
g_hash_table_remove (compositor->scheduled_surface_associations,
GINT_TO_POINTER (id));
}
}
static void
on_scheduled_association_unmanaged (MetaWindow *window,
gpointer user_data)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
meta_wayland_compositor_remove_surface_association (compositor,
GPOINTER_TO_INT (user_data));
}
void
meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor,
int id,
MetaWindow *window)
{
g_signal_connect (window, "unmanaged",
G_CALLBACK (on_scheduled_association_unmanaged),
GINT_TO_POINTER (id));
g_hash_table_insert (compositor->scheduled_surface_associations,
GINT_TO_POINTER (id), window);
}
void
meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
int id,
MetaWaylandSurface *surface)
{
MetaWindow *window;
window = g_hash_table_lookup (compositor->scheduled_surface_associations,
GINT_TO_POINTER (id));
if (window)
{
meta_xwayland_associate_window_with_surface (window, surface);
meta_wayland_compositor_remove_surface_association (compositor, id);
}
}

View File

@@ -65,12 +65,5 @@ gboolean meta_wayland_compositor_is_shortcuts_inhibited (MetaWayl
void meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor);
void meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor,
int id,
MetaWindow *window);
void meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
int id,
MetaWaylandSurface *surface);
#endif

View File

@@ -371,8 +371,8 @@ scale_rect_size (MetaRectangle *rect,
}
static void
meta_window_wayland_update_main_monitor (MetaWindow *window,
gboolean user_op)
meta_window_wayland_update_main_monitor (MetaWindow *window,
MetaWindowUpdateMonitorFlags flags)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
@@ -392,7 +392,7 @@ meta_window_wayland_update_main_monitor (MetaWindow *window,
toplevel_window = meta_wayland_surface_get_toplevel_window (window->surface);
if (toplevel_window != window)
{
meta_window_update_monitor (toplevel_window, user_op);
meta_window_update_monitor (toplevel_window, flags);
window->monitor = toplevel_window->monitor;
return;
}
@@ -413,6 +413,12 @@ meta_window_wayland_update_main_monitor (MetaWindow *window,
return;
}
if (flags & META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE)
{
window->monitor = to;
return;
}
from_scale = meta_logical_monitor_get_scale (from);
to_scale = meta_logical_monitor_get_scale (to);

View File

@@ -85,6 +85,13 @@ meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab)
{
MetaWaylandSeat *seat = active_grab->seat;
if (seat->keyboard->grab->interface->key == meta_xwayland_keyboard_grab_key)
{
meta_wayland_keyboard_end_grab (active_grab->keyboard_grab.keyboard);
meta_wayland_keyboard_set_focus (active_grab->keyboard_grab.keyboard, NULL);
meta_display_sync_wayland_input_focus (meta_get_display ());
}
if (!active_grab->surface)
return;
@@ -104,13 +111,6 @@ meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab)
active_grab->window_associate_handler = 0;
}
if (seat->keyboard->grab->interface->key == meta_xwayland_keyboard_grab_key)
{
meta_wayland_keyboard_end_grab (active_grab->keyboard_grab.keyboard);
meta_wayland_keyboard_set_focus (active_grab->keyboard_grab.keyboard, NULL);
meta_display_sync_wayland_input_focus (meta_get_display ());
}
active_grab->surface = NULL;
}

View File

@@ -60,9 +60,9 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
meta_wayland_surface_role_xwayland,
META_TYPE_WAYLAND_ACTOR_SURFACE)
void
meta_xwayland_associate_window_with_surface (MetaWindow *window,
MetaWaylandSurface *surface)
static void
associate_window_with_surface (MetaWindow *window,
MetaWaylandSurface *surface)
{
MetaDisplay *display = window->display;
@@ -110,13 +110,58 @@ associate_window_with_surface_id (MetaXWaylandManager *manager,
if (resource)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
meta_xwayland_associate_window_with_surface (window, surface);
associate_window_with_surface (window, surface);
return TRUE;
}
else
return FALSE;
}
typedef struct {
MetaXWaylandManager *manager;
MetaWindow *window;
guint32 surface_id;
guint later_id;
} AssociateWindowWithSurfaceOp;
static void associate_window_with_surface_window_unmanaged (MetaWindow *window,
AssociateWindowWithSurfaceOp *op);
static void
associate_window_with_surface_op_free (AssociateWindowWithSurfaceOp *op)
{
if (op->later_id != 0)
meta_later_remove (op->later_id);
g_signal_handlers_disconnect_by_func (op->window,
(gpointer) associate_window_with_surface_window_unmanaged,
op);
g_free (op);
}
static void
associate_window_with_surface_window_unmanaged (MetaWindow *window,
AssociateWindowWithSurfaceOp *op)
{
associate_window_with_surface_op_free (op);
}
static gboolean
associate_window_with_surface_later (gpointer user_data)
{
AssociateWindowWithSurfaceOp *op = user_data;
op->later_id = 0;
if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id))
{
/* Not here? Oh well... nothing we can do */
g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc);
}
associate_window_with_surface_op_free (op);
return G_SOURCE_REMOVE;
}
void
meta_xwayland_handle_wl_surface_id (MetaWindow *window,
guint32 surface_id)
@@ -126,11 +171,21 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window,
if (!associate_window_with_surface_id (manager, window, surface_id))
{
/* No surface ID yet, schedule this association for whenever the
* surface is made known.
/* No surface ID yet... it should arrive after the next
* iteration through the loop, so queue a later and see
* what happens.
*/
meta_wayland_compositor_schedule_surface_association (compositor,
surface_id, window);
AssociateWindowWithSurfaceOp *op = g_new0 (AssociateWindowWithSurfaceOp, 1);
op->manager = manager;
op->window = window;
op->surface_id = surface_id;
op->later_id = meta_later_add (META_LATER_BEFORE_REDRAW,
associate_window_with_surface_later,
op,
NULL);
g_signal_connect (op->window, "unmanaged",
G_CALLBACK (associate_window_with_surface_window_unmanaged), op);
}
}

View File

@@ -41,8 +41,4 @@ void
meta_xwayland_handle_xwayland_grab (MetaWindow *window,
gboolean allow);
void
meta_xwayland_associate_window_with_surface (MetaWindow *window,
MetaWaylandSurface *surface);
#endif /* META_XWAYLAND_H */

View File

@@ -1365,6 +1365,12 @@ handle_other_xevent (MetaDisplay *display,
window = meta_window_x11_new (display, event->xmap.window,
FALSE, META_COMP_EFFECT_CREATE);
}
else if (window && window->restore_focus_on_map)
{
meta_window_focus (window,
meta_display_get_current_time_roundtrip (display));
}
break;
case MapRequest:
if (window == NULL)

View File

@@ -1483,8 +1483,8 @@ meta_window_x11_update_icon (MetaWindow *window,
}
static void
meta_window_x11_update_main_monitor (MetaWindow *window,
gboolean user_op)
meta_window_x11_update_main_monitor (MetaWindow *window,
MetaWindowUpdateMonitorFlags flags)
{
window->monitor = meta_window_calculate_main_logical_monitor (window);
}
@@ -3314,7 +3314,7 @@ meta_window_x11_configure_notify (MetaWindow *window,
priv->client_rect = window->rect;
window->buffer_rect = window->rect;
meta_window_update_monitor (window, FALSE);
meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE);
/* Whether an override-redirect window is considered fullscreen depends
* on its geometry.