Compare commits

...

36 Commits

Author SHA1 Message Date
9b2ee14eb1 tests/stacking: Add test checking the initial size
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
0a8286e008 tests/stacking: Add test for checking restored positions
Going maximized -> unmaximized should restore the previous position. The
same for untiling, or going from tiled, to maximized, to floating.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
42fecdb60b tests/test-runner: Add 'move' and 'assert_position'
Make it possible for tests to move the windows, and check their
positions.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
f84ec95d2f tests/restore-size: Also test that untiling restores correctly
Tiling, then untiling should restore to the size prior to tiling.

Tiling, maximizing, then unmaximizing should also restore to the size
prior to tiling.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
4b4cf96de1 tests/test-runner: Add tile and untile commands
This allows test cases to tile windows to the right or left, and untile,
just as the keyboard shortcuts does.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
c413dd9078 window: Set fall-back tile monitor if not set
When tiling, we want to set the tile monitor. To not have to do this
from the call site, make meta_window_tile() fall back to the current
monitor if nothing set it prior to the call.

This will make it more convenient for test cases that what to test
tiling.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
95f3fe7bd5 window: Add meta_window_untile()
It does the same as the untile keyboard shortcut does, i.e. handles
going back to saved maximized state. It's split out to be able to be
tested by the stacking tests.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
443dd146e1 tests/stacking: Test some maximize fullscreen interaction
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
2d982b678e tests/test-client: Add 'fullscreen' and 'unfullscreen' commands
This needs some hand holding when calculating the "full" size of the
window, as the titlebar isn't actually shown.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:13 +02:00
7cf61a392d tests/stacking: Check that unmaximize to new size works
A client that set a new fallback size while being maximized should not
restore to the one prior to being maximized.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
e190efb7af tests/stacking: Add test to verify we unmaximize correctly
The test tests that (for both X11 and Wayland) that:

 * The client unmaximizes after mapping maximized to a predictable size
 * That the client unmaximizes to the same size after toggling maximize

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
711adcb36e tests/test-runner: Add a 'wait_reconfigure' command
This makes sure that a client has properly responded to a configure
event it itself triggered. In practice, this is just two 'wait'
commands, with a 'dispatch' in between, which is needed because a single
one does not reliably include the two way round trip happening when e.g.
responding to a unmaximize configure event triggered by a unmaximize
request.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
b98ce96d09 tests/test-runner: Add 'assert_size' command
The 'assert_size' command checks that the size of the window, both
client side and compositor side, corresponds to an expected size set by
the test case.

The size comparison can only be done when the window is using 'csd', in
order for both the client and server to have the same amount of
understanding of the title bar. For ssd, the client cannot know how
large the title bar, thus cannot verify the full window size.

Sizes can be specified to mean the size of the monitor divided by a
number. This is that one can make sure a window is maximized or
fullscreened correctly.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
b7ad1fb086 tests/test-client: Remove shadow from X11 test client CSS style
Gtk is quite buggy and "fluid" in how it handles the shadow margins for
windows under X11. The "size" of the window fluctuate between including and
excluding a shadow margin in a way that causes issues, as there are no
atomic update of any state going on.

In order to avoid running into those particular issues now, lets get rid
of shadows so the margins are always zero, when the client is using the
X11 backend.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
d812cecc44 tests/test-client: Make 'resize' client command include the titlebar
To get some kind of consistency between what 'resize' means for the
compositor and the client, make the size correspond to the "frame rect"
of the window, i.e. the window geometry in the Wayland case, and the
window size including the titlebar in the X11 case.

This is so that the window size later can be reliably compared both in
the compositor and in the client using the same expected dimensions.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
965d74355a tests/test-client: Add line breaks to warning messages
When toying with the test client to try to reproduce issues (e.g.
writing commands on stdin to create and manipulate windows), when you
write a command incorrectly you'll get a warning printed to standard
out. The problem, however, is that it doesn't include a line break in
the end, meaning when you type the correct command, it won't be on a new
line.

Fix this minor annoyance by adding line breaks to all warning messages.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
92b1359d04 tests/test-runner: Plumb "resize" command
The test client could already understand the resize command, but they
could not be added to metatests as the command was not properly plumbed
via the test runner. Establish the plumbing for the resize command so
that resize tests can be added.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
c25fa19208 tests/test-client: Add commands to maximize/unmaximize
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
2020-04-15 15:59:12 +02:00
ad500ef4e5 input-settings: fix device list iteration
Dereference the loop variable rather than the original list head. This
fixes a regression introduced in 4413b86a3 ("backends: Replace
ClutterDeviceManager usage in favor of ClutterSeat", 2019-10-04) which
broke button scrolling with trackballs.

Closes:https://gitlab.gnome.org/GNOME/mutter/-/issues/1120

(cherry picked from commit 3e967d731a)
2020-04-12 23:43:01 +02:00
9a2471db47 wayland: preserve xkb_state on VT switch
On VT switch, the devices are removed, which means for Wayland disabling
the keyboard.

When the keyboard is disabled, the associated `xkb_state` is freed and
recreated whenever the keyboard is re-enabled when switching back to the
compositor VT.

That means the `xkb_state` for Wayland is lost whereas the same for
clutter is kept, which causes to a discrepancy with locked modifiers on
VT switch.

To avoid that issue, preserve the XKB info only to dispose it when the
keyboard is eventually finalized.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/344
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1185


(cherry picked from commit 5b30a52bbd)
2020-04-08 14:04:02 +00:00
db164bcfa2 wayland/xdnd: Add error traps around Xdnd* IPC
Make all of them spew criticals, except for XdndLeave as it's feasible
to expect the window we are sending the event to did disappear in the
way (eg. if the window is destroyed while the DnD operation is ongoing
and the pointer is over the window).

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2590

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1184
2020-04-07 20:38:02 +02:00
83553e3f6e backends/native: Translate coordinates of absolute motion events
The motion events of tablets for example need to be mapped on the
selected screen area if the input device is configured to use only a
part of the active logical monitor.
To achieve this behavior each motion event is transformed using the
transformation matrix set for the input device.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1118
2020-04-07 20:37:53 +02:00
3b2f6ae93d backends/x11: Fix access to WacomDevice
At some point we crossed the streams... In a short timespan we had
1f00aba92c merged, pushing WacomDevice to a common parent object,
and dcaa45fc0c implementing device grouping for X11.

The latter did not rely on the former, and just happened to
merge/compile without issues, but would promptly trigger a crash
whenever the API would be used.

Drop all traces of the WacomDevice internal to MetaInputDeviceX11.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1183


(cherry picked from commit f0718c7d95)
2020-04-07 17:48:09 +00:00
bc47f0a1ac clutter/stage: Don't assume stage relayouts reallocate everything
With the introduction of "shallow" relayouts, we are now able to enter
allocation cycles not only at the stage but also deeper down the
hierarchy if we know an actors allocation isn't affected by its children
since the NO_LAYOUT flag is set.

Now that means when queuing relayouts it's possible that
`priv->needs_allocation` gets set to TRUE for some actors down the
hierarchy, but not for actors higher up in the hierarchy. An actor tree
where that happens could look like that:

stage -> container -> container2 (NO_LAYOUT) -> textActor

With that tree, if the "textActor" queues a relayout, "container2" will
be added to the relayout hashtable of the stage and the actors "stage"
and "container" will have `priv->needs_allocation` set to FALSE.

Now if another relayout on the stage actor is queued,
`clutter_stage_queue_actor_relayout()` currently removes all the other
hashtable entries in favour of the stage entry, (wrongly) assuming that
will allocate everything. It doesn't allocate everything because in the
example above "container" has `priv->needs_allocation` set to FALSE,
which makes clutter_actor_allocate() return early before allocating its
children, so in the end "container2" will never get a new allocation.

To fix this, stop flushing the relayout hashtable when queuing a
stage-relayout and still add new entries to the hashtable if a stage
relayout is already queued to make sure we still go through all the
previously queued "shallow" relayouts. That shouldn't hurt performance,
too, because as soon as an actor got allocated once, it doesn't need an
allocation anymore and should bail out in clutter_actor_allocate() as
long as it's absolute position didn't change.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1173


(cherry picked from commit e74c2e42cf)
2020-04-07 16:47:32 +00:00
c8986d19e5 window: Check aliveness a bit less aggressively
Currently we check whether a window is alive everytime it's focused.
This means that an application that doesn't respond to the check-alive
event during startup always showing the "application froze" dialog,
without the user ever trying to interact with it.

An example where this tends to to happen is with games, and for this
particular scenario, it's purely an annoyance, as I never tried to
interact with the game window in the first place, so I don't care that
it's not responding - it's loading.

To avoid these unnecessary particular "app-is-frozen" popups, remove the
alive check from the focus function, and instead move it back to the
"meta_window_activate_full()" call. To also trigger it slightly more
often, also add it to the path that triggers the window focus when a
user actively clicks on the window.

This means that we currently check whether a window is alive on:

  * Any time the window is activated. This means e.g. alt-tab or
    selecting the window in the overview.
  * The user clicks on the window.

Note that the second only works for an already focused window on
Wayland, as on X11, we don't refocus it. This particular case isn't
changed with this commit, as we didn't call meta_window_focus() to begin
with here.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1182


(cherry picked from commit 8df3b21a51)
2020-04-07 13:23:21 +00:00
7baabc7ed0 x11: fix compilation if 'libwacom=false'
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1168


(cherry picked from commit a8f6cada88)
2020-04-06 14:57:57 +00:00
b0709504ea Update Slovak translation 2020-04-05 20:22:08 +00:00
7e94311e2e window-actor: Set viewport when blitting to screencast fb
This fixes an issue where a non-maximized screen casted window would be
stretched to fill the whole screen cast stream, instead of just the crop
that corresponds to the current window size.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1174


(cherry picked from commit a6f94696e2)
2020-04-03 16:30:26 +00:00
e339a57ddf cogl: Defend against empty or unallocated framebuffers
It isn't immediately obvious that this is impossible, because there's some
"action at a distance" going on with framebuffers that have their size
set lazily, after their textures get allocated; so let's make this a
critical warning rather than crashing.

In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.

Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172

Signed-off-by: Simon McVittie <smcv@debian.org>

(cherry picked from commit c389aadff9)
2020-04-03 13:49:34 +02:00
e3b2b90c72 cogl: Don't allow creating sized textures with 0 pixels
A texture with no pixels isn't a useful thing to have, and breaks
assumptions elsewhere. For example, CoglFramebuffer assumes that after
a texture has been allocated, it will have width and height both greater
than 0.

In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.

Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172

Signed-off-by: Simon McVittie <smcv@debian.org>

(cherry picked from commit 37eda498f2)
2020-04-03 13:48:46 +02:00
6f094bd399 clutter/master-clock-default: Sync timelines to hardware vsync
Previously clutter timelines advanced according to `g_source_get_time`.
But that meant the spatial stepping of animations was visibly sensitive to
any irregularities in the main loop. It also represented a time older [1]
than the intended presentation time of each frame.

Now we instead use `master_clock_get_next_presentation_time`. This ensures
we get the smoothness of hardware vsync as well as being closer to the
actual presentation time.

This means, for example, backends like Xorg that move the hardware cursor
independently of repaints will have their animations more closely matching
the hardware cursor position. So the cursor appears to stick more closely
when dragging windows or on the lock screen etc.

[1] "older" = (refresh_interval - sync_delay) = ~14ms for 60Hz

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

https://gitlab.gnome.org/GNOME/mutter/merge_requests/724
2020-04-03 10:59:36 +00:00
2c805524b4 clutter/stage: Add API to get_next_presentation_time
https://gitlab.gnome.org/GNOME/mutter/merge_requests/724
2020-04-03 10:59:36 +00:00
95c1baf3d1 clutter/click-action: Do not process captured event if action is disabled
Disabling a click action after a button-press but before a
button-release is captured makes ClutterClickAction connect to
captured-event and never disconnect.

This change fixes it by making sure the captured-event is only
processed if the action is still enabled, otherwise releasing
the action (reset state) and propagating the event.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1170


(cherry picked from commit 5f5ce08ba4)
2020-04-02 17:09:24 +00:00
6f9b5edd4d tests/actor-pick: Allocate actor before picking
Picking now only happens on allocated actors, but the
callback in the actor-pick test is not waiting for the
stage to run an allocation cycle. Ideally, we'd wait
for this cycle, but for now, forcing an allocation works
as well.

Allocate the overlay actor in the actor-pick test.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169


(cherry picked from commit 7f488e3e1d)
2020-03-31 23:13:42 +00:00
31809e1214 tests/actor-pick: Remove tabs
They're evil.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169


(cherry picked from commit 059d2144b2)
2020-03-31 23:13:15 +00:00
82f3bdd14e clutter/actor: Fix pick when actor is not allocated
When selecting the pick regions for an actor we were not considering
whether the actor was allocated and that was causing issues where the
preferred width/height of the actor was used when deciding whether
the actor should be considered as a pick target.

Check if the actor has a valid allocation, in addition to being mapped
and being in pick mode, in clutter_actor_should_pick_paint().

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169


(cherry picked from commit 902302a174)
2020-03-31 23:12:44 +00:00
31 changed files with 1033 additions and 138 deletions

View File

@ -2410,6 +2410,7 @@ clutter_actor_should_pick_paint (ClutterActor *self)
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
if (CLUTTER_ACTOR_IS_MAPPED (self) &&
clutter_actor_has_allocation (self) &&
(_clutter_context_get_pick_mode () == CLUTTER_PICK_ALL ||
CLUTTER_ACTOR_IS_REACTIVE (self)))
return TRUE;

View File

@ -346,6 +346,12 @@ on_captured_event (ClutterActor *stage,
ClutterModifierType modifier_state;
gboolean has_button = TRUE;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
{
clutter_click_action_release (action);
return CLUTTER_EVENT_PROPAGATE;
}
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
switch (clutter_event_type (event))

View File

@ -190,6 +190,26 @@ master_clock_get_swap_wait_time (ClutterMasterClockDefault *master_clock)
}
}
static int64_t
master_clock_get_next_presentation_time (ClutterMasterClockDefault *master_clock)
{
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
const GSList *stages, *l;
int64_t earliest = -1;
stages = clutter_stage_manager_peek_stages (stage_manager);
for (l = stages; l != NULL; l = l->next)
{
gint64 t = _clutter_stage_get_next_presentation_time (l->data);
if (earliest == -1 || (t != -1 && t < earliest))
earliest = t;
}
return earliest;
}
static void
master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
{
@ -466,7 +486,11 @@ clutter_clock_dispatch (GSource *source,
COGL_TRACE_BEGIN (ClutterMasterClockTick, "Master Clock (tick)");
/* Get the time to use for this frame */
master_clock->cur_tick = g_source_get_time (source);
master_clock->cur_tick = master_clock_get_next_presentation_time (master_clock);
/* On the first frame the backend might not have an answer */
if (master_clock->cur_tick <= 0)
master_clock->cur_tick = g_source_get_time (source);
#ifdef CLUTTER_ENABLE_DEBUG
master_clock->remaining_budget = master_clock->frame_budget;

View File

@ -78,6 +78,7 @@ void _clutter_stage_schedule_update (ClutterStage *stage);
gint64 _clutter_stage_get_update_time (ClutterStage *stage);
void _clutter_stage_clear_update_time (ClutterStage *stage);
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
int64_t _clutter_stage_get_next_presentation_time (ClutterStage *stage);
void clutter_stage_log_pick (ClutterStage *stage,
const graphene_point_t *vertices,

View File

@ -178,6 +178,22 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
iface->clear_update_time (window);
}
int64_t
_clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
/* If not implemented then just revert to the old behaviour... */
if (iface->get_next_presentation_time == NULL)
return _clutter_stage_window_get_update_time (window);
return iface->get_next_presentation_time (window);
}
void
_clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
gboolean accept_focus)

View File

@ -61,6 +61,8 @@ struct _ClutterStageWindowInterface
GList *(* get_views) (ClutterStageWindow *stage_window);
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
void (* finish_frame) (ClutterStageWindow *stage_window);
int64_t (* get_next_presentation_time) (ClutterStageWindow *stage_window);
};
ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *window);
@ -101,6 +103,8 @@ void _clutter_stage_window_finish_frame (ClutterStageWin
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
int64_t _clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window);
G_END_DECLS
#endif /* __CLUTTER_STAGE_WINDOW_H__ */

View File

@ -1320,15 +1320,9 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
{
ClutterStagePrivate *priv = stage->priv;
if (g_hash_table_contains (priv->pending_relayouts, stage))
return;
if (g_hash_table_size (priv->pending_relayouts) == 0)
_clutter_stage_schedule_update (stage);
if (actor == (ClutterActor *) stage)
g_hash_table_remove_all (priv->pending_relayouts);
g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
priv->pending_relayouts_version++;
}
@ -3751,6 +3745,21 @@ _clutter_stage_clear_update_time (ClutterStage *stage)
_clutter_stage_window_clear_update_time (stage_window);
}
int64_t
_clutter_stage_get_next_presentation_time (ClutterStage *stage)
{
ClutterStageWindow *stage_window;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return 0;
stage_window = _clutter_stage_get_window (stage);
if (stage_window == NULL)
return 0;
return _clutter_stage_window_get_next_presentation_time (stage_window);
}
ClutterPaintVolume *
_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage)
{

View File

@ -235,7 +235,12 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
if (stage_cogl->update_time == stage_cogl->last_update_time)
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
{
stage_cogl->update_time += refresh_interval;
next_presentation_time += refresh_interval;
}
stage_cogl->next_presentation_time = next_presentation_time;
}
static gint64
@ -256,6 +261,29 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
stage_cogl->last_update_time = stage_cogl->update_time;
stage_cogl->update_time = -1;
stage_cogl->next_presentation_time = -1;
}
static int64_t
clutter_stage_cogl_get_next_presentation_time (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
int64_t now = g_get_monotonic_time ();
if (stage_cogl->next_presentation_time > 0 &&
stage_cogl->next_presentation_time <= now)
{
CLUTTER_NOTE (BACKEND,
"Missed some frames. Something blocked for over "
"%" G_GINT64_FORMAT "ms.",
(now - stage_cogl->next_presentation_time) / 1000);
stage_cogl->update_time = -1;
clutter_stage_cogl_schedule_update (stage_window,
stage_cogl->last_sync_delay);
}
return stage_cogl->next_presentation_time;
}
static ClutterActor *
@ -1008,6 +1036,7 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
iface->schedule_update = clutter_stage_cogl_schedule_update;
iface->get_update_time = clutter_stage_cogl_get_update_time;
iface->clear_update_time = clutter_stage_cogl_clear_update_time;
iface->get_next_presentation_time = clutter_stage_cogl_get_next_presentation_time;
iface->redraw = clutter_stage_cogl_redraw;
}
@ -1053,6 +1082,7 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
stage->refresh_rate = 0.0;
stage->update_time = -1;
stage->next_presentation_time = -1;
}
static void

View File

@ -48,6 +48,7 @@ struct _ClutterStageCogl
gint64 last_presentation_time;
gint64 update_time;
int64_t last_update_time;
int64_t next_presentation_time;
/* We only enable clipped redraws after 2 frames, since we've seen
* a lot of drivers can struggle to get going and may output some

View File

@ -121,6 +121,9 @@ cogl_texture_2d_new_with_size (CoglContext *ctx,
{
CoglTextureLoader *loader;
g_return_val_if_fail (width >= 1, NULL);
g_return_val_if_fail (height >= 1, NULL);
loader = _cogl_texture_create_loader ();
loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED;
loader->src.sized.width = width;

View File

@ -132,8 +132,8 @@ _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer)
{
float gl_viewport_y;
g_assert (framebuffer->viewport_width >=0 &&
framebuffer->viewport_height >=0);
g_return_if_fail (framebuffer->viewport_width >= 0);
g_return_if_fail (framebuffer->viewport_height >= 0);
/* Convert the Cogl viewport y offset to an OpenGL viewport y offset
* NB: OpenGL defines its window and viewport origins to be bottom

167
po/sk.po
View File

@ -13,8 +13,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2018-02-06 04:14+0000\n"
"PO-Revision-Date: 2018-03-17 21:52+0100\n"
"POT-Creation-Date: 2020-03-30 20:11+0000\n"
"PO-Revision-Date: 2020-04-05 22:21+0200\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n"
@ -22,7 +22,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
"X-Generator: Poedit 2.0.6\n"
"X-Generator: Poedit 2.3\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@ -468,29 +468,47 @@ 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. • “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."
"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes "
"mutter request a low priority real-time scheduling. The executable or user "
"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — "
"initializes Xwayland lazily if there are X11 clients. Requires restart."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:134
msgid "Modifier to use to locate the pointer"
msgstr "Modifikátor použitý na lokalizovanie ukazovateľa"
#: data/org.gnome.mutter.gschema.xml.in:135
msgid "This key will initiate the “locate pointer” action."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:142
msgid "Timeout for check-alive ping"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:143
msgid ""
"Number of milliseconds a client has to respond to a ping request in order to "
"not be detected as frozen. Using 0 will disable the alive check completely."
msgstr ""
# summary
#: data/org.gnome.mutter.gschema.xml.in:145
#: data/org.gnome.mutter.gschema.xml.in:165
msgid "Select window from tab popup"
msgstr "Vybrať okno z rozbaľovacej ponuky tabulátora"
# summary
#: data/org.gnome.mutter.gschema.xml.in:150
#: data/org.gnome.mutter.gschema.xml.in:170
msgid "Cancel tab popup"
msgstr "Zrušit rozbaľovaciu ponuku tabulátora"
# PK: predpokladam ze to prepisane medzi tlacidlami
# description
#: data/org.gnome.mutter.gschema.xml.in:155
#: data/org.gnome.mutter.gschema.xml.in:175
msgid "Switch monitor configurations"
msgstr "Prepnúť nastavenia monitorov"
#: data/org.gnome.mutter.gschema.xml.in:160
#: data/org.gnome.mutter.gschema.xml.in:180
msgid "Rotates the built-in monitor configuration"
msgstr "Otočí nastavenie vstavaného monitora"
@ -554,23 +572,27 @@ msgid "Re-enable shortcuts"
msgstr "Znovu povoliť klávesové skratky"
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
msgid "Allow grabs with Xwayland"
msgid "Allow X11 grabs to lock keyboard focus with Xwayland"
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
msgid ""
"Allow keyboard grabs issued by X11 applications running in Xwayland to be "
"taken into account. For a X11 grab to be taken into account under Wayland, "
"the client must also either send a specific X11 ClientMessage to the root "
"window or be among the applications white-listed in key “xwayland-grab-"
"access-rules”."
"Allow all keyboard events to be routed to X11 “override redirect” windows "
"with a grab when running in Xwayland. This option is to support X11 clients "
"which map an “override redirect” window (which do not receive keyboard "
"focus) and issue a keyboard grab to force all keyboard events to that "
"window. This option is seldom used and has no effect on regular X11 windows "
"which can receive keyboard focus under normal circumstances. For a X11 grab "
"to be taken into account under Wayland, the client must also either send a "
"specific X11 ClientMessage to the root window or be among the applications "
"white-listed in key “xwayland-grab-access-rules”."
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
#: data/org.gnome.mutter.wayland.gschema.xml.in:84
msgid "Xwayland applications allowed to issue keyboard grabs"
msgstr ""
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
#: data/org.gnome.mutter.wayland.gschema.xml.in:85
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 "
@ -587,7 +609,7 @@ msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2260
#: src/backends/meta-input-settings.c:2631
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Prepínač režimu (skupina č. %d)"
@ -597,53 +619,61 @@ msgstr "Prepínač režimu (skupina č. %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:2654
msgid "Switch monitor"
msgstr "Prepnúť monitor"
#: src/backends/meta-input-settings.c:2285
#: src/backends/meta-input-settings.c:2656
msgid "Show on-screen help"
msgstr "Zobraziť pomocníka na obrazovke"
#: src/backends/meta-monitor-manager.c:900
#: src/backends/meta-monitor.c:226
msgid "Built-in display"
msgstr "Vstavaný displej"
#: src/backends/meta-monitor-manager.c:923
#: src/backends/meta-monitor.c:255
msgid "Unknown"
msgstr "Neznámy"
#: src/backends/meta-monitor-manager.c:925
#: src/backends/meta-monitor.c:257
msgid "Unknown Display"
msgstr "Neznámy displej"
#. 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.c:265
#, c-format
#| msgid "%s %s"
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor.c:273
#, c-format
#| msgid "%s %s"
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
"inches could not be calculated, e.g. Dell U2414H"
msgid "%s %s"
msgstr "%s %s"
#. Translators: this string will appear in Sysprof
#: src/backends/meta-profiler.c:79
msgid "Compositor"
msgstr "Kompozítor"
#. 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:533
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
msgstr ""
"Pre obrazovku č. %i na displeji „%s“ je spustený už iný správca rozloženia."
#: src/core/bell.c:194
#: src/core/bell.c:192
msgid "Bell event"
msgstr "Udalosť zvončeka"
# X window system preloz, napr. system na spravu okien X
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n"
# cmd desc
#: src/core/main.c:190
msgid "Disable connection to session manager"
@ -683,41 +713,45 @@ msgstr "Spustí ako kompozitor protokolu wayland"
msgid "Run as a nested compositor"
msgstr "Spustí ako kompozitor s vnoreným režimom"
#: src/core/main.c:240
#: src/core/main.c:238
msgid "Run wayland compositor without starting Xwayland"
msgstr ""
#: src/core/main.c:246
msgid "Run as a full display server, rather than nested"
msgstr "Spustí ako plnohodnotný zobrazovací server, namiesto vnoreného režimu"
#: src/core/main.c:246
#: src/core/main.c:252
msgid "Run with X11 backend"
msgstr "Spustí s obslužným programom X11"
# %s is a window title
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#: src/core/meta-close-dialog-default.c:151
#, c-format
msgid "“%s” is not responding."
msgstr "„%s“ neodpovedá."
#: src/core/meta-close-dialog-default.c:149
#: src/core/meta-close-dialog-default.c:153
msgid "Application is not responding."
msgstr "Aplikácia neodpovedá."
#: src/core/meta-close-dialog-default.c:154
#: src/core/meta-close-dialog-default.c:158
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Môžete chvíľu počkať na pokračovanie aplikácie, alebo ju môžete ukončiť."
#: src/core/meta-close-dialog-default.c:161
#: src/core/meta-close-dialog-default.c:165
msgid "_Force Quit"
msgstr "_Vynútiť ukončenie"
#: src/core/meta-close-dialog-default.c:161
#: src/core/meta-close-dialog-default.c:165
msgid "_Wait"
msgstr "_Počkať"
#: src/core/mutter.c:39
#: src/core/mutter.c:38
#, c-format
msgid ""
"mutter %s\n"
@ -733,21 +767,30 @@ msgstr ""
"Záruka sa NEPOSKYTUJE; ani na PREDAJNOSŤ alebo VHODNOSŤ PRE URČITÝ ÚČEL.\n"
# cmd desc
#: src/core/mutter.c:53
#: src/core/mutter.c:52
msgid "Print version"
msgstr "Zobrazí verziu"
# cmd desc
#: src/core/mutter.c:59
#: src/core/mutter.c:58
msgid "Mutter plugin to use"
msgstr "Použije zásuvný modul Mutter"
#: src/core/prefs.c:1997
#: src/core/prefs.c:1911
#, c-format
msgid "Workspace %d"
msgstr "Pracovný priestor č. %d"
#: src/core/screen.c:583
#: src/core/util.c:122
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n"
#: src/wayland/meta-wayland-tablet-pad.c:568
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Prepínač režimu: Režim č. %d"
#: src/x11/meta-x11-display.c:676
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
@ -756,21 +799,27 @@ msgstr ""
"Displej „%s“ už má správcu okien. Skúste použiť prepínač --replace, aby sa "
"aktuálny správca nahradil."
#: src/core/screen.c:668
#: src/x11/meta-x11-display.c:1089
msgid "Failed to initialize GDK\n"
msgstr "Zlyhala inicializácia GDK\n"
# X window system preloz, napr. system na spravu okien X
#: src/x11/meta-x11-display.c:1113
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n"
#: src/x11/meta-x11-display.c:1196
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "Obrazovka č. %d na displeji „%s“ nie je platná\n"
#: src/core/util.c:120
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n"
#: src/wayland/meta-wayland-tablet-pad.c:563
#: src/x11/meta-x11-selection-input-stream.c:460
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Prepínač režimu: Režim č. %d"
msgid "Format %s not supported"
msgstr "Formát %s nie je podporovaný"
#: src/x11/session.c:1818
#: src/x11/session.c:1821
msgid ""
"These windows do not support “save current setup” and will have to be "
"restarted manually next time you log in."
@ -779,7 +828,7 @@ msgstr ""
"prihlásení ich budete musieť znovu spustiť ručne."
# window title; wm_client_machine
#: src/x11/window-props.c:559
#: src/x11/window-props.c:569
#, c-format
msgid "%s (on %s)"
msgstr "%s (na %s)"

View File

@ -818,7 +818,7 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
for (l = devices; l; l = l->next)
{
device = devices->data;
device = l->data;
if (input_settings_class->is_trackball_device (input_settings, device))
input_settings_class->set_scroll_button (input_settings, device, button);

View File

@ -90,6 +90,7 @@ float meta_logical_monitor_get_scale (MetaLogicalMonitor *logical_monitor);
MetaMonitorTransform meta_logical_monitor_get_transform (MetaLogicalMonitor *logical_monitor);
META_EXPORT_TEST
MetaRectangle meta_logical_monitor_get_layout (MetaLogicalMonitor *logical_monitor);
META_EXPORT_TEST

View File

@ -424,6 +424,9 @@ new_absolute_motion_event (MetaSeatNative *seat,
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
event->motion.x = x;
event->motion.y = y;
meta_input_device_native_translate_coordinates (input_device, stage,
&event->motion.x,
&event->motion.y);
event->motion.axes = axes;
clutter_event_set_device (event, seat->core_pointer);
clutter_event_set_source_device (event, input_device);

View File

@ -38,7 +38,6 @@ struct _MetaInputDeviceX11
float current_y;
#ifdef HAVE_LIBWACOM
WacomDevice *wacom_device;
GArray *group_modes;
#endif
};
@ -93,13 +92,16 @@ meta_input_device_x11_is_grouped (ClutterInputDevice *device,
ClutterInputDevice *other_device)
{
#ifdef HAVE_LIBWACOM
MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
MetaInputDeviceX11 *other_device_x11 = META_INPUT_DEVICE_X11 (other_device);
WacomDevice *wacom_device, *other_wacom_device;
if (device_x11->wacom_device &&
other_device_x11->wacom_device &&
libwacom_compare (device_x11->wacom_device,
other_device_x11->wacom_device,
wacom_device =
meta_input_device_get_wacom_device (META_INPUT_DEVICE (device));
other_wacom_device =
meta_input_device_get_wacom_device (META_INPUT_DEVICE (other_device));
if (wacom_device && other_wacom_device &&
libwacom_compare (wacom_device,
other_wacom_device,
WCOMPARE_NORMAL) == 0)
return TRUE;
#endif
@ -122,9 +124,9 @@ meta_input_device_x11_is_grouped (ClutterInputDevice *device,
static void
meta_input_device_x11_finalize (GObject *object)
{
#ifdef HAVE_LIBWACOM
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object);
#ifdef HAVE_LIBWACOM
if (device_xi2->group_modes)
g_array_unref (device_xi2->group_modes);
#endif
@ -413,9 +415,12 @@ pad_switch_mode (ClutterInputDevice *device,
{
MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
uint32_t n_buttons, n_modes, button_group, next_mode, i;
WacomDevice *wacom_device;
GList *switch_buttons = NULL;
n_buttons = libwacom_get_num_buttons (device_x11->wacom_device);
wacom_device =
meta_input_device_get_wacom_device (META_INPUT_DEVICE (device));
n_buttons = libwacom_get_num_buttons (wacom_device);
for (i = 0; i < n_buttons; i++)
{

View File

@ -1300,6 +1300,7 @@ meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0);
cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
meta_rectangle_scale_double (bounds, resource_scale,
META_ROUNDING_STRATEGY_GROW,

View File

@ -3302,15 +3302,7 @@ handle_toggle_tiled (MetaDisplay *display,
if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) ||
(META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT))
{
window->tile_monitor_number = window->saved_maximize ? window->monitor->number
: -1;
window->tile_mode = window->saved_maximize ? META_TILE_MAXIMIZED
: META_TILE_NONE;
if (window->saved_maximize)
meta_window_maximize (window, META_MAXIMIZE_BOTH);
else
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
meta_window_untile (window);
}
else if (meta_window_can_tile_side_by_side (window))
{

View File

@ -656,6 +656,9 @@ void meta_window_unmanage (MetaWindow *window,
void meta_window_unmanage_on_idle (MetaWindow *window);
void meta_window_queue (MetaWindow *window,
guint queuebits);
META_EXPORT_TEST
void meta_window_untile (MetaWindow *window);
META_EXPORT_TEST
void meta_window_tile (MetaWindow *window,
MetaTileMode mode);

View File

@ -3148,6 +3148,22 @@ update_edge_constraints (MetaWindow *window)
}
}
void
meta_window_untile (MetaWindow *window)
{
window->tile_monitor_number =
window->saved_maximize ? window->monitor->number
: -1;
window->tile_mode =
window->saved_maximize ? META_TILE_MAXIMIZED
: META_TILE_NONE;
if (window->saved_maximize)
meta_window_maximize (window, META_MAXIMIZE_BOTH);
else
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
}
void
meta_window_tile (MetaWindow *window,
MetaTileMode tile_mode)
@ -3164,6 +3180,10 @@ meta_window_tile (MetaWindow *window,
window->tile_monitor_number = -1;
return;
}
else
{
window->tile_monitor_number = window->monitor->number;
}
if (window->tile_mode == META_TILE_MAXIMIZED)
directions = META_MAXIMIZE_BOTH;
@ -3751,6 +3771,8 @@ meta_window_activate_full (MetaWindow *window,
meta_window_focus (window, timestamp);
else
meta_workspace_activate_with_focus (window->workspace, window, timestamp);
meta_window_check_alive (window, timestamp);
}
/* This function exists since most of the functionality in window_activate
@ -4790,8 +4812,6 @@ meta_window_focus (MetaWindow *window,
return;
}
meta_window_check_alive (window, timestamp);
META_WINDOW_GET_CLASS (window)->focus (window, timestamp);
if (window->display->event_route == META_EVENT_ROUTE_NORMAL)
@ -8349,6 +8369,7 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
"Focusing %s due to button %u press (display.c)\n",
window->desc, button);
meta_window_focus (window, event->any.time);
meta_window_check_alive (window, event->any.time);
}
else
/* However, do allow terminals to lose focus due to new

View File

@ -67,6 +67,9 @@ on_timeout (gpointer data)
}
else if (test_num == 2)
{
ClutterActorBox over_actor_box =
CLUTTER_ACTOR_BOX_INIT (0, 0, STAGE_WIDTH, STAGE_HEIGHT);
/* Make the actor visible but set a clip so that only some
of the actors are accessible */
clutter_actor_show (over_actor);
@ -76,6 +79,11 @@ on_timeout (gpointer data)
state->actor_width * (ACTORS_X - 4),
state->actor_height * (ACTORS_Y - 4));
/* Only allocated actors can be picked, so force an allocation
* of the overlay actor here.
*/
clutter_actor_allocate (over_actor, &over_actor_box, 0);
if (g_test_verbose ())
g_print ("Clipped covering actor:\n");
}
@ -175,10 +183,10 @@ actor_pick (void)
for (y = 0; y < ACTORS_Y; y++)
for (x = 0; x < ACTORS_X; x++)
{
ClutterColor color = { x * 255 / (ACTORS_X - 1),
y * 255 / (ACTORS_Y - 1),
128, 255 };
ClutterActor *rect = clutter_rectangle_new_with_color (&color);
ClutterColor color = { x * 255 / (ACTORS_X - 1),
y * 255 / (ACTORS_Y - 1),
128, 255 };
ClutterActor *rect = clutter_rectangle_new_with_color (&color);
clutter_actor_set_position (rect,
x * state.actor_width,
@ -187,9 +195,9 @@ actor_pick (void)
state.actor_width,
state.actor_height);
clutter_actor_add_child (state.stage, rect);
clutter_actor_add_child (state.stage, rect);
state.actors[y * ACTORS_X + x] = rect;
state.actors[y * ACTORS_X + x] = rect;
}
clutter_actor_show (state.stage);

View File

@ -141,6 +141,11 @@ stacking_tests = [
'override-redirect',
'set-override-redirect-parent',
'set-parent-exported',
'restore-size',
'unmaximize-new-size',
'fullscreen-maximize',
'restore-position',
'default-size',
]
foreach stacking_test: stacking_tests

View File

@ -0,0 +1,36 @@
new_client x x11
create x/1 csd
resize x/1 300 400
show x/1
wait
assert_size x/1 300 400
resize x/1 200 300
wait
assert_size x/1 200 300
hide x/1
show x/1
wait
assert_size x/1 200 300
new_client w wayland
create w/1 csd
resize w/1 300 400
show w/1
wait
assert_size w/1 300 400
resize w/1 200 300
wait_reconfigure
assert_size w/1 200 300
hide w/1
show w/1
wait_reconfigure
assert_size w/1 200 300

View File

@ -0,0 +1,73 @@
# Tests that the following works, both on Wayland and X11
# 1. Create a window with a known size
# 2. Maxmize window results in maximized size
# 3. Fullscreen window results in fullscreen size
# 4. Unfullscreen window results in maximized size
# 5. Unmaximize window results in original size
# 6. Toggling fullscreen ends up with original size
new_client w wayland
create w/1 csd
resize w/1 500 400
show w/1
wait
assert_size w/1 500 400
maximize w/1
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
fullscreen w/1
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
unfullscreen w/1
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize w/1
wait_reconfigure
assert_size w/1 500 400
fullscreen w/1
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
unfullscreen w/1
wait_reconfigure
assert_size w/1 500 400
new_client x x11
create x/1 csd
resize x/1 500 400
show x/1
wait
assert_size x/1 500 400
maximize x/1
wait_reconfigure
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
fullscreen x/1
wait_reconfigure
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
unfullscreen x/1
wait_reconfigure
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize x/1
wait_reconfigure
assert_size x/1 500 400
fullscreen x/1
wait_reconfigure
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
unfullscreen x/1
wait_reconfigure
assert_size x/1 500 400

View File

@ -0,0 +1,73 @@
# X11
new_client x x11
create x/1 csd
show x/1
move x/1 100 100
assert_position x/1 100 100
maximize x/1
wait_reconfigure
assert_position x/1 0 0
unmaximize x/1
wait_reconfigure
assert_position x/1 100 100
tile x/1 left
wait
assert_position x/1 0 0
untile x/1
wait
assert_position x/1 100 100
tile x/1 left
wait
assert_position x/1 0 0
maximize x/1
wait_reconfigure
assert_position x/1 0 0
unmaximize x/1
wait_reconfigure
assert_position x/1 100 100
# Wayland
new_client w wayland
create w/1 csd
show w/1
move w/1 100 100
assert_position w/1 100 100
maximize w/1
wait_reconfigure
assert_position w/1 0 0
unmaximize w/1
wait_reconfigure
assert_position w/1 100 100
tile w/1 left
wait_reconfigure
assert_position w/1 0 0
untile w/1
wait
assert_position w/1 100 100
tile w/1 left
wait
assert_position w/1 0 0
maximize w/1
wait_reconfigure
assert_position w/1 0 0
unmaximize w/1
wait_reconfigure
assert_position w/1 100 100

View File

@ -0,0 +1,93 @@
# Check that X11 clients restore to their right size after unmaximize
# or untile
new_client x x11
create x/1 csd
resize x/1 500 400
maximize x/1
show x/1
wait
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize x/1
wait
assert_size x/1 500 400
resize x/1 300 200
maximize x/1
wait
unmaximize x/1
wait
assert_size x/1 300 200
tile x/1 right
wait
assert_size x/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
untile x/1
wait
assert_size x/1 300 200
tile x/1 left
wait
assert_size x/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
maximize x/1
wait_reconfigure
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize x/1
wait_reconfigure
assert_size x/1 300 200
# Check that Wayland clients restore to their right size after unmaximize
# or untile
new_client w wayland
create w/1 csd
resize w/1 150 300
maximize w/1
show w/1
wait
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize w/1
wait_reconfigure
assert_size w/1 150 300
resize w/1 300 200
maximize w/1
wait
unmaximize w/1
wait_reconfigure
assert_size w/1 300 200
tile w/1 right
wait
assert_size w/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
untile w/1
wait
assert_size w/1 300 200
tile w/1 left
wait
assert_size w/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
maximize w/1
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize w/1
wait_reconfigure
assert_size w/1 300 200

View File

@ -0,0 +1,22 @@
# This is only tested on Wayland since it's broken on X11
new_client w wayland
create w/1 csd
resize w/1 500 400
show w/1
wait
assert_size w/1 500 400
maximize w/1
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
resize w/1 300 500
wait_reconfigure
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
unmaximize w/1
wait_reconfigure
assert_size w/1 300 500

View File

@ -48,7 +48,7 @@ window_export_handle_cb (GdkWindow *window,
if (!gdk_wayland_window_set_transient_for_exported (gdk_window,
(gchar *) handle_str))
g_print ("Fail to set transient_for exported window handle %s", handle_str);
g_print ("Fail to set transient_for exported window handle %s\n", handle_str);
gdk_window_set_modal_hint (gdk_window, TRUE);
}
@ -57,7 +57,7 @@ lookup_window (const char *window_id)
{
GtkWidget *window = g_hash_table_lookup (windows, window_id);
if (!window)
g_print ("Window %s doesn't exist", window_id);
g_print ("Window %s doesn't exist\n", window_id);
return window;
}
@ -242,6 +242,23 @@ handle_take_focus (GtkWidget *window,
}
}
static int
calculate_titlebar_height (GtkWindow *window)
{
GtkWidget *titlebar;
GdkWindow *gdk_window;
gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
if (gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_FULLSCREEN)
return 0;
titlebar = gtk_window_get_titlebar (window);
if (!titlebar)
return 0;
return gtk_widget_get_allocated_height (titlebar);
}
static void
process_line (const char *line)
{
@ -251,14 +268,14 @@ process_line (const char *line)
if (!g_shell_parse_argv (line, &argc, &argv, &error))
{
g_print ("error parsing command: %s", error->message);
g_print ("error parsing command: %s\n", error->message);
g_error_free (error);
return;
}
if (argc < 1)
{
g_print ("Empty command");
g_print ("Empty command\n");
goto out;
}
@ -268,13 +285,13 @@ process_line (const char *line)
if (argc < 2)
{
g_print ("usage: create <id> [override|csd]");
g_print ("usage: create <id> [override|csd]\n");
goto out;
}
if (g_hash_table_lookup (windows, argv[1]))
{
g_print ("window %s already exists", argv[1]);
g_print ("window %s already exists\n", argv[1]);
goto out;
}
@ -290,7 +307,7 @@ process_line (const char *line)
if (override && csd)
{
g_print ("override and csd keywords are exclusie");
g_print ("override and csd keywords are exclusive\n");
goto out;
}
@ -334,21 +351,21 @@ process_line (const char *line)
{
if (argc != 3)
{
g_print ("usage: set_parent <window-id> <parent-id>");
g_print ("usage: set_parent <window-id> <parent-id>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
{
g_print ("unknown window %s", argv[1]);
g_print ("unknown window %s\n", argv[1]);
goto out;
}
GtkWidget *parent_window = lookup_window (argv[2]);
if (!parent_window)
{
g_print ("unknown parent window %s", argv[2]);
g_print ("unknown parent window %s\n", argv[2]);
goto out;
}
@ -359,21 +376,21 @@ process_line (const char *line)
{
if (argc != 3)
{
g_print ("usage: set_parent_exported <window-id> <parent-id>");
g_print ("usage: set_parent_exported <window-id> <parent-id>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
{
g_print ("unknown window %s", argv[1]);
g_print ("unknown window %s\n", argv[1]);
goto out;
}
GtkWidget *parent_window = lookup_window (argv[2]);
if (!parent_window)
{
g_print ("unknown parent window %s", argv[2]);
g_print ("unknown parent window %s\n", argv[2]);
goto out;
}
@ -382,27 +399,27 @@ process_line (const char *line)
window_export_handle_cb,
window,
NULL))
g_print ("Fail to export handle for window id %s", argv[2]);
g_print ("Fail to export handle for window id %s\n", argv[2]);
}
else if (strcmp (argv[0], "accept_focus") == 0)
{
if (argc != 3)
{
g_print ("usage: %s <window-id> [true|false]", argv[0]);
g_print ("usage: %s <window-id> [true|false]\n", argv[0]);
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
{
g_print ("unknown window %s", argv[1]);
g_print ("unknown window %s\n", argv[1]);
goto out;
}
if (!wayland &&
window_has_x11_event_handler (window, handle_take_focus))
{
g_print ("Impossible to use %s for windows accepting take focus",
g_print ("Impossible to use %s for windows accepting take focus\n",
argv[1]);
goto out;
}
@ -414,26 +431,26 @@ process_line (const char *line)
{
if (argc != 3)
{
g_print ("usage: %s <window-id> [true|false]", argv[0]);
g_print ("usage: %s <window-id> [true|false]\n", argv[0]);
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
{
g_print ("unknown window %s", argv[1]);
g_print ("unknown window %s\n", argv[1]);
goto out;
}
if (wayland)
{
g_print ("%s not supported under wayland", argv[0]);
g_print ("%s not supported under wayland\n", argv[0]);
goto out;
}
if (window_has_x11_event_handler (window, handle_take_focus))
{
g_print ("Impossible to change %s for windows accepting take focus",
g_print ("Impossible to change %s for windows accepting take focus\n",
argv[1]);
goto out;
}
@ -473,32 +490,32 @@ process_line (const char *line)
{
if (argc != 3)
{
g_print ("usage: %s <window-id> [true|false]", argv[0]);
g_print ("usage: %s <window-id> [true|false]\n", argv[0]);
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
{
g_print ("unknown window %s", argv[1]);
g_print ("unknown window %s\n", argv[1]);
goto out;
}
if (wayland)
{
g_print ("%s not supported under wayland", argv[0]);
g_print ("%s not supported under wayland\n", argv[0]);
goto out;
}
if (gtk_window_get_accept_focus (GTK_WINDOW (window)))
{
g_print ("%s not supported for input windows", argv[0]);
g_print ("%s not supported for input windows\n", argv[0]);
goto out;
}
if (!g_object_get_qdata (G_OBJECT (window), can_take_focus_quark))
{
g_print ("%s not supported for windows with no WM_TAKE_FOCUS set",
g_print ("%s not supported for windows with no WM_TAKE_FOCUS set\n",
argv[0]);
goto out;
}
@ -512,7 +529,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: show <id>");
g_print ("usage: show <id>\n");
goto out;
}
@ -527,7 +544,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: hide <id>");
g_print ("usage: hide <id>\n");
goto out;
}
@ -541,7 +558,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: activate <id>");
g_print ("usage: activate <id>\n");
goto out;
}
@ -555,7 +572,7 @@ process_line (const char *line)
{
if (argc != 4)
{
g_print ("usage: resize <id> <width> <height>");
g_print ("usage: resize <id> <width> <height>\n");
goto out;
}
@ -565,13 +582,16 @@ process_line (const char *line)
int width = atoi (argv[2]);
int height = atoi (argv[3]);
gtk_window_resize (GTK_WINDOW (window), width, height);
int titlebar_height = calculate_titlebar_height (GTK_WINDOW (window));
gtk_window_resize (GTK_WINDOW (window),
width,
height - titlebar_height);
}
else if (strcmp (argv[0], "raise") == 0)
{
if (argc != 2)
{
g_print ("usage: raise <id>");
g_print ("usage: raise <id>\n");
goto out;
}
@ -585,7 +605,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: lower <id>");
g_print ("usage: lower <id>\n");
goto out;
}
@ -599,7 +619,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: destroy <id>");
g_print ("usage: destroy <id>\n");
goto out;
}
@ -614,7 +634,7 @@ process_line (const char *line)
{
if (argc != 1)
{
g_print ("usage: destroy_all");
g_print ("usage: destroy_all\n");
goto out;
}
@ -631,7 +651,7 @@ process_line (const char *line)
{
if (argc != 1)
{
g_print ("usage: sync");
g_print ("usage: sync\n");
goto out;
}
@ -644,13 +664,13 @@ process_line (const char *line)
if (argc != 3)
{
g_print ("usage: set_counter <counter> <value>");
g_print ("usage: set_counter <counter> <value>\n");
goto out;
}
if (wayland)
{
g_print ("usage: set_counter can only be used for X11");
g_print ("usage: set_counter can only be used for X11\n");
goto out;
}
@ -666,7 +686,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: minimize <id>");
g_print ("usage: minimize <id>\n");
goto out;
}
@ -680,7 +700,7 @@ process_line (const char *line)
{
if (argc != 2)
{
g_print ("usage: unminimize <id>");
g_print ("usage: unminimize <id>\n");
goto out;
}
@ -690,9 +710,95 @@ process_line (const char *line)
gtk_window_deiconify (GTK_WINDOW (window));
}
else if (strcmp (argv[0], "maximize") == 0)
{
if (argc != 2)
{
g_print ("usage: maximize <id>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
goto out;
gtk_window_maximize (GTK_WINDOW (window));
}
else if (strcmp (argv[0], "unmaximize") == 0)
{
if (argc != 2)
{
g_print ("usage: unmaximize <id>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
goto out;
gtk_window_unmaximize (GTK_WINDOW (window));
}
else if (strcmp (argv[0], "fullscreen") == 0)
{
if (argc != 2)
{
g_print ("usage: fullscreen <id>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
goto out;
gtk_window_fullscreen (GTK_WINDOW (window));
}
else if (strcmp (argv[0], "unfullscreen") == 0)
{
if (argc != 2)
{
g_print ("usage: unfullscreen <id>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
goto out;
gtk_window_unfullscreen (GTK_WINDOW (window));
}
else if (strcmp (argv[0], "assert_size") == 0)
{
int expected_width;
int expected_height;
int width;
int height;
if (argc != 4)
{
g_print ("usage: assert_size <id> <width> <height>\n");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
goto out;
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
height += calculate_titlebar_height (GTK_WINDOW (window));
expected_width = atoi (argv[2]);
expected_height = atoi (argv[3]);
if (expected_width != width || expected_height != height)
{
g_print ("Expected size %dx%d didn't match actual size %dx%d\n",
expected_width, expected_height,
width, height);
goto out;
}
}
else
{
g_print ("Unknown command %s", argv[0]);
g_print ("Unknown command %s\n", argv[0]);
goto out;
}
@ -770,6 +876,32 @@ main(int argc, char **argv)
gtk_init (NULL, NULL);
if (!wayland)
{
GdkScreen *screen;
GtkCssProvider *provider;
screen = gdk_screen_get_default ();
provider = gtk_css_provider_new ();
static const char *no_decoration_css =
"decoration {"
" border-radius: 0 0 0 0;"
" border-width: 0;"
" box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), 0 0 0 0 rgba(0, 0, 0, 0);"
" margin: 0px;"
"}";
if (!gtk_css_provider_load_from_data (provider,
no_decoration_css,
strlen (no_decoration_css),
&error))
{
g_printerr ("%s", error->message);
return 1;
}
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
windows = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
event_source_quark = g_quark_from_static_string ("event-source");

View File

@ -291,6 +291,30 @@ test_case_assert_focused (TestCase *test,
return *error == NULL;
}
static gboolean
test_case_assert_size (TestCase *test,
MetaWindow *window,
int expected_width,
int expected_height,
GError **error)
{
MetaRectangle frame_rect;
meta_window_get_frame_rect (window, &frame_rect);
if (frame_rect.width != expected_width ||
frame_rect.height != expected_height)
{
g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
"Expected size %dx%d didn't match actual size %dx%d",
expected_width, expected_height,
frame_rect.width, frame_rect.height);
return FALSE;
}
return TRUE;
}
static gboolean
test_case_check_xserver_stacking (TestCase *test,
GError **error)
@ -344,6 +368,55 @@ test_case_check_xserver_stacking (TestCase *test,
return *error == NULL;
}
static int
maybe_divide (const char *str,
int value)
{
if (strstr (str, "/") == str)
{
int divisor;
str += 1;
divisor = atoi (str);
value /= divisor;
}
return value;
}
static int
parse_window_size (const char *size_str)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor =
meta_monitor_manager_get_logical_monitors (monitor_manager)->data;
MetaRectangle logical_monitor_layout =
meta_logical_monitor_get_layout (logical_monitor);
int value;
if (strstr (size_str, "MONITOR_WIDTH") == size_str)
{
value = logical_monitor_layout.width;
size_str += strlen ("MONITOR_WIDTH");
value = maybe_divide (size_str, value);
}
else if (strstr (size_str, "MONITOR_HEIGHT") == size_str)
{
value = logical_monitor_layout.height;
size_str += strlen ("MONITOR_HEIGHT");
value = maybe_divide (size_str, value);
}
else
{
value = atoi (size_str);
}
return value;
}
static gboolean
test_case_do (TestCase *test,
int argc,
@ -504,12 +577,96 @@ test_case_do (TestCase *test,
test_client_wait_for_window_shown (client, window);
}
else if (strcmp (argv[0], "resize") == 0)
{
if (argc != 4)
BAD_COMMAND("usage: %s <client-id>/<window-id> width height", argv[0]);
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
if (!test_client_do (client, error, argv[0], window_id,
argv[2], argv[3], NULL))
return FALSE;
}
else if (strcmp (argv[0], "move") == 0)
{
if (argc != 4)
BAD_COMMAND("usage: %s <client-id>/<window-id> x y", argv[0]);
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
MetaWindow *window = test_client_find_window (client, window_id, error);
if (!window)
return FALSE;
meta_window_move_frame (window, TRUE, atoi (argv[2]), atoi (argv[3]));
}
else if (strcmp (argv[0], "tile") == 0)
{
if (argc != 3)
BAD_COMMAND("usage: %s <client-id>/<window-id> [right|left]", argv[0]);
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
MetaWindow *window = test_client_find_window (client, window_id, error);
if (!window)
return FALSE;
MetaTileMode tile_mode;
if (strcmp (argv[2], "right") == 0)
{
tile_mode = META_TILE_RIGHT;
}
else if (strcmp (argv[2], "left") == 0)
{
tile_mode = META_TILE_LEFT;
}
else
{
g_set_error (error,
TEST_RUNNER_ERROR,
TEST_RUNNER_ERROR_ASSERTION_FAILED,
"Invalid tile mode '%s'", argv[2]);
return FALSE;
}
meta_window_tile (window, tile_mode);
}
else if (strcmp (argv[0], "untile") == 0)
{
if (argc != 2)
BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]);
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
MetaWindow *window = test_client_find_window (client, window_id, error);
if (!window)
return FALSE;
meta_window_untile (window);
}
else if (strcmp (argv[0], "hide") == 0 ||
strcmp (argv[0], "activate") == 0 ||
strcmp (argv[0], "raise") == 0 ||
strcmp (argv[0], "lower") == 0 ||
strcmp (argv[0], "minimize") == 0 ||
strcmp (argv[0], "unminimize") == 0 ||
strcmp (argv[0], "maximize") == 0 ||
strcmp (argv[0], "unmaximize") == 0 ||
strcmp (argv[0], "fullscreen") == 0 ||
strcmp (argv[0], "unfullscreen") == 0 ||
strcmp (argv[0], "destroy") == 0)
{
if (argc != 2)
@ -547,6 +704,24 @@ test_case_do (TestCase *test,
if (!test_case_wait (test, error))
return FALSE;
}
else if (strcmp (argv[0], "wait_reconfigure") == 0)
{
if (argc != 1)
BAD_COMMAND("usage: %s", argv[0]);
/*
* Wait twice, so that we
* 1) First wait for any requests to configure has been made
* 2) Then wait for the new configuration has been applied
*/
if (!test_case_wait (test, error))
return FALSE;
if (!test_case_dispatch (test, error))
return FALSE;
if (!test_case_wait (test, error))
return FALSE;
}
else if (strcmp (argv[0], "dispatch") == 0)
{
if (argc != 1)
@ -582,6 +757,80 @@ test_case_do (TestCase *test,
if (!test_case_assert_focused (test, argv[1], error))
return FALSE;
}
else if (strcmp (argv[0], "assert_size") == 0)
{
if (argc != 4)
{
BAD_COMMAND("usage: %s <client-id>/<window-id> <width> <height>",
argv[0]);
}
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
MetaWindow *window = test_client_find_window (client, window_id, error);
if (!window)
return FALSE;
if (meta_window_get_frame (window))
{
g_set_error (error,
TEST_RUNNER_ERROR,
TEST_RUNNER_ERROR_ASSERTION_FAILED,
"Can only assert size of CSD window");
return FALSE;
}
int width = parse_window_size (argv[2]);
int height = parse_window_size (argv[3]);
g_autofree char *width_str = g_strdup_printf ("%d", width);
g_autofree char *height_str = g_strdup_printf ("%d", height);
if (!test_client_do (client, error, argv[0],
window_id,
width_str,
height_str,
NULL))
return FALSE;
if (!test_case_assert_size (test, window,
width, height,
error))
return FALSE;
}
else if (strcmp (argv[0], "assert_position") == 0)
{
if (argc != 4)
{
BAD_COMMAND("usage: %s <client-id>/<window-id> <x> <y>",
argv[0]);
}
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
MetaWindow *window = test_client_find_window (client, window_id, error);
if (!window)
return FALSE;
MetaRectangle frame_rect;
meta_window_get_frame_rect (window, &frame_rect);
int x = atoi (argv[2]);
int y = atoi (argv[3]);
if (frame_rect.x != x || frame_rect.y != y)
{
g_set_error (error,
TEST_RUNNER_ERROR,
TEST_RUNNER_ERROR_ASSERTION_FAILED,
"Expected window position (%d, %d) doesn't match (%d, %d)",
x, y, frame_rect.x, frame_rect.y);
return FALSE;
}
}
else
{
BAD_COMMAND("Unknown command %s", argv[0]);

View File

@ -603,7 +603,6 @@ meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard)
meta_wayland_keyboard_end_grab (keyboard);
meta_wayland_keyboard_set_focus (keyboard, NULL);
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
wl_list_remove (&keyboard->resource_list);
wl_list_init (&keyboard->resource_list);
@ -917,7 +916,18 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard)
keyboard_handle_focus_surface_destroy;
}
static void
meta_wayland_keyboard_finalize (GObject *object)
{
MetaWaylandKeyboard *keyboard = META_WAYLAND_KEYBOARD (object);
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
}
static void
meta_wayland_keyboard_class_init (MetaWaylandKeyboardClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_wayland_keyboard_finalize;
}

View File

@ -145,6 +145,8 @@ xdnd_send_enter (MetaXWaylandDnd *dnd,
gchar **p;
struct wl_array *source_mime_types;
meta_x11_error_trap_push (x11_display);
data_source = compositor->seat->data_device.dnd_data_source;
xev.xclient.type = ClientMessage;
xev.xclient.message_type = xdnd_atoms[ATOM_DND_ENTER];
@ -189,6 +191,9 @@ xdnd_send_enter (MetaXWaylandDnd *dnd,
}
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
g_critical ("Error sending XdndEnter");
}
static void
@ -205,7 +210,9 @@ xdnd_send_leave (MetaXWaylandDnd *dnd,
xev.xclient.window = dest;
xev.xclient.data.l[0] = x11_display->selection.xwindow;
meta_x11_error_trap_push (x11_display);
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
meta_x11_error_trap_pop (x11_display);
}
static void
@ -241,7 +248,11 @@ xdnd_send_position (MetaXWaylandDnd *dnd,
xev.xclient.data.l[3] = time;
xev.xclient.data.l[4] = action_to_atom (action);
meta_x11_error_trap_push (x11_display);
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
g_critical ("Error sending XdndPosition");
}
static void
@ -261,7 +272,11 @@ xdnd_send_drop (MetaXWaylandDnd *dnd,
xev.xclient.data.l[0] = x11_display->selection.xwindow;
xev.xclient.data.l[2] = time;
meta_x11_error_trap_push (x11_display);
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
g_critical ("Error sending XdndDrop");
}
static void
@ -289,7 +304,11 @@ xdnd_send_finished (MetaXWaylandDnd *dnd,
xev.xclient.data.l[2] = action_to_atom (action);
}
meta_x11_error_trap_push (x11_display);
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
g_critical ("Error sending XdndFinished");
}
static void
@ -297,6 +316,7 @@ xdnd_send_status (MetaXWaylandDnd *dnd,
Window dest,
uint32_t action)
{
MetaX11Display *x11_display = meta_get_display ()->x11_display;
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
XEvent xev = { 0 };
@ -312,7 +332,11 @@ xdnd_send_status (MetaXWaylandDnd *dnd,
if (xev.xclient.data.l[4])
xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */
meta_x11_error_trap_push (x11_display);
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
g_critical ("Error sending Xdndstatus");
}
static void