Compare commits

..

27 Commits

Author SHA1 Message Date
Benjamin Berg
07aef68670 startup: Fix possible crash in startup notifications
A GAppInfo is not guaranteed to have a filename or an application (or
rather a desktop ID). Add a check for application_id to be non-NULL
before trying to call sn_launcher_set_application_id, which would crash
otherwise.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1392
2020-07-31 15:27:08 +02:00
Jonas Ådahl
34579d71cc remote-access-handle: Add 'is-recording' property
Will be TRUE if it is a screen cast session where all streams have the
'is-recording' set to TRUE. For other screen casts or remote desktop
sessions, it'll be FALSE.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1377
2020-07-31 10:41:38 +02:00
Jonas Ådahl
153357cd36 screen-cast: Add 'is-recording' option to record methods
This can be used by the Shell to change the UI to be the same as the
current built in screen recording.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1377
2020-07-31 10:41:15 +02:00
Jonas Ådahl
14cd78a016 screen-cast: Add screen cast flag to streams
Intended to be used to pass state from screen cast clients down the
line. The first use case will be a boolean whether a screen cast is a
plain recording or not, e.g. letting the Shell decide whether to use a
red dot as the icon, or the generic "sharing" symbol.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1377
2020-07-30 09:51:16 +02:00
Daniel García Moreno
109fbdbac9 clutter/actor: Add get_transformed_extents
The clutter_actor_get_transformed_position returns the position of the
top left point of the actor, with the actor transformations. That means
that if the actor is rotated 180º it'll return the "screen" position top
right.

Using this to calculate if the actor is in the screen is causing
problems when it's transformted.

This patch adds a new function clutter_actor_get_transformed_extents,
that will return the transformed actor bounding rect.

This new function is used on the update_stage_views so the actor will
get updated. this way rotated actors will be updated if they are on the
screen.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1386
2020-07-29 11:12:26 +02:00
Christian Hergert
2c08eb6d16 build: bump ABI to sysprof-capture-4
GLib will now be linking against sysprof-capture-4.a. To support that,
sysprof had to remove the GLib dependency from sysprof-capture-4 which
had the side-effect of breaking ABi.

This bumps the dependency and includes a fallback to compile just the
libsysprof-capture-4.a using a subproject wrap.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1352
2020-07-28 11:13:30 -07:00
Olivier Fourdan
ca64a308eb surface-actor: Restore drop shadow with server-side decorations
Commit 510cbef15a changed the logic in `handle_update()` for X11 window
actors to return early if the surface is not an X11 surface.

That works fine for plain Xorg, but on Xwayland, the surface is actually
a Wayland surface, therefore the function returns early before updating
the drop shadows of server-side decorations for X11 windows.

Change the test logic to restore drops shadows with Xwayland windows.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1384
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1358
2020-07-28 13:21:23 +00:00
Olivier Fourdan
d0ee02fae7 cleanup: Remove duplicate semicolons in C code
No functional change, it just hurts my eyes when reading the code.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1385
2020-07-28 10:32:46 +02:00
Sebastian Keller
c7d14244b1 x11: Add STRING/UTF8_STRING targets for selection sources lacking them
The memory selection source was only providing the "text/plain" or the
"text/plain;charset=utf-8" mimetype, but not "STRING" or "UTF8_STRING",
which some X11 clients, like wine, are looking for. This was breaking
pasting from the clipboard in wine applications.

Fix this by adding those targets when they are missing and the selection
source provides the corresponding mimetypes.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1369
2020-07-27 08:34:40 +00:00
Sebastian Keller
e1c4e55880 x11: Handle selection windows being destroyed before new selection
Wine destroys its old selection window immediately before creating a new
selection. This would trigger restoring the clipboard, which would
overwrite the new selection with the old one. The selection window
however can also be destroyed as part of the shutdown process of
applications, such as Chromium for example. In those cases we want the
clipboard to be restored after the selection window has been destroyed.

Solve this by not immediately restoring the clipboard but instead using
a timeout which can be canceled by any new selection owner, such as in
the Wine case.

Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1338
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1369
2020-07-27 08:34:40 +00:00
Martin Whitaker
7b79fcee45 Fix segfaults on 32-bit systems.
The new "id" properties for the MetaCrtc* and MetaOuput* objects are 64-bit
values, so take care to pass 64-bit values when calling g_object_new.

Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1343.
2020-07-24 11:24:08 +00:00
Carlos Garnacho
ac6990ef51 build: Depend on an up-to-date gsettings-desktop-schemas
Update the dependency as we use newer settings there.

Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3004

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1376
2020-07-21 12:54:42 +02:00
Erik Kurzinger
0aa4bab539 kms: Use custom page flip function when retrying failed flips
When using its EGLStream-based presentation path with the proprietary NVIDIA
driver, mutter will use a different function to process page flips -
custom_egl_stream_page_flip.  If that fails due to an EBUSY error, it will
attempt to retry the flip.  However, when retrying, it unconditionally uses the
libdrm-based path. In practice, this causes a segfault when attempting to
access plane_assignments->fb_id, since plane_assignments will be NULL in the
EGLStream case.  The issue can be reproduced reliably by VT-switching away from
GNOME and back again while an EGL application is running.

This patch has mutter also use the custom page flip function when retrying the
failed flip.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1375
2020-07-19 12:50:37 -07:00
Rafael Fontenelle
224db78409 Update Brazilian Portuguese translation
(cherry picked from commit ef3dac7064)
2020-07-17 21:36:43 +00:00
Daniel van Vugt
7658e07beb Include the pkgconfig-specified gdesktop-enums.h
Instead of blindly hoping that `$INCLUDE` contains the parent directory
of `gsettings-desktop-schemas`.

Because `gsettings-desktop-schemas.pc` says:
```
Cflags: -I/SOME/DIRECTORY/gsettings-desktop-schemas
```
Which means to include the version that Meson has configured you need
to drop the directory prefix and only `#include <gdesktop-enums.h>`.

This fixes a build failure with local installs triggered by 775ec67a44
but it's also the right thing to do™.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1370
2020-07-13 17:30:20 +08:00
Fabio Tomat
1faba58ccc Update Friulian translation 2020-07-12 16:35:03 +00:00
Giusy Margarita
775ec67a44 Add tap-button-map and tap-and-drag-lock support to X11 and Wayland
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1319
2020-07-10 13:31:46 +00:00
Jonas Ådahl
d67ba3ea65 screen-cast/src: Remove follow up timeout source on disable
We failed to remove the timeout source when disabling, meaning that if a
follow up was scheduled, and shortly after we disabled the source, the
timeout would be invoked after the source was freed causing
use-after-free bugs.

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

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1365
2020-07-10 09:08:59 +02:00
Jonas Ådahl
50634d450e screen-cast/src: Use G_USEC_PER_SEC instead of 1000000
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:23 +02:00
Jonas Ådahl
9bab8e8751 screen-cast/src: Record follow up frame after timeout
During animation or other things that cause multiple frames in a row
being painted, we might skip recording frames if the max framerate is
reached.

Doing so means we might end up skipping the last frame in a series,
ending with the last frame we sent was not the last one, making things
appear to get stuck sometimes.

Handle this by creating a timeout if we ever throttle, and at the time
the timeout callback is triggered, make sure we eventually send an up to
date frame.

This is handle differently depending on the source type. A monitor
source type reports 1x1 pixel damage on each view its monitor overlaps,
while a window source type simply records a frame from the surface
directly, except without recording a timestamp, so that timestamps
always refer to when damage actually happened.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:23 +02:00
Jonas Ådahl
7adc24d3a6 screen-cast/src: Fix signedness of timestamp field
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:23 +02:00
Jonas Ådahl
047da80c3b screen-cast/src: Make record functions return an error when failing
Now that we don't use the record function to early out depending on
implicit state (don't record pixels if only cursor moved for example),
let it simply report an error when it fails, as we should no longer ever
return without pixels if nothing failed.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:23 +02:00
Jonas Ådahl
882967d3ce screen-cast: Let the reason for recording determine what to record
E.g. we'll have pointer movement that, if no painting is already
scheduled, should only send new cursor metadata without any new pixel
buffer. When this happens, tell next step to not record the pixels if
this was the case, instead of having it rediscover this itself.

Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:23 +02:00
Jonas Ådahl
cea0722e72 screen-cast/src: Add flag to maybe_record()
Will later be used to make recording avoid recording actual pixel
content if e.g. only the cursor moved.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:23 +02:00
Jonas Ådahl
03823128c4 screen-cast/window-stream-src: Fix indentation
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:22 +02:00
Jonas Ådahl
7b35ed8c35 screen-cast-src: Make the two record vfuncs more similarly named
Both do more or less the same but with different methods - one puts
pixels into a buffer using the CPU, the other puts pixels into a buffer
using the GPU.

However, they are behaving slightly different, which they shouldn't.
Lets first address the misleading disconnect in naming, and later we'll
make them behave more similarly.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1361
2020-07-08 21:42:22 +02:00
Daniel van Vugt
ecaaccb064 background: Use NEAREST filtering when the texture is the monitor resolution
That was obviously always the intention, but it didn't work when the
display was scaled. My 3840x2160 monitor with a 3840x2160 texture was
being rendered with LINEAR filtering.

It seems the `force_bilinear` flag was TRUE when it should be FALSE.
Because a texture area that's an integer fraction of the texture
resolution is still a perfect match when that integer is the monitor
scale. We were also getting:

`meta_actor_painting_untransformed (fb, W, H, W, H, NULL, NULL) == FALSE`

when the display was scaled. Because the second W,H was not the real
sampling resolution. So with both of those issues fixed we now get
NEAREST filtering when the texture resolution matches the resolution it's
physically being rendered at.

Note: The background texture actually wasn't equal to the physical monitor
resolution prior to January 2020 (76240e24f7). So it wasn't possible to do
this before then. Since then however, the texture resolution is always
equal to the physical monitor resolution.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1346
2020-07-08 07:26:50 +00:00
60 changed files with 1024 additions and 240 deletions

1
.gitignore vendored
View File

@@ -103,3 +103,4 @@ doc/reference/meta.types
.dirstamp
**/tags.*
build/
subprojects/sysprof/

View File

@@ -10295,6 +10295,38 @@ clutter_actor_get_fixed_position (ClutterActor *self,
return FALSE;
}
/**
* clutter_actor_get_transformed_extents:
* @self: A #ClutterActor
* @rect: (out): return location for the transformed bounding rect
*
* Gets the transformed bounding rect of an actor, in pixels relative to the stage.
*/
void
clutter_actor_get_transformed_extents (ClutterActor *self,
graphene_rect_t *rect)
{
graphene_quad_t quad;
graphene_point3d_t v[4];
ClutterActorBox box;
box.x1 = 0;
box.y1 = 0;
box.x2 = clutter_actor_box_get_width (&self->priv->allocation);
box.y2 = clutter_actor_box_get_height (&self->priv->allocation);
if (_clutter_actor_transform_and_project_box (self, &box, v))
{
graphene_quad_init (&quad,
(graphene_point_t *) &v[0],
(graphene_point_t *) &v[1],
(graphene_point_t *) &v[2],
(graphene_point_t *) &v[3]);
if (rect)
graphene_quad_bounds (&quad, rect);
}
}
/**
* clutter_actor_get_transformed_position:
* @self: A #ClutterActor
@@ -16183,12 +16215,7 @@ update_stage_views (ClutterActor *self)
stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
g_return_if_fail (stage);
clutter_actor_get_transformed_position (self,
&bounding_rect.origin.x,
&bounding_rect.origin.y);
clutter_actor_get_transformed_size (self,
&bounding_rect.size.width,
&bounding_rect.size.height);
clutter_actor_get_transformed_extents (self, &bounding_rect);
if (bounding_rect.size.width == 0.0 ||
bounding_rect.size.height == 0.0)

View File

@@ -813,6 +813,11 @@ void clutter_actor_set_child_transform
CLUTTER_EXPORT
void clutter_actor_get_child_transform (ClutterActor *self,
ClutterMatrix *transform);
CLUTTER_EXPORT
void clutter_actor_get_transformed_extents (ClutterActor *self,
graphene_rect_t *rect);
CLUTTER_EXPORT
void clutter_actor_get_transformed_position (ClutterActor *self,
gfloat *x,

View File

@@ -5326,7 +5326,7 @@ clutter_text_set_selection_bound (ClutterText *self,
if (priv->selection_bound != selection_bound)
{
gint len = clutter_text_buffer_get_length (get_buffer (self));;
gint len = clutter_text_buffer_get_length (get_buffer (self));
if (selection_bound < 0 || selection_bound >= len)
priv->selection_bound = -1;

View File

@@ -325,7 +325,7 @@ foreach_clamped_region (CoglMetaTexture *meta_texture,
if (*tx_1 < 0)
{
clamp_data.start = *tx_1;
clamp_data.end = MIN (0, *tx_2);;
clamp_data.end = MIN (0, *tx_2);
cogl_meta_texture_foreach_in_region (meta_texture,
half_texel_width, *ty_1,
half_texel_width, *ty_2,
@@ -377,7 +377,7 @@ foreach_clamped_region (CoglMetaTexture *meta_texture,
if (*ty_1 < 0)
{
clamp_data.start = *ty_1;
clamp_data.end = MIN (0, *ty_2);;
clamp_data.end = MIN (0, *ty_2);
cogl_meta_texture_foreach_in_region (meta_texture,
*tx_1, half_texel_height,
*tx_2, half_texel_height,
@@ -396,7 +396,7 @@ foreach_clamped_region (CoglMetaTexture *meta_texture,
/* Handle any bottom clamped region */
if (*ty_2 > max_t_coord)
{
clamp_data.start = MAX (max_t_coord, *ty_1);;
clamp_data.start = MAX (max_t_coord, *ty_1);
clamp_data.end = *ty_2;
cogl_meta_texture_foreach_in_region (meta_texture,
*tx_1,

View File

@@ -1,6 +1,6 @@
project('mutter', 'c',
version: '3.37.3',
meson_version: '>= 0.50.0',
meson_version: '>= 0.51.0',
license: 'GPLv2+'
)
@@ -24,7 +24,7 @@ uprof_req = '>= 0.3'
pango_req = '>= 1.2.0'
cairo_req = '>= 1.10.0'
pangocairo_req = '>= 1.20'
gsettings_desktop_schemas_req = '>= 3.33.0'
gsettings_desktop_schemas_req = '>= 3.37.2'
json_glib_req = '>= 0.12.0'
upower_glib_req = '>= 0.99.0'
xcomposite_req = '>= 0.4'
@@ -53,7 +53,7 @@ gbm_req = '>= 10.3'
libpipewire_req = '>= 0.3.0'
# profiler requirements
sysprof_req = '>= 3.35.2'
sysprof_req = '>= 3.37.2'
gnome = import('gnome')
pkg = import('pkgconfig')
@@ -279,7 +279,20 @@ endif
have_profiler = get_option('profiler')
if have_profiler
sysprof_dep = dependency('sysprof-capture-3', version: sysprof_req)
# libsysprof-capture support
sysprof_dep = dependency('sysprof-capture-4',
required: true,
default_options: [
'enable_examples=false',
'enable_gtk=false',
'enable_tests=false',
'enable_tools=false',
'libsysprof=false',
'with_sysprofd=none',
'help=false',
],
fallback: ['sysprof', 'libsysprof_capture_dep'],
)
endif
required_functions = [

View File

@@ -7,15 +7,15 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2019-08-06 00:49+0000\n"
"PO-Revision-Date: 2019-09-03 09:53+0200\n"
"POT-Creation-Date: 2020-05-26 13:44+0000\n"
"PO-Revision-Date: 2020-07-12 18:34+0200\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.2.3\n"
"X-Generator: Poedit 2.3.1\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@@ -420,19 +420,32 @@ msgstr "Modificadôr di doprâ par localizâ il pontadôr"
msgid "This key will initiate the “locate pointer” action."
msgstr "Cheste clâf e inizializerâ la azion “localize pontadôr”."
#: data/org.gnome.mutter.gschema.xml.in:155
#: data/org.gnome.mutter.gschema.xml.in:142
msgid "Timeout for check-alive ping"
msgstr "Timp scjadût pal control di sorevivence dal ping"
#: 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 ""
"Numar di miliseconts jenfri di chei che un client al à di rispuindi a une "
"richieste di ping, par fâ in mût che nol vegni identificât tant che "
"inglaçât. Doprant 0 si disabilitarà dal dut il control di sorevivence."
#: data/org.gnome.mutter.gschema.xml.in:165
msgid "Select window from tab popup"
msgstr "Selezione barcon dal tab popup"
#: data/org.gnome.mutter.gschema.xml.in:160
#: data/org.gnome.mutter.gschema.xml.in:170
msgid "Cancel tab popup"
msgstr "Anule tab popup"
#: data/org.gnome.mutter.gschema.xml.in:165
#: data/org.gnome.mutter.gschema.xml.in:175
msgid "Switch monitor configurations"
msgstr "Cambie configurazions visôr"
#: data/org.gnome.mutter.gschema.xml.in:170
#: data/org.gnome.mutter.gschema.xml.in:180
msgid "Rotates the built-in monitor configuration"
msgstr "Al volte la configurazion dal visôr integrât"
@@ -546,7 +559,7 @@ msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2531
#: src/backends/meta-input-settings.c:2631
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Cambie mût (Grup %d)"
@@ -554,34 +567,34 @@ msgstr "Cambie mût (Grup %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2554
#: src/backends/meta-input-settings.c:2654
msgid "Switch monitor"
msgstr "Cambie visôr"
#: src/backends/meta-input-settings.c:2556
#: src/backends/meta-input-settings.c:2656
msgid "Show on-screen help"
msgstr "Mostre jutori a schermi"
#: src/backends/meta-monitor.c:223
#: src/backends/meta-monitor.c:226
msgid "Built-in display"
msgstr "Display integrât"
#: src/backends/meta-monitor.c:252
#: src/backends/meta-monitor.c:255
msgid "Unknown"
msgstr "No cognossût"
#: src/backends/meta-monitor.c:254
#: src/backends/meta-monitor.c:257
msgid "Unknown Display"
msgstr "Display no cognossût"
#: src/backends/meta-monitor.c:262
#: src/backends/meta-monitor.c:265
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor.c:270
#: src/backends/meta-monitor.c:273
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
@@ -590,13 +603,13 @@ msgid "%s %s"
msgstr "%s %s"
#. Translators: this string will appear in Sysprof
#: src/backends/meta-profiler.c:82
#: src/backends/meta-profiler.c:79
msgid "Compositor"
msgstr "Composidôr"
#. 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:510
#: src/compositor/compositor.c:545
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@@ -608,47 +621,47 @@ msgstr ""
msgid "Bell event"
msgstr "Event cjampane"
#: src/core/main.c:185
#: src/core/main.c:190
msgid "Disable connection to session manager"
msgstr "Disabilite la conession al gjestôr de session"
#: src/core/main.c:191
#: src/core/main.c:196
msgid "Replace the running window manager"
msgstr "Rimplace il window manager in vore"
#: src/core/main.c:197
#: src/core/main.c:202
msgid "Specify session management ID"
msgstr "Specifiche il ID di gjestion session"
#: src/core/main.c:202
#: src/core/main.c:207
msgid "X Display to use"
msgstr "Display X di doprâ"
#: src/core/main.c:208
#: src/core/main.c:213
msgid "Initialize session from savefile"
msgstr "Inizialize session da file salvât"
#: src/core/main.c:214
#: src/core/main.c:219
msgid "Make X calls synchronous"
msgstr "Fâs lis clamadis X sincronis"
#: src/core/main.c:221
#: src/core/main.c:226
msgid "Run as a wayland compositor"
msgstr "Eseguìs come compositor wayland"
#: src/core/main.c:227
#: src/core/main.c:232
msgid "Run as a nested compositor"
msgstr "Eseguìs come compositor nidiât"
#: src/core/main.c:233
#: src/core/main.c:238
msgid "Run wayland compositor without starting Xwayland"
msgstr "Eseguìs il compositôr di wayland cence inviâ Xwayland"
#: src/core/main.c:241
#: src/core/main.c:246
msgid "Run as a full display server, rather than nested"
msgstr "Eseguìs come servidôr display complet, invezit che nidiât"
#: src/core/main.c:247
#: src/core/main.c:252
msgid "Run with X11 backend"
msgstr "Eseguìs cul backend X11"
@@ -701,21 +714,21 @@ msgstr "Stampe version"
msgid "Mutter plugin to use"
msgstr "Plugin Mutter di doprâ"
#: src/core/prefs.c:1849
#: src/core/prefs.c:1911
#, c-format
msgid "Workspace %d"
msgstr "Spazi di lavôr %d"
#: src/core/util.c:121
#: src/core/util.c:119
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter al è stât compilât cence supuart pe modalitât fetose\n"
#: src/wayland/meta-wayland-tablet-pad.c:567
#: src/wayland/meta-wayland-tablet-pad.c:568
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Cambie mût: mût %d"
#: src/x11/meta-x11-display.c:671
#: src/x11/meta-x11-display.c:676
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
@@ -724,21 +737,21 @@ msgstr ""
"Il display “%s” al à za un window manager; prove dopre la opzion --replace "
"par rimplaçâ chel atuâl."
#: src/x11/meta-x11-display.c:1032
#: src/x11/meta-x11-display.c:1089
msgid "Failed to initialize GDK\n"
msgstr "No si è rivâts a inizializâ GDK\n"
#: src/x11/meta-x11-display.c:1056
#: src/x11/meta-x11-display.c:1113
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "Impussibil vierzi il display “%s” di X Window System\n"
#: src/x11/meta-x11-display.c:1140
#: src/x11/meta-x11-display.c:1196
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "Schermi %d su display “%s” no valit\n"
#: src/x11/meta-x11-selection-input-stream.c:445
#: src/x11/meta-x11-selection-input-stream.c:460
#, c-format
msgid "Format %s not supported"
msgstr "Il formât %s nol è supuartât"
@@ -751,7 +764,7 @@ msgstr ""
"Chescj barcons no supuartin la funzion “salve impostazions atuâls” e si "
"scugnarà tornâ a inviâlis a man tal prossim acès."
#: src/x11/window-props.c:569
#: src/x11/window-props.c:548
#, c-format
msgid "%s (on %s)"
msgstr "%s (su %s)"

View File

@@ -21,8 +21,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2020-02-23 17:41+0000\n"
"PO-Revision-Date: 2020-02-24 06:39-0300\n"
"POT-Creation-Date: 2020-04-27 14:06+0000\n"
"PO-Revision-Date: 2020-07-17 17:56-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
@@ -30,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"X-Generator: Gtranslator 3.32.0\n"
"X-Generator: Gtranslator 3.36.0\n"
"X-Project-Style: gnome\n"
#: data/50-mutter-navigation.xml:6
@@ -59,35 +59,35 @@ msgstr "Mover a janela para o último espaço de trabalho"
#: data/50-mutter-navigation.xml:24
msgid "Move window one workspace up"
msgstr "Mover a janela um espaço de trabalho acima"
msgstr "Mover a janela para um espaço de trabalho acima"
#: data/50-mutter-navigation.xml:27
msgid "Move window one workspace down"
msgstr "Mover a janela um espaço de trabalho abaixo"
msgstr "Mover a janela para um espaço de trabalho abaixo"
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
#: data/50-mutter-navigation.xml:30
msgid "Move window one monitor to the left"
msgstr "Mover janela para o monitor da esquerda"
msgstr "Mover a janela para o monitor da esquerda"
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
#: data/50-mutter-navigation.xml:33
msgid "Move window one monitor to the right"
msgstr "Mover janela para o monitor da direita"
msgstr "Mover a janela para o monitor da direita"
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
#: data/50-mutter-navigation.xml:36
msgid "Move window one monitor up"
msgstr "Mover janela para o monitor acima"
msgstr "Mover a janela para o monitor acima"
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
#: data/50-mutter-navigation.xml:39
msgid "Move window one monitor down"
msgstr "Mover janela para o monitor abaixo"
msgstr "Mover a janela para o monitor abaixo"
#: data/50-mutter-navigation.xml:43
msgid "Switch applications"
msgstr "Alternar aplicativos"
msgstr "Alternar entre aplicativos"
#: data/50-mutter-navigation.xml:48
msgid "Switch to previous application"
@@ -95,7 +95,7 @@ msgstr "Alternar para o aplicativo anterior"
#: data/50-mutter-navigation.xml:52
msgid "Switch windows"
msgstr "Alternar janelas"
msgstr "Alternar entre janelas"
#: data/50-mutter-navigation.xml:57
msgid "Switch to previous window"
@@ -111,7 +111,7 @@ msgstr "Alternar para a janela anterior de um aplicativo"
#: data/50-mutter-navigation.xml:70
msgid "Switch system controls"
msgstr "Alternar controles do sistema"
msgstr "Alternar os controles do sistema"
#: data/50-mutter-navigation.xml:75
msgid "Switch to previous system control"
@@ -167,11 +167,11 @@ msgstr "Trocar para o último espaço de trabalho"
#: data/50-mutter-navigation.xml:123
msgid "Move to workspace above"
msgstr "Mover para o espaço de trabalho acima"
msgstr "Mover a visualização para o espaço de trabalho acima"
#: data/50-mutter-navigation.xml:126
msgid "Move to workspace below"
msgstr "Mover para o espaço de trabalho abaixo"
msgstr "Mover a visualização para o espaço de trabalho abaixo"
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
msgid "System"
@@ -199,11 +199,11 @@ msgstr "Ativar o menu da janela"
#: data/50-mutter-windows.xml:10
msgid "Toggle fullscreen mode"
msgstr "Alternar modo de tela inteira"
msgstr "Alternar o modo de tela inteira"
#: data/50-mutter-windows.xml:12
msgid "Toggle maximization state"
msgstr "Alternar estado de maximização"
msgstr "Alternar o estado de maximização"
#: data/50-mutter-windows.xml:14
msgid "Maximize window"
@@ -211,35 +211,35 @@ msgstr "Maximizar a janela"
#: data/50-mutter-windows.xml:16
msgid "Restore window"
msgstr "Restaurar janela"
msgstr "Restaurar a anela"
#: data/50-mutter-windows.xml:18
msgid "Close window"
msgstr "Fechar janela"
msgstr "Fechar a janela"
#: data/50-mutter-windows.xml:20
msgid "Hide window"
msgstr "Ocultar janela"
msgstr "Ocultar a janela"
#: data/50-mutter-windows.xml:22
msgid "Move window"
msgstr "Mover janela"
msgstr "Mover a janela"
#: data/50-mutter-windows.xml:24
msgid "Resize window"
msgstr "Redimensionar janela"
msgstr "Redimensionar a janela"
#: data/50-mutter-windows.xml:27
msgid "Toggle window on all workspaces or one"
msgstr "Alternar a janela em todos os espaços de trabalho ou em apenas um"
msgstr "Alternar a janela em todos os espaços de trabalho ou apenas em um"
#: data/50-mutter-windows.xml:29
msgid "Raise window if covered, otherwise lower it"
msgstr "Elevar a janela se estiver coberta; caso contrário, a abaixa"
msgstr "Trazer a janela se estiver coberta; caso contrário, coloca atrás"
#: data/50-mutter-windows.xml:31
msgid "Raise window above other windows"
msgstr "Elevar a janela para frente das outras"
msgstr "Trazer a janela para frente das outras"
#: data/50-mutter-windows.xml:33
msgid "Lower window below other windows"
@@ -255,11 +255,11 @@ msgstr "Maximizar a janela horizontalmente"
#: data/50-mutter-windows.xml:41
msgid "View split on left"
msgstr "Visualizar divisão à esquerda"
msgstr "Visualizar a divisão à esquerda"
#: data/50-mutter-windows.xml:45
msgid "View split on right"
msgstr "Visualizar divisão à direita"
msgstr "Visualizar a divisão à direita"
#: data/mutter.desktop.in:4
msgid "Mutter"
@@ -580,7 +580,7 @@ msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2567
#: src/backends/meta-input-settings.c:2631
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Alternador de modo (Grupo %d)"
@@ -588,34 +588,34 @@ msgstr "Alternador de modo (Grupo %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2590
#: src/backends/meta-input-settings.c:2654
msgid "Switch monitor"
msgstr "Trocar monitor"
#: src/backends/meta-input-settings.c:2592
#: src/backends/meta-input-settings.c:2656
msgid "Show on-screen help"
msgstr "Mostrar ajuda na tela"
#: src/backends/meta-monitor.c:223
#: src/backends/meta-monitor.c:226
msgid "Built-in display"
msgstr "Tela embutida"
#: src/backends/meta-monitor.c:252
#: src/backends/meta-monitor.c:255
msgid "Unknown"
msgstr "Desconhecido"
#: src/backends/meta-monitor.c:254
#: src/backends/meta-monitor.c:257
msgid "Unknown Display"
msgstr "Monitor desconhecido"
#: src/backends/meta-monitor.c:262
#: src/backends/meta-monitor.c:265
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor.c:270
#: src/backends/meta-monitor.c:273
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "

View File

@@ -22,7 +22,7 @@
#ifndef META_INPUT_SETTINGS_PRIVATE_H
#define META_INPUT_SETTINGS_PRIVATE_H
#include <gsettings-desktop-schemas/gdesktop-enums.h>
#include <gdesktop-enums.h>
#ifdef HAVE_LIBWACOM
#include <libwacom/libwacom.h>
@@ -55,9 +55,15 @@ struct _MetaInputSettingsClass
void (* set_tap_enabled) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_tap_button_map) (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadTapButtonMap mode);
void (* set_tap_and_drag_enabled) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_tap_and_drag_lock_enabled) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_disable_while_typing) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);

View File

@@ -620,6 +620,36 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
}
}
static void
update_touchpad_tap_button_map (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
GDesktopTouchpadTapButtonMap method;
MetaInputSettingsPrivate *priv;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
method = g_settings_get_enum (priv->touchpad_settings, "tap-button-map");
if (device)
{
settings_device_set_uint_setting (input_settings, device,
input_settings_class->set_tap_button_map,
method);
}
else
{
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
(ConfigUintFunc) input_settings_class->set_tap_button_map,
method);
}
}
static void
update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device)
@@ -652,6 +682,37 @@ update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings,
}
}
static void
update_touchpad_tap_and_drag_lock_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
gboolean enabled;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag-lock");
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_tap_and_drag_lock_enabled,
enabled);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
NULL,
input_settings_class->set_tap_and_drag_lock_enabled,
enabled);
}
}
static void
update_touchpad_edge_scroll (MetaInputSettings *input_settings,
ClutterInputDevice *device)
@@ -1198,8 +1259,12 @@ meta_input_settings_changed_cb (GSettings *settings,
update_device_natural_scroll (input_settings, NULL);
else if (strcmp (key, "tap-to-click") == 0)
update_touchpad_tap_enabled (input_settings, NULL);
else if (strcmp (key, "tap-button-map") == 0)
update_touchpad_tap_button_map (input_settings, NULL);
else if (strcmp (key, "tap-and-drag") == 0)
update_touchpad_tap_and_drag_enabled (input_settings, NULL);
else if (strcmp (key, "tap-and-drag-lock") == 0)
update_touchpad_tap_and_drag_lock_enabled (input_settings, NULL);
else if (strcmp(key, "disable-while-typing") == 0)
update_touchpad_disable_while_typing (input_settings, NULL);
else if (strcmp (key, "send-events") == 0)
@@ -1700,7 +1765,9 @@ apply_device_settings (MetaInputSettings *input_settings,
update_touchpad_left_handed (input_settings, device);
update_touchpad_tap_enabled (input_settings, device);
update_touchpad_tap_button_map (input_settings, device);
update_touchpad_tap_and_drag_enabled (input_settings, device);
update_touchpad_tap_and_drag_lock_enabled (input_settings, device);
update_touchpad_disable_while_typing (input_settings, device);
update_touchpad_send_events (input_settings, device);
update_touchpad_two_finger_scroll (input_settings, device);

View File

@@ -317,7 +317,7 @@ handle_start_element (GMarkupParseContext *context,
}
else if (g_str_equal (element_name, "monitor"))
{
parser->current_monitor_config = g_new0 (MetaMonitorConfig, 1);;
parser->current_monitor_config = g_new0 (MetaMonitorConfig, 1);
parser->state = STATE_MONITOR;
}

View File

@@ -96,7 +96,7 @@ create_mode (CrtcModeSpec *spec,
crtc_mode_info->refresh_rate = spec->refresh_rate;
return g_object_new (META_TYPE_CRTC_MODE,
"id", mode_id,
"id", (uint64_t) mode_id,
"info", crtc_mode_info,
NULL);
}
@@ -205,7 +205,7 @@ append_monitor (MetaMonitorManager *manager,
*modes = g_list_concat (*modes, new_modes);
crtc = g_object_new (META_TYPE_CRTC_DUMMY,
"id", g_list_length (*crtcs) + 1,
"id", (uint64_t) g_list_length (*crtcs) + 1,
"gpu", gpu,
NULL);
*crtcs = g_list_append (*crtcs, crtc);
@@ -237,7 +237,7 @@ append_monitor (MetaMonitorManager *manager,
output_info->n_possible_crtcs = 1;
output = g_object_new (META_TYPE_OUTPUT_DUMMY,
"id", number,
"id", (uint64_t) number,
"gpu", gpu,
"info", output_info,
NULL);
@@ -291,7 +291,7 @@ append_tiled_monitor (MetaMonitorManager *manager,
MetaCrtc *crtc;
crtc = g_object_new (META_TYPE_CRTC_DUMMY,
"id", g_list_length (*crtcs) + i + 1,
"id", (uint64_t) g_list_length (*crtcs) + i + 1,
"gpu", gpu,
NULL);
new_crtcs = g_list_append (new_crtcs, crtc);
@@ -358,7 +358,7 @@ append_tiled_monitor (MetaMonitorManager *manager,
output_info->n_possible_crtcs = n_tiles;
output = g_object_new (META_TYPE_OUTPUT_DUMMY,
"id", number,
"id", (uint64_t) number,
"gpu", gpu,
"info", output_info,
NULL);

View File

@@ -1186,7 +1186,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
{
MetaCrtcMode *mode = l->data;
const MetaCrtcModeInfo *crtc_mode_info =
meta_crtc_mode_get_info (mode);;
meta_crtc_mode_get_info (mode);
g_variant_builder_add (&mode_builder, "(uxuudu)",
i, /* ID */

View File

@@ -36,6 +36,17 @@ enum
static int handle_signals[N_HANDLE_SIGNALS];
enum
{
PROP_0,
PROP_IS_RECORDING,
N_PROPS
};
static GParamSpec *obj_props[N_PROPS];
enum
{
CONTROLLER_NEW_HANDLE,
@@ -50,6 +61,8 @@ typedef struct _MetaRemoteAccessHandlePrivate
gboolean has_stopped;
gboolean disable_animations;
gboolean is_recording;
} MetaRemoteAccessHandlePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle,
@@ -177,6 +190,48 @@ meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
return remote_access_controller;
}
static void
meta_remote_access_handle_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaRemoteAccessHandle *handle = META_REMOTE_ACCESS_HANDLE (object);
MetaRemoteAccessHandlePrivate *priv =
meta_remote_access_handle_get_instance_private (handle);
switch (prop_id)
{
case PROP_IS_RECORDING:
g_value_set_boolean (value, priv->is_recording);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_remote_access_handle_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaRemoteAccessHandle *handle = META_REMOTE_ACCESS_HANDLE (object);
MetaRemoteAccessHandlePrivate *priv =
meta_remote_access_handle_get_instance_private (handle);
switch (prop_id)
{
case PROP_IS_RECORDING:
priv->is_recording = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_remote_access_handle_init (MetaRemoteAccessHandle *handle)
{
@@ -185,6 +240,11 @@ meta_remote_access_handle_init (MetaRemoteAccessHandle *handle)
static void
meta_remote_access_handle_class_init (MetaRemoteAccessHandleClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = meta_remote_access_handle_get_property;
object_class->set_property = meta_remote_access_handle_set_property;
handle_signals[HANDLE_STOPPED] =
g_signal_new ("stopped",
G_TYPE_FROM_CLASS (klass),
@@ -192,6 +252,16 @@ meta_remote_access_handle_class_init (MetaRemoteAccessHandleClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
obj_props[PROP_IS_RECORDING] =
g_param_spec_boolean ("is-recording",
"is-recording",
"Is a screen recording",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
}
static void

View File

@@ -170,6 +170,7 @@ static void
sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
MetaScreenCastRecordFlag flags;
if (!is_cursor_in_stream (area_src))
return;
@@ -177,7 +178,8 @@ sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
if (is_redraw_queued (area_src))
return;
meta_screen_cast_stream_src_maybe_record_frame (src);
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -233,10 +235,12 @@ maybe_record_frame_on_idle (gpointer user_data)
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
MetaScreenCastRecordFlag flags;
area_src->maybe_record_idle_id = 0;
meta_screen_cast_stream_src_maybe_record_frame (src);
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
return G_SOURCE_REMOVE;
}
@@ -388,8 +392,9 @@ meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
meta_screen_cast_area_stream_src_record_frame (MetaScreenCastStreamSrc *src,
uint8_t *data)
meta_screen_cast_area_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
uint8_t *data,
GError **error)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
@@ -400,7 +405,6 @@ meta_screen_cast_area_stream_src_record_frame (MetaScreenCastStreamSrc *src,
float scale;
int stride;
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
g_autoptr (GError) error = NULL;
stage = get_stage (area_src);
area = meta_screen_cast_area_stream_get_area (area_stream);
@@ -422,18 +426,16 @@ meta_screen_cast_area_stream_src_record_frame (MetaScreenCastStreamSrc *src,
stride,
CLUTTER_CAIRO_FORMAT_ARGB32,
paint_flags,
&error))
{
g_warning ("Failed to record area: %s", error->message);
return FALSE;
}
error))
return FALSE;
return TRUE;
}
static gboolean
meta_screen_cast_area_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer)
meta_screen_cast_area_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer,
GError **error)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
@@ -467,6 +469,19 @@ meta_screen_cast_area_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *s
return TRUE;
}
static void
meta_screen_cast_area_stream_record_follow_up (MetaScreenCastStreamSrc *src)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaScreenCastRecordFlag flags;
g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove);
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
@@ -578,9 +593,12 @@ meta_screen_cast_area_stream_src_class_init (MetaScreenCastAreaStreamSrcClass *k
src_class->get_specs = meta_screen_cast_area_stream_src_get_specs;
src_class->enable = meta_screen_cast_area_stream_src_enable;
src_class->disable = meta_screen_cast_area_stream_src_disable;
src_class->record_frame = meta_screen_cast_area_stream_src_record_frame;
src_class->blit_to_framebuffer =
meta_screen_cast_area_stream_src_blit_to_framebuffer;
src_class->record_to_buffer =
meta_screen_cast_area_stream_src_record_to_buffer;
src_class->record_to_framebuffer =
meta_screen_cast_area_stream_src_record_to_framebuffer;
src_class->record_follow_up =
meta_screen_cast_area_stream_record_follow_up;
src_class->set_cursor_metadata =
meta_screen_cast_area_stream_src_set_cursor_metadata;
}

View File

@@ -87,6 +87,7 @@ meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
MetaRectangle *area,
ClutterStage *stage,
MetaScreenCastCursorMode cursor_mode,
MetaScreenCastFlag flags,
GError **error)
{
MetaScreenCastAreaStream *area_stream;
@@ -105,6 +106,7 @@ meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
"session", session,
"connection", connection,
"cursor-mode", cursor_mode,
"flags", flags,
NULL);
if (!area_stream)
return NULL;

View File

@@ -37,6 +37,7 @@ MetaScreenCastAreaStream * meta_screen_cast_area_stream_new (MetaScreenCastSessi
MetaRectangle *area,
ClutterStage *stage,
MetaScreenCastCursorMode cursor_mode,
MetaScreenCastFlag flags,
GError **error);
ClutterStage * meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream);

View File

@@ -121,8 +121,10 @@ stage_painted (MetaStage *stage,
gpointer user_data)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
MetaScreenCastRecordFlag flags;
meta_screen_cast_stream_src_maybe_record_frame (src);
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static MetaBackend *
@@ -202,6 +204,7 @@ static void
sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
MetaScreenCastRecordFlag flags;
if (!is_cursor_in_stream (monitor_src))
return;
@@ -209,7 +212,11 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
if (is_redraw_queued (monitor_src))
return;
meta_screen_cast_stream_src_maybe_record_frame (src);
if (meta_screen_cast_stream_src_pending_follow_up_frame (src))
return;
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -383,8 +390,9 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
uint8_t *data)
meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
uint8_t *data,
GError **error)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
@@ -392,9 +400,6 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
MetaMonitor *monitor;
MetaLogicalMonitor *logical_monitor;
if (!is_redraw_queued (monitor_src))
return FALSE;
monitor = get_monitor (monitor_src);
logical_monitor = meta_monitor_get_logical_monitor (monitor);
stage = get_stage (monitor_src);
@@ -404,8 +409,9 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
}
static gboolean
meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer)
meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer,
GError **error)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
@@ -429,7 +435,6 @@ meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data);
g_autoptr (GError) error = NULL;
CoglFramebuffer *view_framebuffer;
MetaRectangle view_layout;
int x, y;
@@ -450,12 +455,8 @@ meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
x, y,
cogl_framebuffer_get_width (view_framebuffer),
cogl_framebuffer_get_height (view_framebuffer),
&error))
{
g_warning ("Error blitting view into DMABuf framebuffer: %s",
error->message);
return FALSE;
}
error))
return FALSE;
}
cogl_framebuffer_finish (framebuffer);
@@ -463,6 +464,44 @@ meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
return TRUE;
}
static void
meta_screen_cast_monitor_stream_record_follow_up (MetaScreenCastStreamSrc *src)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
MetaBackend *backend = get_backend (monitor_src);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
ClutterStage *stage = get_stage (monitor_src);
MetaMonitor *monitor;
MetaLogicalMonitor *logical_monitor;
MetaRectangle logical_monitor_layout;
GList *l;
monitor = get_monitor (monitor_src);
logical_monitor = meta_monitor_get_logical_monitor (monitor);
logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
MetaRendererView *view = l->data;
MetaRectangle view_layout;
MetaRectangle damage;
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout))
continue;
damage = (cairo_rectangle_int_t) {
.x = view_layout.x,
.y = view_layout.y,
.width = 1,
.height = 1,
};
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &damage);
}
}
static void
meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
@@ -583,9 +622,12 @@ meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcCl
src_class->get_specs = meta_screen_cast_monitor_stream_src_get_specs;
src_class->enable = meta_screen_cast_monitor_stream_src_enable;
src_class->disable = meta_screen_cast_monitor_stream_src_disable;
src_class->record_frame = meta_screen_cast_monitor_stream_src_record_frame;
src_class->blit_to_framebuffer =
meta_screen_cast_monitor_stream_src_blit_to_framebuffer;
src_class->record_to_buffer =
meta_screen_cast_monitor_stream_src_record_to_buffer;
src_class->record_to_framebuffer =
meta_screen_cast_monitor_stream_src_record_to_framebuffer;
src_class->record_follow_up =
meta_screen_cast_monitor_stream_record_follow_up;
src_class->set_cursor_metadata =
meta_screen_cast_monitor_stream_src_set_cursor_metadata;
}

View File

@@ -110,6 +110,7 @@ meta_screen_cast_monitor_stream_new (MetaScreenCastSession *session,
MetaMonitor *monitor,
ClutterStage *stage,
MetaScreenCastCursorMode cursor_mode,
MetaScreenCastFlag flags,
GError **error)
{
MetaGpu *gpu = meta_monitor_get_gpu (monitor);
@@ -130,6 +131,7 @@ meta_screen_cast_monitor_stream_new (MetaScreenCastSession *session,
"session", session,
"connection", connection,
"cursor-mode", cursor_mode,
"flags", flags,
"monitor", monitor,
NULL);
if (!monitor_stream)

View File

@@ -40,6 +40,7 @@ MetaScreenCastMonitorStream * meta_screen_cast_monitor_stream_new (MetaScreenCas
MetaMonitor *monitor,
ClutterStage *stage,
MetaScreenCastCursorMode cursor_mode,
MetaScreenCastFlag flags,
GError **error);
ClutterStage * meta_screen_cast_monitor_stream_get_stage (MetaScreenCastMonitorStream *monitor_stream);

View File

@@ -310,6 +310,8 @@ handle_record_monitor (MetaDBusScreenCastSession *skeleton,
meta_backend_get_monitor_manager (backend);
MetaMonitor *monitor;
MetaScreenCastCursorMode cursor_mode;
gboolean is_recording;
MetaScreenCastFlag flags;
ClutterStage *stage;
GError *error = NULL;
MetaScreenCastMonitorStream *monitor_stream;
@@ -356,13 +358,21 @@ handle_record_monitor (MetaDBusScreenCastSession *skeleton,
}
}
if (!g_variant_lookup (properties_variant, "is-recording", "b", &is_recording))
is_recording = FALSE;
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
flags = META_SCREEN_CAST_FLAG_NONE;
if (is_recording)
flags |= META_SCREEN_CAST_FLAG_IS_RECORDING;
monitor_stream = meta_screen_cast_monitor_stream_new (session,
connection,
monitor,
stage,
cursor_mode,
flags,
&error);
if (!monitor_stream)
{
@@ -398,6 +408,8 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
GDBusConnection *connection;
MetaWindow *window;
MetaScreenCastCursorMode cursor_mode;
gboolean is_recording;
MetaScreenCastFlag flags;
GError *error = NULL;
MetaDisplay *display;
GVariant *window_id_variant = NULL;
@@ -454,13 +466,21 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
}
}
if (!g_variant_lookup (properties_variant, "is-recording", "b", &is_recording))
is_recording = FALSE;
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
flags = META_SCREEN_CAST_FLAG_NONE;
if (is_recording)
flags |= META_SCREEN_CAST_FLAG_IS_RECORDING;
window_stream = meta_screen_cast_window_stream_new (session,
connection,
window,
cursor_mode,
flags,
&error);
if (!window_stream)
{
@@ -501,6 +521,8 @@ handle_record_area (MetaDBusScreenCastSession *skeleton,
MetaBackend *backend;
ClutterStage *stage;
MetaScreenCastCursorMode cursor_mode;
gboolean is_recording;
MetaScreenCastFlag flags;
g_autoptr (GError) error = NULL;
MetaRectangle rect;
MetaScreenCastAreaStream *area_stream;
@@ -530,11 +552,18 @@ handle_record_area (MetaDBusScreenCastSession *skeleton,
}
}
if (!g_variant_lookup (properties_variant, "is-recording", "b", &is_recording))
is_recording = FALSE;
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
backend = meta_screen_cast_get_backend (session->screen_cast);
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
flags = META_SCREEN_CAST_FLAG_NONE;
if (is_recording)
flags |= META_SCREEN_CAST_FLAG_IS_RECORDING;
rect = (MetaRectangle) {
.x = x,
.y = y,
@@ -546,6 +575,7 @@ handle_record_area (MetaDBusScreenCastSession *skeleton,
&rect,
stage,
cursor_mode,
flags,
&error);
if (!area_stream)
{
@@ -647,12 +677,37 @@ meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass)
object_class->finalize = meta_screen_cast_session_finalize;
}
static gboolean
meta_screen_cast_session_is_recording (MetaScreenCastSession *session)
{
GList *l;
if (!session->streams)
return FALSE;
for (l = session->streams; l; l = l->next)
{
MetaScreenCastStream *stream = l->data;
MetaScreenCastFlag flags;
flags = meta_screen_cast_stream_get_flags (stream);
if (!(flags & META_SCREEN_CAST_FLAG_IS_RECORDING))
return FALSE;
}
return TRUE;
}
static MetaScreenCastSessionHandle *
meta_screen_cast_session_handle_new (MetaScreenCastSession *session)
{
MetaScreenCastSessionHandle *handle;
gboolean is_recording;
handle = g_object_new (META_TYPE_SCREEN_CAST_SESSION_HANDLE, NULL);
is_recording = meta_screen_cast_session_is_recording (session);
handle = g_object_new (META_TYPE_SCREEN_CAST_SESSION_HANDLE,
"is-recording", is_recording,
NULL);
handle->session = session;
return handle;

View File

@@ -91,7 +91,8 @@ typedef struct _MetaScreenCastStreamSrcPrivate
struct spa_video_info_raw video_format;
int video_stride;
uint64_t last_frame_timestamp_us;
int64_t last_frame_timestamp_us;
guint follow_up_frame_source_id;
GHashTable *dmabuf_handles;
@@ -135,23 +136,34 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
}
static gboolean
meta_screen_cast_stream_src_record_frame (MetaScreenCastStreamSrc *src,
uint8_t *data)
meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
uint8_t *data,
GError **error)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
return klass->record_frame (src, data);
return klass->record_to_buffer (src, data, error);
}
static gboolean
meta_screen_cast_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer)
meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer,
GError **error)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
return klass->blit_to_framebuffer (src, framebuffer);
return klass->record_to_framebuffer (src, framebuffer, error);
}
static void
meta_screen_cast_stream_src_record_follow_up (MetaScreenCastStreamSrc *src)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
klass->record_follow_up (src);
}
static void
@@ -409,9 +421,10 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src,
}
static gboolean
do_record_frame (MetaScreenCastStreamSrc *src,
struct spa_buffer *spa_buffer,
uint8_t *data)
do_record_frame (MetaScreenCastStreamSrc *src,
struct spa_buffer *spa_buffer,
uint8_t *data,
GError **error)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
@@ -419,7 +432,7 @@ do_record_frame (MetaScreenCastStreamSrc *src,
if (spa_buffer->datas[0].data ||
spa_buffer->datas[0].type == SPA_DATA_MemFd)
{
return meta_screen_cast_stream_src_record_frame (src, data);
return meta_screen_cast_stream_src_record_to_buffer (src, data, error);
}
else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf)
{
@@ -429,14 +442,56 @@ do_record_frame (MetaScreenCastStreamSrc *src,
CoglFramebuffer *dmabuf_fbo =
cogl_dma_buf_handle_get_framebuffer (dmabuf_handle);
return meta_screen_cast_stream_src_blit_to_framebuffer (src, dmabuf_fbo);
return meta_screen_cast_stream_src_record_to_framebuffer (src,
dmabuf_fbo,
error);
}
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Unknown SPA buffer type %u", spa_buffer->datas[0].type);
return FALSE;
}
gboolean
meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
return priv->follow_up_frame_source_id != 0;
}
static gboolean
follow_up_frame_cb (gpointer user_data)
{
MetaScreenCastStreamSrc *src = user_data;
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
priv->follow_up_frame_source_id = 0;
meta_screen_cast_stream_src_record_follow_up (src);
return G_SOURCE_REMOVE;
}
static void
maybe_schedule_follow_up_frame (MetaScreenCastStreamSrc *src,
int64_t timeout_us)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
if (priv->follow_up_frame_source_id)
return;
priv->follow_up_frame_source_id = g_timeout_add (us2ms (timeout_us),
follow_up_frame_cb,
src);
}
void
meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
MetaScreenCastRecordFlag flags)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
@@ -445,14 +500,29 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
struct spa_buffer *spa_buffer;
uint8_t *data = NULL;
uint64_t now_us;
g_autoptr (GError) error = NULL;
now_us = g_get_monotonic_time ();
if (priv->video_format.max_framerate.num > 0 &&
priv->last_frame_timestamp_us != 0 &&
(now_us - priv->last_frame_timestamp_us <
((1000000 * priv->video_format.max_framerate.denom) /
priv->video_format.max_framerate.num)))
return;
priv->last_frame_timestamp_us != 0)
{
int64_t min_interval_us;
int64_t time_since_last_frame_us;
min_interval_us =
((G_USEC_PER_SEC * priv->video_format.max_framerate.denom) /
priv->video_format.max_framerate.num);
time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
if (time_since_last_frame_us < min_interval_us)
{
int64_t timeout_us;
timeout_us = min_interval_us - time_since_last_frame_us;
maybe_schedule_follow_up_frame (src, timeout_us);
return;
}
}
if (!priv->pipewire_stream)
return;
@@ -470,34 +540,43 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
return;
}
if (do_record_frame (src, spa_buffer, data))
if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
{
struct spa_meta_region *spa_meta_video_crop;
spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
spa_buffer->datas[0].chunk->stride = priv->video_stride;
/* Update VideoCrop if needed */
spa_meta_video_crop =
spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
sizeof (*spa_meta_video_crop));
if (spa_meta_video_crop)
g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
if (do_record_frame (src, spa_buffer, data, &error))
{
if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
struct spa_meta_region *spa_meta_video_crop;
spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
spa_buffer->datas[0].chunk->stride = priv->video_stride;
/* Update VideoCrop if needed */
spa_meta_video_crop =
spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
sizeof (*spa_meta_video_crop));
if (spa_meta_video_crop)
{
spa_meta_video_crop->region.position.x = crop_rect.x;
spa_meta_video_crop->region.position.y = crop_rect.y;
spa_meta_video_crop->region.size.width = crop_rect.width;
spa_meta_video_crop->region.size.height = crop_rect.height;
}
else
{
spa_meta_video_crop->region.position.x = 0;
spa_meta_video_crop->region.position.y = 0;
spa_meta_video_crop->region.size.width = priv->stream_width;
spa_meta_video_crop->region.size.height = priv->stream_height;
if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
{
spa_meta_video_crop->region.position.x = crop_rect.x;
spa_meta_video_crop->region.position.y = crop_rect.y;
spa_meta_video_crop->region.size.width = crop_rect.width;
spa_meta_video_crop->region.size.height = crop_rect.height;
}
else
{
spa_meta_video_crop->region.position.x = 0;
spa_meta_video_crop->region.position.y = 0;
spa_meta_video_crop->region.size.width = priv->stream_width;
spa_meta_video_crop->region.size.height = priv->stream_height;
}
}
}
else
{
g_warning ("Failed to record screen cast frame: %s", error->message);
spa_buffer->datas[0].chunk->size = 0;
}
}
else
{
@@ -539,6 +618,8 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->disable (src);
g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
priv->is_enabled = FALSE;
}
@@ -1020,7 +1101,7 @@ meta_screen_cast_stream_src_set_property (GObject *object,
{
case PROP_STREAM:
priv->stream = g_value_get_object (value);
break;;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}

View File

@@ -37,6 +37,12 @@
typedef struct _MetaScreenCastStream MetaScreenCastStream;
typedef enum _MetaScreenCastRecordFlag
{
META_SCREEN_CAST_RECORD_FLAG_NONE = 0,
META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY = 1 << 0,
} MetaScreenCastRecordFlag;
#define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc,
meta_screen_cast_stream_src,
@@ -53,17 +59,24 @@ struct _MetaScreenCastStreamSrcClass
float *frame_rate);
void (* enable) (MetaScreenCastStreamSrc *src);
void (* disable) (MetaScreenCastStreamSrc *src);
gboolean (* record_frame) (MetaScreenCastStreamSrc *src,
uint8_t *data);
gboolean (* blit_to_framebuffer) (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer);
gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
uint8_t *data,
GError **error);
gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer,
GError **error);
void (* record_follow_up) (MetaScreenCastStreamSrc *src);
gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
MetaRectangle *crop_rect);
void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor);
};
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
MetaScreenCastRecordFlag flags);
gboolean meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src);
int meta_screen_cast_stream_src_get_stride (MetaScreenCastStreamSrc *src);

View File

@@ -26,6 +26,8 @@
#include "backends/meta-screen-cast-session.h"
#include "meta-private-enum-types.h"
#define META_SCREEN_CAST_STREAM_DBUS_IFACE "org.gnome.Mutter.ScreenCast.Stream"
#define META_SCREEN_CAST_STREAM_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Stream"
@@ -36,6 +38,7 @@ enum
PROP_SESSION,
PROP_CONNECTION,
PROP_CURSOR_MODE,
PROP_FLAGS,
};
enum
@@ -55,6 +58,7 @@ typedef struct _MetaScreenCastStreamPrivate
char *object_path;
MetaScreenCastCursorMode cursor_mode;
MetaScreenCastFlag flags;
MetaScreenCastStreamSrc *src;
} MetaScreenCastStreamPrivate;
@@ -187,6 +191,15 @@ meta_screen_cast_stream_get_cursor_mode (MetaScreenCastStream *stream)
return priv->cursor_mode;
}
MetaScreenCastFlag
meta_screen_cast_stream_get_flags (MetaScreenCastStream *stream)
{
MetaScreenCastStreamPrivate *priv =
meta_screen_cast_stream_get_instance_private (stream);
return priv->flags;
}
static void
meta_screen_cast_stream_set_property (GObject *object,
guint prop_id,
@@ -208,6 +221,9 @@ meta_screen_cast_stream_set_property (GObject *object,
case PROP_CURSOR_MODE:
priv->cursor_mode = g_value_get_uint (value);
break;
case PROP_FLAGS:
priv->flags = g_value_get_flags (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -234,6 +250,9 @@ meta_screen_cast_stream_get_property (GObject *object,
case PROP_CURSOR_MODE:
g_value_set_uint (value, priv->cursor_mode);
break;
case PROP_FLAGS:
g_value_set_flags (value, priv->flags);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -337,6 +356,17 @@ meta_screen_cast_stream_class_init (MetaScreenCastStreamClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_FLAGS,
g_param_spec_flags ("flags",
"flags",
"Screen cast flags",
META_TYPE_SCREEN_CAST_FLAG,
META_SCREEN_CAST_FLAG_NONE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
signals[CLOSED] = g_signal_new ("closed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,

View File

@@ -67,4 +67,6 @@ void meta_screen_cast_stream_transform_position (MetaScreenCastStream *stream,
MetaScreenCastCursorMode meta_screen_cast_stream_get_cursor_mode (MetaScreenCastStream *stream);
MetaScreenCastFlag meta_screen_cast_stream_get_flags (MetaScreenCastStream *stream);
#endif /* META_SCREEN_CAST_STREAM_H */

View File

@@ -327,8 +327,10 @@ screen_cast_window_damaged (MetaWindowActor *actor,
MetaScreenCastWindowStreamSrc *window_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
MetaScreenCastRecordFlag flags;
meta_screen_cast_stream_src_maybe_record_frame (src);
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -365,6 +367,7 @@ static void
sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
MetaScreenCastRecordFlag flags;
if (!is_cursor_in_stream (window_src))
return;
@@ -372,7 +375,8 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
return;
meta_screen_cast_stream_src_maybe_record_frame (src);
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -401,6 +405,7 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
MetaWindowActor *window_actor;
MetaScreenCastStream *stream;
MetaScreenCastRecordFlag flags;
window_actor = meta_window_actor_from_window (get_window (window_src));
if (!window_actor)
@@ -438,7 +443,8 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
break;
}
meta_screen_cast_stream_src_maybe_record_frame (src);
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -451,8 +457,9 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
uint8_t *data)
meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
uint8_t *data,
GError **error)
{
MetaScreenCastWindowStreamSrc *window_src =
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
@@ -463,8 +470,9 @@ meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
}
static gboolean
meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer)
meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer,
GError **error)
{
MetaScreenCastWindowStreamSrc *window_src =
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
@@ -477,9 +485,13 @@ meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
stream_rect.height = get_stream_height (window_src);
if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
&stream_rect,
framebuffer))
return FALSE;
&stream_rect,
framebuffer))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to blit window content to framebuffer");
return FALSE;
}
stream = meta_screen_cast_stream_src_get_stream (src);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
@@ -497,6 +509,15 @@ meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
return TRUE;
}
static void
meta_screen_cast_window_stream_record_follow_up (MetaScreenCastStreamSrc *src)
{
MetaScreenCastRecordFlag flags;
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
@@ -580,9 +601,12 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
src_class->get_specs = meta_screen_cast_window_stream_src_get_specs;
src_class->enable = meta_screen_cast_window_stream_src_enable;
src_class->disable = meta_screen_cast_window_stream_src_disable;
src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
src_class->blit_to_framebuffer =
meta_screen_cast_window_stream_src_blit_to_framebuffer;
src_class->record_to_buffer =
meta_screen_cast_window_stream_src_record_to_buffer;
src_class->record_to_framebuffer =
meta_screen_cast_window_stream_src_record_to_framebuffer;
src_class->record_follow_up =
meta_screen_cast_window_stream_record_follow_up;
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
}

View File

@@ -84,6 +84,7 @@ meta_screen_cast_window_stream_new (MetaScreenCastSession *session,
GDBusConnection *connection,
MetaWindow *window,
MetaScreenCastCursorMode cursor_mode,
MetaScreenCastFlag flags,
GError **error)
{
return g_initable_new (META_TYPE_SCREEN_CAST_WINDOW_STREAM,
@@ -92,6 +93,7 @@ meta_screen_cast_window_stream_new (MetaScreenCastSession *session,
"session", session,
"connection", connection,
"cursor-mode", cursor_mode,
"flags", flags,
"window", window,
NULL);
}

View File

@@ -36,6 +36,7 @@ MetaScreenCastWindowStream * meta_screen_cast_window_stream_new (MetaScreenCastS
GDBusConnection *connection,
MetaWindow *window,
MetaScreenCastCursorMode cursor_mode,
MetaScreenCastFlag flags,
GError **error);
MetaWindow * meta_screen_cast_window_stream_get_window (MetaScreenCastWindowStream *window_stream);

View File

@@ -32,7 +32,7 @@
#define META_SCREEN_CAST_DBUS_SERVICE "org.gnome.Mutter.ScreenCast"
#define META_SCREEN_CAST_DBUS_PATH "/org/gnome/Mutter/ScreenCast"
#define META_SCREEN_CAST_API_VERSION 3
#define META_SCREEN_CAST_API_VERSION 4
struct _MetaScreenCast
{

View File

@@ -37,6 +37,12 @@ typedef enum _MetaScreenCastCursorMode
META_SCREEN_CAST_CURSOR_MODE_METADATA = 2,
} MetaScreenCastCursorMode;
typedef enum _MetaScreenCastFlag
{
META_SCREEN_CAST_FLAG_NONE = 0,
META_SCREEN_CAST_FLAG_IS_RECORDING = 1 << 0,
} MetaScreenCastFlag;
#define META_TYPE_SCREEN_CAST (meta_screen_cast_get_type ())
G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast,
META, SCREEN_CAST,

View File

@@ -554,7 +554,7 @@ on_udev_device_added (MetaUdev *udev,
device_path = g_udev_device_get_device_file (device);
gpus = meta_backend_get_gpus (backend);;
gpus = meta_backend_get_gpus (backend);
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;

View File

@@ -291,7 +291,7 @@ meta_crtc_kms_new (MetaGpuKms *gpu_kms,
primary_plane = meta_kms_device_get_primary_plane_for (kms_device,
kms_crtc);
crtc_kms = g_object_new (META_TYPE_CRTC_KMS,
"id", meta_kms_crtc_get_id (kms_crtc),
"id", (uint64_t) meta_kms_crtc_get_id (kms_crtc),
"gpu", gpu,
NULL);

View File

@@ -140,6 +140,24 @@ meta_input_settings_native_set_tap_and_drag_enabled (MetaInputSettings *setting
LIBINPUT_CONFIG_DRAG_DISABLED);
}
static void
meta_input_settings_native_set_tap_and_drag_lock_enabled (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
struct libinput_device *libinput_device;
libinput_device = meta_input_device_native_get_libinput_device (device);
if (!libinput_device)
return;
if (libinput_device_config_tap_get_finger_count (libinput_device) > 0)
libinput_device_config_tap_set_drag_lock_enabled (libinput_device,
enabled ?
LIBINPUT_CONFIG_DRAG_LOCK_ENABLED :
LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
}
static void
meta_input_settings_native_set_disable_while_typing (MetaInputSettings *settings,
ClutterInputDevice *device,
@@ -193,6 +211,15 @@ device_set_click_method (struct libinput_device *libinput_device,
return status == LIBINPUT_CONFIG_STATUS_SUCCESS;
}
static gboolean
device_set_tap_button_map (struct libinput_device *libinput_device,
enum libinput_config_tap_button_map map)
{
enum libinput_config_status status =
libinput_device_config_tap_set_button_map (libinput_device, map);
return status == LIBINPUT_CONFIG_STATUS_SUCCESS;
}
static void
meta_input_settings_native_set_edge_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
@@ -309,6 +336,40 @@ meta_input_settings_native_set_click_method (MetaInputSettings *settin
device_set_click_method (libinput_device, click_method);
}
static void
meta_input_settings_native_set_tap_button_map (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadTapButtonMap mode)
{
enum libinput_config_tap_button_map button_map = 0;
struct libinput_device *libinput_device;
libinput_device = meta_input_device_native_get_libinput_device (device);
if (!libinput_device)
return;
if (libinput_device_config_tap_get_finger_count (libinput_device) == 0)
return;
switch (mode)
{
case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_DEFAULT:
button_map = libinput_device_config_tap_get_default_button_map (libinput_device);
break;
case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LRM:
button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
break;
case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LMR:
button_map = LIBINPUT_CONFIG_TAP_MAP_LMR;
break;
default:
g_assert_not_reached ();
return;
}
device_set_tap_button_map (libinput_device, button_map);
}
static void
meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
gboolean enabled,
@@ -633,7 +694,10 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
input_settings_class->set_speed = meta_input_settings_native_set_speed;
input_settings_class->set_left_handed = meta_input_settings_native_set_left_handed;
input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled;
input_settings_class->set_tap_button_map = meta_input_settings_native_set_tap_button_map;
input_settings_class->set_tap_and_drag_enabled = meta_input_settings_native_set_tap_and_drag_enabled;
input_settings_class->set_tap_and_drag_lock_enabled =
meta_input_settings_native_set_tap_and_drag_lock_enabled;
input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_native_set_edge_scroll;
input_settings_class->set_two_finger_scroll = meta_input_settings_native_set_two_finger_scroll;

View File

@@ -319,6 +319,8 @@ typedef struct _RetryPageFlipData
MetaKmsPageFlipData *page_flip_data;
float refresh_rate;
uint64_t retry_time_us;
MetaKmsCustomPageFlipFunc custom_page_flip_func;
gpointer custom_page_flip_user_data;
} RetryPageFlipData;
static void
@@ -370,6 +372,7 @@ retry_page_flips (gpointer user_data)
int fd;
int ret;
MetaKmsPageFlipData *page_flip_data;
MetaKmsCustomPageFlipFunc custom_page_flip_func;
if (is_timestamp_earlier_than (now_us,
retry_page_flip_data->retry_time_us))
@@ -378,12 +381,22 @@ retry_page_flips (gpointer user_data)
continue;
}
fd = meta_kms_impl_device_get_fd (impl_device);
ret = drmModePageFlip (fd,
meta_kms_crtc_get_id (crtc),
retry_page_flip_data->fb_id,
DRM_MODE_PAGE_FLIP_EVENT,
retry_page_flip_data->page_flip_data);
custom_page_flip_func = retry_page_flip_data->custom_page_flip_func;
if (custom_page_flip_func)
{
ret = custom_page_flip_func (retry_page_flip_data->custom_page_flip_user_data,
retry_page_flip_data->page_flip_data);
}
else
{
fd = meta_kms_impl_device_get_fd (impl_device);
ret = drmModePageFlip (fd,
meta_kms_crtc_get_id (crtc),
retry_page_flip_data->fb_id,
DRM_MODE_PAGE_FLIP_EVENT,
retry_page_flip_data->page_flip_data);
}
if (ret == -EBUSY)
{
float refresh_rate;
@@ -451,11 +464,13 @@ retry_page_flips (gpointer user_data)
}
static void
schedule_retry_page_flip (MetaKmsImplSimple *impl_simple,
MetaKmsCrtc *crtc,
uint32_t fb_id,
float refresh_rate,
MetaKmsPageFlipData *page_flip_data)
schedule_retry_page_flip (MetaKmsImplSimple *impl_simple,
MetaKmsCrtc *crtc,
uint32_t fb_id,
float refresh_rate,
MetaKmsPageFlipData *page_flip_data,
MetaKmsCustomPageFlipFunc custom_page_flip_func,
gpointer custom_page_flip_user_data)
{
RetryPageFlipData *retry_page_flip_data;
uint64_t now_us;
@@ -471,6 +486,8 @@ schedule_retry_page_flip (MetaKmsImplSimple *impl_simple,
.page_flip_data = meta_kms_page_flip_data_ref (page_flip_data),
.refresh_rate = refresh_rate,
.retry_time_us = retry_time_us,
.custom_page_flip_func = custom_page_flip_func,
.custom_page_flip_user_data = custom_page_flip_user_data,
};
if (!impl_simple->retry_page_flips_source)
@@ -677,9 +694,12 @@ process_page_flip (MetaKmsImpl *impl,
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
schedule_retry_page_flip (impl_simple,
crtc,
plane_assignment->fb_id,
plane_assignment ?
plane_assignment->fb_id : 0,
refresh_rate,
page_flip_data);
page_flip_data,
custom_page_flip_func,
page_flip->custom_page_flip_user_data);
}
else
{

View File

@@ -483,7 +483,7 @@ update_states_in_impl (MetaKmsImpl *impl,
gpointer user_data,
GError **error)
{
MetaKms *kms = meta_kms_impl_get_kms (impl);;
MetaKms *kms = meta_kms_impl_get_kms (impl);
meta_kms_update_states_in_impl (kms);

View File

@@ -244,7 +244,7 @@ meta_crtc_xrandr_new (MetaGpuXrandr *gpu_xrandr,
all_transforms =
meta_monitor_transform_from_xrandr_all (xrandr_crtc->rotations);
crtc_xrandr = g_object_new (META_TYPE_CRTC_XRANDR,
"id", crtc_id,
"id", (uint64_t) crtc_id,
"gpu", gpu,
"all-transforms", all_transforms,
NULL);

View File

@@ -154,7 +154,7 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
crtc_mode_name = get_xmode_name (xmode);
mode = g_object_new (META_TYPE_CRTC_MODE,
"id", xmode->id,
"id", (uint64_t) xmode->id,
"name", crtc_mode_name,
"info", crtc_mode_info,
NULL);

View File

@@ -289,6 +289,17 @@ meta_input_settings_x11_set_tap_and_drag_enabled (MetaInputSettings *settings,
XA_INTEGER, 8, &value, 1);
}
static void
meta_input_settings_x11_set_tap_and_drag_lock_enabled (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
guchar value = (enabled) ? 1 : 0;
change_property (device, "libinput Tapping Drag Lock Enabled",
XA_INTEGER, 8, &value, 1);
}
static void
meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
@@ -429,6 +440,40 @@ meta_input_settings_x11_set_click_method (MetaInputSettings *settings,
meta_XFree(available);
}
static void
meta_input_settings_x11_set_tap_button_map (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadTapButtonMap mode)
{
guchar values[2] = { 0 }; /* lrm, lmr */
guchar *defaults;
switch (mode)
{
case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_DEFAULT:
defaults = get_property (device, "libinput Tapping Button Mapping Default",
XA_INTEGER, 8, 2);
if (!defaults)
break;
memcpy (values, defaults, 2);
meta_XFree (defaults);
break;
case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LRM:
values[0] = 1;
break;
case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LMR:
values[1] = 1;
break;
default:
g_assert_not_reached ();
return;
}
if (values[0] || values[1])
change_property (device, "libinput Tapping Button Mapping Enabled",
XA_INTEGER, 8, &values, 2);
}
static void
meta_input_settings_x11_set_keyboard_repeat (MetaInputSettings *settings,
gboolean enabled,
@@ -894,7 +939,10 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
input_settings_class->set_speed = meta_input_settings_x11_set_speed;
input_settings_class->set_left_handed = meta_input_settings_x11_set_left_handed;
input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled;
input_settings_class->set_tap_button_map = meta_input_settings_x11_set_tap_button_map;
input_settings_class->set_tap_and_drag_enabled = meta_input_settings_x11_set_tap_and_drag_enabled;
input_settings_class->set_tap_and_drag_lock_enabled =
meta_input_settings_x11_set_tap_and_drag_lock_enabled;
input_settings_class->set_disable_while_typing = meta_input_settings_x11_set_disable_while_typing;
input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_x11_set_edge_scroll;

View File

@@ -871,7 +871,7 @@ meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr,
output_info_init_backlight_limits_xrandr (output_info, xdisplay, output_id);
output = g_object_new (META_TYPE_OUTPUT_XRANDR,
"id", output_id,
"id", (uint64_t) output_id,
"gpu", gpu_xrandr,
"info", output_info,
NULL);

View File

@@ -163,7 +163,7 @@ struct _MetaBackgroundContent
CoglPipeline *pipeline;
PipelineFlags pipeline_flags;
cairo_rectangle_int_t texture_area;
gboolean force_bilinear;
int texture_width, texture_height;
cairo_region_t *clip_region;
cairo_region_t *unobscured_region;
@@ -336,9 +336,17 @@ setup_pipeline (MetaBackgroundContent *self,
self->monitor,
&self->texture_area,
&wrap_mode);
self->force_bilinear = texture &&
(self->texture_area.width != (int)cogl_texture_get_width (texture) ||
self->texture_area.height != (int)cogl_texture_get_height (texture));
if (texture)
{
self->texture_width = cogl_texture_get_width (texture);
self->texture_height = cogl_texture_get_height (texture);
}
else
{
self->texture_width = 0;
self->texture_height = 0;
}
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode);
@@ -401,12 +409,11 @@ setup_pipeline (MetaBackgroundContent *self,
opacity / 255.);
fb = clutter_paint_context_get_framebuffer (paint_context);
if (!self->force_bilinear &&
meta_actor_painting_untransformed (fb,
actor_pixel_rect->width,
actor_pixel_rect->height,
if (meta_actor_painting_untransformed (fb,
actor_pixel_rect->width,
actor_pixel_rect->height,
self->texture_width,
self->texture_height,
NULL, NULL))
{
min_filter = COGL_PIPELINE_FILTER_NEAREST;

View File

@@ -912,7 +912,7 @@ meta_background_get_texture (MetaBackground *self,
(1 - self->blend_factor),
(1 - self->blend_factor),
(1 - self->blend_factor),
(1 - self->blend_factor));;
(1 - self->blend_factor));
cogl_pipeline_set_layer_texture (pipeline, 0, texture1);
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style));
cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level);

View File

@@ -1223,7 +1223,7 @@ handle_updates (MetaWindowActorX11 *actor_x11)
meta_surface_actor_x11_handle_updates (surface_x11);
}
if (!META_IS_SURFACE_ACTOR_X11 (surface) ||
if (META_IS_SURFACE_ACTOR_X11 (surface) &&
!meta_surface_actor_x11_is_visible (META_SURFACE_ACTOR_X11 (surface)))
return;

View File

@@ -758,7 +758,7 @@ try_flip_window_position (MetaWindow *window,
int *rel_y,
MetaRectangle *intersection)
{
MetaPlacementRule flipped_rule = *placement_rule;;
MetaPlacementRule flipped_rule = *placement_rule;
MetaRectangle flipped_rect;
MetaRectangle flipped_intersection;
int flipped_rel_x;

View File

@@ -2833,7 +2833,7 @@ meta_window_maximize_internal (MetaWindow *window,
window->maximized_vertically || maximize_vertically;
/* Update the edge constraints */
update_edge_constraints (window);;
update_edge_constraints (window);
meta_window_recalc_features (window);
set_net_wm_state (window);

View File

@@ -719,6 +719,18 @@ endif
mutter_built_sources = []
if have_remote_desktop
mutter_private_enum_types = gnome.mkenums('meta-private-enum-types',
sources: [
'backends/meta-screen-cast.h',
],
c_template: 'meta-private-enum-types.c.in',
h_template: 'meta-private-enum-types.h.in',
)
mutter_built_sources += mutter_private_enum_types
endif
dbus_display_config_built_sources = gnome.gdbus_codegen('meta-dbus-display-config',
'org.gnome.Mutter.DisplayConfig.xml',
interface_prefix: 'org.gnome.Mutter.',
@@ -748,9 +760,13 @@ if have_profiler
'backends/meta-profiler.h',
]
sysprof_dbus_interfaces_dir = join_paths(sysprof_dep.get_pkgconfig_variable('datadir'), 'dbus-1', 'interfaces')
sysprof3_dbus_file = join_paths(sysprof_dbus_interfaces_dir, 'org.gnome.Sysprof3.Profiler.xml')
if sysprof_dep.type_name() == 'pkgconfig'
sysprof_dbus_interfaces_dir = join_paths(sysprof_dep.get_pkgconfig_variable('datadir'), 'dbus-1', 'interfaces')
else
sysprof_dbus_interfaces_dir = join_paths(meson.source_root(), 'subprojects', 'sysprof', 'src')
endif
sysprof3_dbus_file = join_paths(sysprof_dbus_interfaces_dir, 'org.gnome.Sysprof3.Profiler.xml')
dbus_sysprof3_profiler_built_sources = gnome.gdbus_codegen('meta-dbus-sysprof3-profiler',
sysprof3_dbus_file,
interface_prefix: 'org.gnome.',

View File

@@ -0,0 +1,40 @@
/*** BEGIN file-header ***/
#include "meta-private-enum-types.h"
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
#include "@filename@"
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
static volatile gsize g_enum_type_id__volatile = 0;
if (g_once_init_enter (&g_enum_type_id__volatile))
{
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
GType g_enum_type_id;
g_enum_type_id =
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
}
return g_enum_type_id__volatile;
}
/*** END value-tail ***/

View File

@@ -0,0 +1,25 @@
/*** BEGIN file-header ***/
#ifndef META_PRIVATE_ENUM_TYPES_H
#define META_PRIVATE_ENUM_TYPES_H
#include <glib-object.h>
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* !__MUTTER_ENUM_TYPES_H__ */
/*** END file-tail ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
#define META_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
/*** END value-header ***/

View File

@@ -21,7 +21,7 @@
#ifndef META_BACKGROUND_ACTOR_H
#define META_BACKGROUND_ACTOR_H
#include <gsettings-desktop-schemas/gdesktop-enums.h>
#include <gdesktop-enums.h>
#include "clutter/clutter.h"
#include "meta/meta-background.h"

View File

@@ -21,7 +21,7 @@
#ifndef META_BACKGROUND_CONTENT_H
#define META_BACKGROUND_CONTENT_H
#include <gsettings-desktop-schemas/gdesktop-enums.h>
#include <gdesktop-enums.h>
#include "clutter/clutter.h"
#include "meta/meta-background.h"

View File

@@ -21,7 +21,7 @@
#ifndef META_BACKGROUND_H
#define META_BACKGROUND_H
#include <gsettings-desktop-schemas/gdesktop-enums.h>
#include <gdesktop-enums.h>
#include "clutter/clutter.h"
#include "meta/display.h"

View File

@@ -79,6 +79,9 @@
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing appropriate visual feedback.
Default: false. Available since API version 4.
Available cursor mode values:
@@ -105,6 +108,9 @@
* "window-id" (t): Id of the window to record.
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see RecordMonitor).
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
-->
<method name="RecordWindow">
@@ -129,6 +135,9 @@
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:

View File

@@ -1,6 +1,7 @@
clutter_tests_conform_c_args = [
'-DG_LOG_DOMAIN="Clutter-Conform"',
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
'-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
]
clutter_tests_conform_c_args += clutter_debug_c_args

View File

@@ -7,6 +7,7 @@ clutter_tests_interactive_c_args = [
'-DGLIB_DISABLE_DEPRECATION_WARNINGS',
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
'-DCLUTTER_DISABLE_DEPRECATION_WARNINGS',
'-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
]
clutter_tests_interactive_c_args += clutter_debug_c_args

View File

@@ -137,14 +137,14 @@ meta_test_headless_monitor_connect (void)
crtc_mode_info->refresh_rate = 60.0;
crtc_mode = g_object_new (META_TYPE_CRTC_MODE,
"id", 1,
"id", (uint64_t) 1,
"info", crtc_mode_info,
NULL);
test_setup->modes = g_list_append (NULL, crtc_mode);
gpu = META_GPU (meta_backend_get_gpus (meta_get_backend ())->data);
crtc = g_object_new (META_TYPE_CRTC_TEST,
"id", 1,
"id", (uint64_t) 1,
"gpu", gpu,
NULL);
test_setup->crtcs = g_list_append (NULL, crtc);
@@ -169,7 +169,7 @@ meta_test_headless_monitor_connect (void)
output_info->connector_type = META_CONNECTOR_TYPE_DisplayPort;
output = g_object_new (META_TYPE_OUTPUT_TEST,
"id", 1,
"id", (uint64_t) 1,
"gpu", gpu,
"info", output_info,
NULL);

View File

@@ -556,7 +556,7 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
crtc_mode_info->flags = setup->modes[i].flags;
mode = g_object_new (META_TYPE_CRTC_MODE,
"id", i,
"id", (uint64_t) i,
"info", crtc_mode_info,
NULL);
@@ -569,7 +569,7 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
MetaCrtc *crtc;
crtc = g_object_new (META_TYPE_CRTC_TEST,
"id", i + 1,
"id", (uint64_t) i + 1,
"gpu", test_get_gpu (),
NULL);
@@ -676,7 +676,7 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
setup->outputs[i].panel_orientation_transform;
output = g_object_new (META_TYPE_OUTPUT_TEST,
"id", i,
"id", (uint64_t) i,
"gpu", test_get_gpu (),
"info", output_info,
NULL);

View File

@@ -495,7 +495,7 @@ meta_ui_frame_attach_style (MetaUIFrame *frame)
variant = frame->meta_window->gtk_theme_variant;
if (variant == NULL)
variant = get_global_theme_variant (frame->frames);;
variant = get_global_theme_variant (frame->frames);
if (variant == NULL || *variant == '\0')
frame->style_info = meta_style_info_ref (frames->normal_style);

View File

@@ -355,7 +355,7 @@ meta_x11_startup_notification_launch (MetaX11Display *x11_display,
(gpointer *) &func);
}
if (func)
if (func && application_id)
func (sn_launcher, application_id);
g_module_close (self);

View File

@@ -127,6 +127,7 @@ struct _MetaX11Display
struct {
Window xwindow;
guint timeout_id;
MetaSelectionSource *owners[META_N_SELECTION_TYPES];
GCancellable *cancellables[META_N_SELECTION_TYPES];

View File

@@ -79,18 +79,49 @@ static GBytes *
mimetypes_to_bytes (GList *mimetypes,
Display *xdisplay)
{
gint i = 0, len = g_list_length (mimetypes) + 2;
Atom *atoms = g_new0 (Atom, len);
GArray *atoms = g_array_new (FALSE, FALSE, sizeof (Atom));
GList *l;
char *mimetype;
Atom atom;
gboolean utf8_string_found = FALSE, utf8_string_mimetype_found = FALSE;
gboolean string_found = FALSE, string_mimetype_found = FALSE;
GBytes *bytes;
for (l = mimetypes; l; l = l->next)
atoms[i++] = XInternAtom (xdisplay, l->data, False);
{
mimetype = l->data;
atom = XInternAtom (xdisplay, mimetype, False);
g_array_append_val (atoms, atom);
utf8_string_mimetype_found |= strcmp (mimetype, UTF8_STRING_MIMETYPE) == 0;
utf8_string_found |= strcmp (mimetype, "UTF8_STRING") == 0;
string_mimetype_found |= strcmp (mimetype, STRING_MIMETYPE) == 0;
string_found |= strcmp (mimetype, "STRING") == 0;
}
atoms[i++] = XInternAtom (xdisplay, "TARGETS", False);
atoms[i++] = XInternAtom (xdisplay, "TIMESTAMP", False);
g_assert (i == len);
/* Some X11 clients can only handle STRING/UTF8_STRING but not the
* corresponding mimetypes. */
if (utf8_string_mimetype_found && !utf8_string_found)
{
atom = XInternAtom (xdisplay, "UTF8_STRING", False);
g_array_append_val (atoms, atom);
}
return g_bytes_new_take (atoms, len * sizeof (Atom));
if (string_mimetype_found && !string_found)
{
atom = XInternAtom (xdisplay, "STRING", False);
g_array_append_val (atoms, atom);
}
atom = XInternAtom (xdisplay, "TARGETS", False);
g_array_append_val (atoms, atom);
atom = XInternAtom (xdisplay, "TIMESTAMP", False);
g_array_append_val (atoms, atom);
bytes = g_bytes_new_take (atoms->data, atoms->len * sizeof (Atom));
g_array_free (atoms, FALSE);
return bytes;
}
static void
@@ -311,6 +342,22 @@ source_new_cb (GObject *object,
g_free (data);
}
static gboolean
unset_clipboard_owner (gpointer data)
{
MetaDisplay *display = meta_get_display ();
MetaSelection *selection = meta_display_get_selection (display);
MetaX11Display *x11_display = meta_display_get_x11_display (display);
meta_selection_unset_owner (selection, META_SELECTION_CLIPBOARD,
x11_display->selection.owners[META_SELECTION_CLIPBOARD]);
g_clear_object (&x11_display->selection.owners[META_SELECTION_CLIPBOARD]);
x11_display->selection.timeout_id = 0;
return G_SOURCE_REMOVE;
}
static gboolean
meta_x11_selection_handle_xfixes_selection_notify (MetaX11Display *x11_display,
XEvent *xevent)
@@ -325,6 +372,9 @@ meta_x11_selection_handle_xfixes_selection_notify (MetaX11Display *x11_display,
selection = meta_display_get_selection (meta_get_display ());
if (selection_type == META_SELECTION_CLIPBOARD)
g_clear_handle_id (&x11_display->selection.timeout_id, g_source_remove);
if (x11_display->selection.cancellables[selection_type])
{
g_cancellable_cancel (x11_display->selection.cancellables[selection_type]);
@@ -345,6 +395,19 @@ meta_x11_selection_handle_xfixes_selection_notify (MetaX11Display *x11_display,
meta_selection_set_owner (selection, selection_type, source);
g_object_unref (source);
}
else if (event->subtype == XFixesSelectionWindowDestroyNotify &&
selection_type == META_SELECTION_CLIPBOARD)
{
/* Selection window might have gotten destroyed as part of application
* shutdown. Trigger restoring clipboard, but wait a bit, because some
* clients, like wine, destroy the old window immediately before a new
* selection. Restoring the clipboard in this case would overwrite the
* new selection, so this will be cancelled when a new selection
* arrives. */
x11_display->selection.timeout_id = g_timeout_add (10,
unset_clipboard_owner,
NULL);
}
else
{
/* An X client went away, clear the selection */
@@ -422,6 +485,7 @@ meta_x11_selection_init (MetaX11Display *x11_display)
attributes.event_mask = PropertyChangeMask | SubstructureNotifyMask;
attributes.override_redirect = True;
x11_display->selection.timeout_id = 0;
x11_display->selection.xwindow =
XCreateWindow (x11_display->xdisplay,
x11_display->xroot,
@@ -482,4 +546,6 @@ meta_x11_selection_shutdown (MetaX11Display *x11_display)
XDestroyWindow (x11_display->xdisplay, x11_display->selection.xwindow);
x11_display->selection.xwindow = None;
}
g_clear_handle_id (&x11_display->selection.timeout_id, g_source_remove);
}

4
subprojects/sysprof.wrap Normal file
View File

@@ -0,0 +1,4 @@
[wrap-git]
directory=sysprof
url=https://gitlab.gnome.org/GNOME/sysprof.git
revision=cae28263ff5dd4a510d82f3dc2e3a3b3d9b386fb