Compare commits

...

10 Commits

Author SHA1 Message Date
7cab502754 Citadel changes to Mutter 2021-12-03 14:07:17 -05:00
8de96d3d7c Bump version to 41.1
Update NEWS.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2075>
2021-11-03 19:58:30 +01:00
ad787c3cf7 input-mapper: Reverse sort order of display score comparator
The `guess_candidates()` function scores each display that an input
device could be mapped to and then uses the `sort_by_score()` comparator
to find the best option. The function expects the list to be sorted from
best to worst, but the comparator currently sorts them in the opposite
order. This causes the function to end up returning the _worst_ match
rather than the the best. This commit reverses the sort order of the
comparator so that the best display can be returned as intended.

Closes: #1889

(Cherry-picked from commit 64ff1f20f8)
2021-11-02 19:11:51 +01:00
7f9defb444 clutter/stage: Only add paint volumes of mapped actors to stage clip
Right now we damage the stage even if an actor is not mapped, for
example in the overview.

Stop doing so, reducing over-paint significantly in some situations.
Clones will still do stage damage on their own.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2035>
(cherry picked from commit 136caca5d5)
2021-11-02 16:19:39 +01:00
c33ca49dfc clutter/offscreen-effect: Consider paint volumes at negative coordinates
When basing the offscreen texture position off the paint volume, the
code was assuming that the paint volume was always starting at 0,0 but
this is not the case if child widgets are placed at negative coordinates
or the widget itself is transformed. This could cause such widgets that
have been flattened and therefore rendered to an offscreen texture to
appear cut off in the top/left.

Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4561
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1923
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2031>
(cherry picked from commit 3768efef2b)
2021-11-02 16:19:39 +01:00
fd826632e8 core: Use b/w unicode for tablet mode OSD
This unicode was initially meant to be b/w, but fonts and pango
eventually had another plan and we ended up with color glyphs
being used here, so we get strings like "". Change the
unicode used to ensure these are simpler b/w glyhps like
"● ○ ○ ○" that are easier to read on the OSD (and maybe even a
bit less ugly).

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4733
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2064>
(cherry picked from commit 5125f66afa)
2021-11-02 16:19:39 +01:00
2f5c4bfc86 clutter: Fix event axes array indices in axis broadcasts
A clutter event's axes array is indexed by `ClutterInputAxis`.
However, a few lines accidentally use `ClutterInputAxisFlags` as
indices, reading incorrect values from elsewhere in memory. As a
result, broadcasted axis values for the tilt, rotation, and wheel
axes don't reflect actual event data.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1982
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2065>
(cherry picked from commit af6fb2a702)
2021-11-02 16:19:39 +01:00
42d6013bc5 clutter: Only reset preedit text if set
On ClutterInputFocus::reset, avoid to unset the preedit text if
none was set earlier. This seems to trick GTK clients into focusing
the cursor position again, even when we are moving away from it.

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

(Cherry-picked from commit 3b6f9111c7)
2021-11-01 18:37:54 +01:00
4ccdedfd99 Update Latvian translation 2021-10-26 19:14:57 +00:00
3fb3764d27 wayland/data-offer: Accept final preferrence of drop destination
Quoting the spec for `wl_data_device::drop`:
> If the resulting action is "ask", the action will not be considered
> final. The drag-and-drop destination is expected to perform one last
> wl_data_offer.set_actions request, or wl_data_offer.destroy in order
> to cancel the operation.

We did not respect the action choosen by the drop destination when
it called `wl_data_offer::set_actions` after `wl_data_device::drop`
if a user override was still active. This eventually resulted in
a protocol error in `wl_data_offer::finish`, as the current action
could still be `ask`.

Fix this by only allowing a user override to `ask` before `drop` is
called, thus making sure the final `set_actions` preference is
honored.

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

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2043>

(cherry picked from commit 33b834c433)
2021-10-14 23:11:23 +02:00
25 changed files with 1101 additions and 314 deletions

40
NEWS
View File

@ -1,3 +1,43 @@
41.1
====
* Fix monitor screencast scanouts [Michel; !1914]
* dma-buf: Use alpha-less pixel formats where appropriate [Robert; !1810]
* wayland: Allow clients to maximize windows regardless of constraints
[Christian; !1997]
* Handle hotplug events without relevant changes more effectively
[Marco; !1964]
* Improve error reporting when startup fails [Jonas; !1994]
* dma-buf: Add support for ABGR and XBGR formats [Erfan; !1999]
* Fix X11 middle button emulation setting [José; !2000]
* Include server-side shadows in window screenshots [Robert; !1996]
* Don't change workspaces of unmanaged windows [Sebastian; !2003]
* Reset idletime when unplugging the power cable [Bastien; !2029]
* xwayland: Avoid unnecessary _NET_WM_STATE events [Dor; !2032]
* Fix videos in Firefox stuttering in overview [Robert; !2034]
* Don't use atomic mode setting for virtio_gpu driver [Jonas; !2040]
* Improve on-screen keyboard on X11 [Sebastian, Ray; !1955, !2039]
* misc [Daniel, Jonas, Corentin, Robert; !1992, !2007, !2008, !2026, !2044]
* Fix text glitches after size changes [Sebastian; !2006]
* Fix reporting output rotation to xwayland [Olivier; !2050]
* wayland: Accept final preference of drop destination [Robert; !2043]
* Fix erratic scrolling in GTK apps [Carlos; gnome-shell#4647]
* Fix tilt direction of pen/tablet inputs [Quytelda; !2065]
* Use b/w unicode for tablet mode OSD [Carlos; !2064]
* Fix negative paint volume offscreen effect [Sebastian; !2031]
* Only add paint volumes of mapped actors to stage clip [Robert; !2035]
* Fix mapping tablet input to correct monitor [Jason; !1934]
* Misc. bug fixes and cleanups
Contributors:
Marco Trevisan (Treviño), Erfan Abdi, Dor Askayo, Michel Dänzer,
José Expósito, Olivier Fourdan, Carlos Garnacho, Jason Gerecke,
Quytelda Kahja, Sebastian Keller, Robert Mader, Bastien Nocera, Corentin Noël,
Christian Rauch, Ray Strode, Daniel van Vugt, Jonas Ådahl
Translators:
eshagh shahidani [fa], Danial Behzadi [fa], Марко Костић [sr],
Zander Brown [en_GB], Ngọc Quân Trần [vi], Rūdolfs Mazurs [lv]
41.0
====
* Avoid race in wl_seat capabilities [Olivier; !77]

View File

@ -103,14 +103,16 @@ clutter_input_focus_reset (ClutterInputFocus *focus)
priv = clutter_input_focus_get_instance_private (focus);
if (priv->preedit &&
priv->mode == CLUTTER_PREEDIT_RESET_COMMIT)
clutter_input_focus_commit (focus, priv->preedit);
if (priv->preedit)
{
if (priv->mode == CLUTTER_PREEDIT_RESET_COMMIT)
clutter_input_focus_commit (focus, priv->preedit);
clutter_input_focus_set_preedit_text (focus, NULL, 0);
g_clear_pointer (&priv->preedit, g_free);
}
clutter_input_focus_set_preedit_text (focus, NULL, 0);
g_clear_pointer (&priv->preedit, g_free);
priv->mode = CLUTTER_PREEDIT_RESET_CLEAR;
clutter_input_method_reset (priv->im);
}

View File

@ -336,18 +336,24 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
_clutter_paint_volume_copy_static (volume, &mutable_volume);
_clutter_paint_volume_get_bounding_box (&mutable_volume, &raw_box);
clutter_paint_volume_free (&mutable_volume);
box = raw_box;
_clutter_actor_box_enlarge_for_effects (&box);
priv->fbo_offset_x = box.x1;
priv->fbo_offset_y = box.y1;
}
else
{
clutter_actor_get_allocation_box (priv->actor, &raw_box);
box = raw_box;
_clutter_actor_box_enlarge_for_effects (&box);
priv->fbo_offset_x = box.x1 - raw_box.x1;
priv->fbo_offset_y = box.y1 - raw_box.y1;
}
box = raw_box;
_clutter_actor_box_enlarge_for_effects (&box);
priv->fbo_offset_x = box.x1 - raw_box.x1;
priv->fbo_offset_y = box.y1 - raw_box.y1;
clutter_actor_box_scale (&box, ceiled_resource_scale);
clutter_actor_box_get_size (&box, &target_width, &target_height);

View File

@ -2849,37 +2849,41 @@ clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage)
{
ClutterActor *redraw_actor = key;
QueueRedrawEntry *entry = value;
ClutterPaintVolume old_actor_pv, new_actor_pv;
g_hash_table_iter_steal (&iter);
_clutter_paint_volume_init_static (&old_actor_pv, NULL);
_clutter_paint_volume_init_static (&new_actor_pv, NULL);
if (clutter_actor_is_mapped (redraw_actor))
{
ClutterPaintVolume old_actor_pv, new_actor_pv;
if (entry->has_clip)
{
add_to_stage_clip (stage, &entry->clip);
}
else if (clutter_actor_get_redraw_clip (redraw_actor,
&old_actor_pv,
&new_actor_pv))
{
/* Add both the old paint volume of the actor (which is
* currently visible on the screen) and the new paint volume
* (which will be visible on the screen after this redraw)
* to the redraw clip.
* The former we do to ensure the old texture on the screen
* will be fully painted over in case the actor was moved.
*/
add_to_stage_clip (stage, &old_actor_pv);
add_to_stage_clip (stage, &new_actor_pv);
}
else
{
/* If there's no clip we can use, we have to trigger an
* unclipped full stage redraw.
*/
add_to_stage_clip (stage, NULL);
_clutter_paint_volume_init_static (&old_actor_pv, NULL);
_clutter_paint_volume_init_static (&new_actor_pv, NULL);
if (entry->has_clip)
{
add_to_stage_clip (stage, &entry->clip);
}
else if (clutter_actor_get_redraw_clip (redraw_actor,
&old_actor_pv,
&new_actor_pv))
{
/* Add both the old paint volume of the actor (which is
* currently visible on the screen) and the new paint volume
* (which will be visible on the screen after this redraw)
* to the redraw clip.
* The former we do to ensure the old texture on the screen
* will be fully painted over in case the actor was moved.
*/
add_to_stage_clip (stage, &old_actor_pv);
add_to_stage_clip (stage, &new_actor_pv);
}
else
{
/* If there's no clip we can use, we have to trigger an
* unclipped full stage redraw.
*/
add_to_stage_clip (stage, NULL);
}
}
g_object_unref (redraw_actor);

View File

@ -1,5 +1,5 @@
project('mutter', 'c',
version: '41.0',
version: '41.1',
meson_version: '>= 0.53.0',
license: 'GPLv2+'
)

410
po/lv.po
View File

@ -7,13 +7,13 @@
# Raivis Dejus <orvils@gmail.com>, 2006, 2007, 2009.
# Rudolfs <rudolfs.mazurs@gmail.com>, 2011.
# Rūdofls Mazurs <rudolfs.mazurs@gmail.com>, 2011, 2012.
# Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020.
# Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021.
msgid ""
msgstr ""
"Project-Id-Version: lv\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2020-08-29 10:31+0000\n"
"PO-Revision-Date: 2020-09-12 13:08+0300\n"
"POT-Creation-Date: 2021-10-14 16:28+0000\n"
"PO-Revision-Date: 2021-10-26 22:14+0300\n"
"Last-Translator: Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>\n"
"Language-Team: Latvian <lata-l10n@googlegroups.com>\n"
"Language: lv\n"
@ -22,7 +22,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 :"
" 2);\n"
"X-Generator: Lokalize 19.12.3\n"
"X-Generator: Lokalize 21.08.1\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@ -49,114 +49,134 @@ msgid "Move window to last workspace"
msgstr "Pārvietot logu uz pēdējo darbvietu"
#: data/50-mutter-navigation.xml:24
#| msgid "Move window one monitor to the left"
msgid "Move window one workspace to the left"
msgstr "Pārvietot logu uz darbvietu pa kreisi"
#: data/50-mutter-navigation.xml:27
#| msgid "Move window one monitor to the right"
msgid "Move window one workspace to the right"
msgstr "Pārvietot logu uz darbvietu pa labi"
#: data/50-mutter-navigation.xml:31
msgid "Move window one workspace up"
msgstr "Pārvietot logu uz darbvietu augšup"
#: data/50-mutter-navigation.xml:27
#: data/50-mutter-navigation.xml:35
msgid "Move window one workspace down"
msgstr "Pārvietot logu uz darbvietu lejup"
#: data/50-mutter-navigation.xml:30
#: data/50-mutter-navigation.xml:38
msgid "Move window one monitor to the left"
msgstr "Pārvietot logu uz monitoru pa kreisi"
#: data/50-mutter-navigation.xml:33
#: data/50-mutter-navigation.xml:41
msgid "Move window one monitor to the right"
msgstr "Pārvietot logu uz monitoru pa labi"
#: data/50-mutter-navigation.xml:36
#: data/50-mutter-navigation.xml:44
msgid "Move window one monitor up"
msgstr "Pārvietot logu uz monitoru augšup"
#: data/50-mutter-navigation.xml:39
#: data/50-mutter-navigation.xml:47
msgid "Move window one monitor down"
msgstr "Pārvietot logu uz monitoru lejup"
#: data/50-mutter-navigation.xml:43
#: data/50-mutter-navigation.xml:51
msgid "Switch applications"
msgstr "Pārslēgt lietotnes"
#: data/50-mutter-navigation.xml:48
#: data/50-mutter-navigation.xml:56
msgid "Switch to previous application"
msgstr "Pārslēgties uz iepriekšējo lietotni"
#: data/50-mutter-navigation.xml:52
#: data/50-mutter-navigation.xml:60
msgid "Switch windows"
msgstr "Pārslēgt logus"
#: data/50-mutter-navigation.xml:57
#: data/50-mutter-navigation.xml:65
msgid "Switch to previous window"
msgstr "Pārslēgties uz iepriekšējo logu"
#: data/50-mutter-navigation.xml:61
#: data/50-mutter-navigation.xml:69
msgid "Switch windows of an application"
msgstr "Pārslēgt vienas lietotnes logus"
#: data/50-mutter-navigation.xml:66
#: data/50-mutter-navigation.xml:74
msgid "Switch to previous window of an application"
msgstr "Pārslēgties uz lietotnes iepriekšējo logu"
#: data/50-mutter-navigation.xml:70
#: data/50-mutter-navigation.xml:78
msgid "Switch system controls"
msgstr "Pārslēgt sistēmas vadīklas"
#: data/50-mutter-navigation.xml:75
#: data/50-mutter-navigation.xml:83
msgid "Switch to previous system control"
msgstr "Pārslēgties uz iepriekšējo sistēmas vadīklu"
#: data/50-mutter-navigation.xml:79
#: data/50-mutter-navigation.xml:87
msgid "Switch windows directly"
msgstr "Pārslēgties starp logiem tieši"
#: data/50-mutter-navigation.xml:84
#: data/50-mutter-navigation.xml:92
msgid "Switch directly to previous window"
msgstr "Pārslēgties tieši uz iepriekšējo logu"
#: data/50-mutter-navigation.xml:88
#: data/50-mutter-navigation.xml:96
msgid "Switch windows of an app directly"
msgstr "Pārslēgties starp lietotnes logiem tieši"
#: data/50-mutter-navigation.xml:93
#: data/50-mutter-navigation.xml:101
msgid "Switch directly to previous window of an app"
msgstr "Pārslēgties tieši uz iepriekšējo lietotnes logu"
#: data/50-mutter-navigation.xml:97
#: data/50-mutter-navigation.xml:105
msgid "Switch system controls directly"
msgstr "Pārslēgt sistēmas vadīklas tieši"
#: data/50-mutter-navigation.xml:102
#: data/50-mutter-navigation.xml:110
msgid "Switch directly to previous system control"
msgstr "Pārslēgties tieši uz iepriekšējo sistēmas vadīklu"
#: data/50-mutter-navigation.xml:105
#: data/50-mutter-navigation.xml:113
msgid "Hide all normal windows"
msgstr "Slēpt visus parastos logus"
#: data/50-mutter-navigation.xml:108
#: data/50-mutter-navigation.xml:116
msgid "Switch to workspace 1"
msgstr "Pārslēgties uz 1. darbvietu"
#: data/50-mutter-navigation.xml:111
#: data/50-mutter-navigation.xml:119
msgid "Switch to workspace 2"
msgstr "Pārslēgties uz 2. darbvietu"
#: data/50-mutter-navigation.xml:114
#: data/50-mutter-navigation.xml:122
msgid "Switch to workspace 3"
msgstr "Pārslēgties uz 3. darbvietu"
#: data/50-mutter-navigation.xml:117
#: data/50-mutter-navigation.xml:125
msgid "Switch to workspace 4"
msgstr "Pārslēgties uz 4. darbvietu"
#: data/50-mutter-navigation.xml:120
#: data/50-mutter-navigation.xml:128
msgid "Switch to last workspace"
msgstr "Pārslēgties uz pēdējo darbvietu"
#: data/50-mutter-navigation.xml:123
#: data/50-mutter-navigation.xml:131
#| msgid "Move to workspace above"
msgid "Move to workspace on the left"
msgstr "Pāriet uz darbvietu pa kreisi"
#: data/50-mutter-navigation.xml:134
#| msgid "Move to workspace above"
msgid "Move to workspace on the right"
msgstr "Pāriet uz darbvietu pa labi"
#: data/50-mutter-navigation.xml:138
msgid "Move to workspace above"
msgstr "Pāriet uz darbvietu augšup"
#: data/50-mutter-navigation.xml:126
#: data/50-mutter-navigation.xml:142
msgid "Move to workspace below"
msgstr "Pāriet uz darbvietu lejup"
@ -168,10 +188,6 @@ msgstr "Sistēma"
msgid "Show the run command prompt"
msgstr "Rādīt palaišanas komandrindu"
#: data/50-mutter-system.xml:10
msgid "Show the activities overview"
msgstr "Rādīt aktivitāšu pārskatu"
#: data/50-mutter-wayland.xml:8
msgid "Restore the keyboard shortcuts"
msgstr "Atjaunot tastatūras saīsnes"
@ -240,11 +256,11 @@ msgstr "Maksimizēt logu vertikāli"
msgid "Maximize window horizontally"
msgstr "Maksimizēt logu horizontāli"
#: data/50-mutter-windows.xml:41
#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:166
msgid "View split on left"
msgstr "Izvietot kreisajā ekrāna pusē"
#: data/50-mutter-windows.xml:45
#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:171
msgid "View split on right"
msgstr "Izvietot labajā ekrāna pusē"
@ -388,6 +404,19 @@ msgid "Enable experimental features"
msgstr "Ieslēgt eksperimentālās iespējas"
#: data/org.gnome.mutter.gschema.xml.in:108
#| msgid ""
#| "To enable experimental features, add the feature keyword to the list. "
#| "Whether the feature requires restarting the compositor depends on the "
#| "given feature. Any experimental feature is not required to still be "
#| "available, or configurable. Dont expect adding anything in this setting "
#| "to be future proof. Currently possible keywords: • “scale-monitor-"
#| "framebuffer” — makes mutter default to layout logical monitors in a "
#| "logical pixel coordinate space, while scaling monitor framebuffers "
#| "instead of window content, to manage HiDPI monitors. Does not require a "
#| "restart. • “rt-scheduler” — makes mutter request a low priority real-time "
#| "scheduling. The executable or user must have CAP_SYS_NICE. Requires a "
#| "restart. • “autostart-xwayland” — initializes Xwayland lazily if there "
#| "are X11 clients. Requires restart."
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
@ -398,8 +427,11 @@ msgid ""
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes "
"mutter request a low priority real-time scheduling. The executable or user "
"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — "
"initializes Xwayland lazily if there are X11 clients. Requires restart."
"must have CAP_SYS_NICE. Requires a restart. • “dma-buf-screen-sharing\" — "
"enables DMA buffered screen sharing. This is already enabled by default when "
"using the i915 driver, but disabled for everything else. Requires a restart. "
"• “autoclose-xwayland” — automatically terminates Xwayland if all relevant "
"X11 clients are gone. Does not require a restart."
msgstr ""
"Lai ieslēgtu eksperimentālās iespējas, pievienojiet iespējas atslēgvārdu "
"sarakstam. Vai iespējai būs nepieciešama kompozitora pārstartēšana, būs "
@ -411,44 +443,45 @@ msgstr ""
"loga saturu, lai pārvaldītu HiDPI monitorus. Pārstartēšana nav nepieciešama. "
"• “rt-scheduler” — liek mutter pieprasīt mazāku prioritāti reālā laika "
"procesu plānošanā. Izpildāmajai datnei vai lietotājam ir jābūt ar "
"CAP_SYS_NICE. Pārstartēšana ir nepieciešama. • “autostart-xwayland” — "
"inicializē Xwayland slinki, ja eksistē X11 klienti. Pārstartēšana ir "
"nepieciešama."
"CAP_SYS_NICE. Nepieciešama pārstartēšana. • “dma-buf-screen-sharing” —"
" izmanto i915 draiveri, bet ir izslēgts visam citam. Nepieciešama"
" pārstartēšana. • “autoclose-xwayland” — automātiski aptur Xwayland, ja visi"
" būtiskie X11 klienti ir pazuduši. Pārstartēšana nav nepieciešama."
#: data/org.gnome.mutter.gschema.xml.in:134
#: data/org.gnome.mutter.gschema.xml.in:143
msgid "Modifier to use to locate the pointer"
msgstr "Modifikators, ko izmantot, lai atrastu rādītāju"
#: data/org.gnome.mutter.gschema.xml.in:135
#: data/org.gnome.mutter.gschema.xml.in:144
msgid "This key will initiate the “locate pointer” action."
msgstr "Šī atslēga inicializēs “atrast rādītāju” darbību."
#: data/org.gnome.mutter.gschema.xml.in:142
#: data/org.gnome.mutter.gschema.xml.in:151
msgid "Timeout for check-alive ping"
msgstr "Aktivitātes pārbaudes ping noildze"
#: data/org.gnome.mutter.gschema.xml.in:143
#: data/org.gnome.mutter.gschema.xml.in:152
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 ""
"Laiks milisekundēs, kurā klientam ir jāatbild uz ping pieprasījumu, lai"
" klientu neuzskatītu par iesalušu. Ja norādītais laiks ir 0, aktivitātes"
" pārbaude netiks veikta."
"Laiks milisekundēs, kurā klientam ir jāatbild uz ping pieprasījumu, lai "
"klientu neuzskatītu par iesalušu. Ja norādītais laiks ir 0, aktivitātes "
"pārbaude netiks veikta."
#: data/org.gnome.mutter.gschema.xml.in:165
#: data/org.gnome.mutter.gschema.xml.in:176
msgid "Select window from tab popup"
msgstr "Izvēlēties logu no tabulatora izvēlnes"
#: data/org.gnome.mutter.gschema.xml.in:170
#: data/org.gnome.mutter.gschema.xml.in:181
msgid "Cancel tab popup"
msgstr "Atcelt logu rādīšanu"
#: data/org.gnome.mutter.gschema.xml.in:175
#: data/org.gnome.mutter.gschema.xml.in:186
msgid "Switch monitor configurations"
msgstr "Pārslēgt monitoru konfigurācijas"
#: data/org.gnome.mutter.gschema.xml.in:180
#: data/org.gnome.mutter.gschema.xml.in:191
msgid "Rotates the built-in monitor configuration"
msgstr "Pagriež iebūvētā monitora konfigurāciju"
@ -509,16 +542,6 @@ msgid "Allow X11 grabs to lock keyboard focus with Xwayland"
msgstr "Atļaut X11 satvērieniem bloķēt tastatūras fokusu ar Xwayland"
#: data/org.gnome.mutter.wayland.gschema.xml.in:71
#| msgid ""
#| "Allow all keyboard events to be routed to X11 “override redirect” windows "
#| "with a grab when running in Xwayland. This option is to support X11 "
#| "clients which map an “override redirect” window (which do not receive "
#| "keyboard focus) and issue a keyboard grab to force all keyboard events to "
#| "that window. This option is seldom used and has no effect on regular X11 "
#| "windows which can receive keyboard focus under normal circumstances. For "
#| "a X11 grab to be taken into account under Wayland, the client must also "
#| "either send a specific X11 ClientMessage to the root window or be among "
#| "the applications white-listed in key “xwayland-grab-access-rules”."
msgid ""
"Allow all keyboard events to be routed to X11 “override redirect” windows "
"with a grab when running in Xwayland. This option is to support X11 clients "
@ -545,17 +568,6 @@ msgid "Xwayland applications allowed to issue keyboard grabs"
msgstr "Xwayland lietotnes, kuras drīkst pieprasīt tastatūras satveršanu"
#: data/org.gnome.mutter.wayland.gschema.xml.in:91
#| msgid ""
#| "List the resource names or resource class of X11 windows either allowed "
#| "or not allowed to issue X11 keyboard grabs under Xwayland. The resource "
#| "name or resource class of a given X11 window can be obtained using the "
#| "command “xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are "
#| "supported. Values starting with “!” are blacklisted, which has precedence "
#| "over the whitelist, to revoke applications from the default system list. "
#| "The default system list includes the following applications: "
#| "“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab "
#| "by using the specific keyboard shortcut defined by the keybinding key "
#| "“restore-shortcuts”."
msgid ""
"List the resource names or resource class of X11 windows either allowed or "
"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or "
@ -572,10 +584,9 @@ msgstr ""
"drīkst, vai nedrīkst pieprasīt X11 tastatūras satveršanu zem Xwayland. "
"Resursa nosaukumu vai resursa klasi dotajam X11 logam var iegūt, izmantojot "
"komandu “xprop WM_CLASS”. Vērtībās ir atbalstītas aizstājējzīmes “*” un “?”. "
"Vērtības, kas sākas ar “!”, ir aizliegto vērtību sarakstā, kam ir prioritāte"
" pār atļauto vērtību "
"sarakstu, kad atsauc lietotnes no noklusējuma sistēmas saraksta. Noklusējuma "
"sistēmas sarakstā iekļauj sekojošās lietotnes: "
"Vērtības, kas sākas ar “!”, ir aizliegto vērtību sarakstā, kam ir prioritāte "
"pār atļauto vērtību sarakstu, kad atsauc lietotnes no noklusējuma sistēmas "
"saraksta. Noklusējuma sistēmas sarakstā iekļauj sekojošās lietotnes: "
"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Lietotāji var pārtraukt esošo "
"tvērienu, izmantojot noteiktus tastatūras īsinājumtaustiņus, kas ir noteikti "
"“restore-shortcuts” atslēgā."
@ -591,50 +602,31 @@ msgid ""
"Xwayland was built without support for the selected extensions. Xwayland "
"needs to be restarted for this setting to take effect."
msgstr ""
"Šī opcija izslēdz izvēlētos X paplašinājumus Xwayland sistēmā, ja Xwayland"
" tika uzbūvēts ar atbalstu šiem X paplašinājumiem. Šai opcijai nav ietekmes,"
" ja Xwayland tika uzbūvēts bez atbalstra izvēlētajiem paplašinājumiem. Lai"
" šie iestatījumi stātos spēkā, Xwayland ir jāpārstartē."
"Šī opcija izslēdz izvēlētos X paplašinājumus Xwayland sistēmā, ja Xwayland "
"tika uzbūvēts ar atbalstu šiem X paplašinājumiem. Šai opcijai nav ietekmes, "
"ja Xwayland tika uzbūvēts bez atbalstra izvēlētajiem paplašinājumiem. Lai "
"šie iestatījumi stātos spēkā, Xwayland ir jāpārstartē."
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2698
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Režīma slēdzis (grupa %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2721
msgid "Switch monitor"
msgstr "Pārslēgt monitoru"
#: src/backends/meta-input-settings.c:2723
msgid "Show on-screen help"
msgstr "Rādīt palīdzību uz ekrāna"
#: src/backends/meta-monitor.c:235
#: src/backends/meta-monitor.c:246
msgid "Built-in display"
msgstr "Iebūvēts displejs"
#: src/backends/meta-monitor.c:264
#: src/backends/meta-monitor.c:275
msgid "Unknown"
msgstr "Nezināms"
#: src/backends/meta-monitor.c:266
#: src/backends/meta-monitor.c:277
msgid "Unknown Display"
msgstr "Nezināms displejs"
#: src/backends/meta-monitor.c:274
#: src/backends/meta-monitor.c:285
#, 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:282
#: src/backends/meta-monitor.c:293
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
@ -647,9 +639,28 @@ msgstr "%s %s"
msgid "Compositor"
msgstr "Kompozitors"
#: src/backends/x11/meta-clutter-backend-x11.c:237
#| msgid "X Display to use"
msgid "X display to use"
msgstr "Izmantojamais X displejs"
#: src/backends/x11/meta-clutter-backend-x11.c:243
#| msgid "X Display to use"
msgid "X screen to use"
msgstr "Izmantojamais X ekrāns"
#: src/backends/x11/meta-clutter-backend-x11.c:248
#: src/core/meta-context-main.c:585
msgid "Make X calls synchronous"
msgstr "Padarīt X izsaukumus sinhronus"
#: src/backends/x11/meta-clutter-backend-x11.c:254
msgid "Disable XInput support"
msgstr "Deaktivēt XInput atbalstu"
#. 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:516
#: src/compositor/compositor.c:513
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@ -659,50 +670,6 @@ msgstr "Cits kompozīcijas pārvaldnieks jau darbojas ekrānā %d displejā “%
msgid "Bell event"
msgstr "Zvana notikums"
#: src/core/main.c:190
msgid "Disable connection to session manager"
msgstr "Deaktivēt savienojumu ar sesiju pārvaldnieku"
#: src/core/main.c:196
msgid "Replace the running window manager"
msgstr "Aizvietot darbojošos logu pārvaldnieku"
#: src/core/main.c:202
msgid "Specify session management ID"
msgstr "Norādiet sesiju pārvaldības ID"
#: src/core/main.c:207
msgid "X Display to use"
msgstr "Lietojamais X displejs"
#: src/core/main.c:213
msgid "Initialize session from savefile"
msgstr "Inicializēt sesiju no saglabātās datnes"
#: src/core/main.c:219
msgid "Make X calls synchronous"
msgstr "Padarīt X izsaukumus sinhronus"
#: src/core/main.c:226
msgid "Run as a wayland compositor"
msgstr "Palaist kā wayland kompozitoru"
#: src/core/main.c:232
msgid "Run as a nested compositor"
msgstr "Palaist kā ligzdotu kompozitoru"
#: src/core/main.c:238
msgid "Run wayland compositor without starting Xwayland"
msgstr "Palaist wayland kompozitoru nestartējot Xwayland"
#: src/core/main.c:246
msgid "Run as a full display server, rather than nested"
msgstr "Palaist kā pilnu attēlošanas serveri, nevis iegultu"
#: src/core/main.c:252
msgid "Run with X11 backend"
msgstr "Palaist ar X11 aizmuguri"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:151
#, c-format
@ -729,44 +696,102 @@ msgstr "Aizvērt _piespiedu kārtā"
msgid "_Wait"
msgstr "_Gaidīt"
#: src/core/mutter.c:38
#, c-format
msgid ""
"mutter %s\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Autortiesības © 2001-%d Havoc Pennington, Red Hat, Inc., un citi\n"
"Šī ir brīvā programmatūra; par kopēšanas nosacījumiem skatīt avotu.\n"
"Netiek dota NEKĀDA garantija; pat ne KOMERCIĀLAS VĒRTĪBAS vai DERĪGUMA "
"NOTEIKTAM NOLŪKAM.\n"
#: src/core/meta-context-main.c:555
msgid "Replace the running window manager"
msgstr "Aizvietot darbojošos logu pārvaldnieku"
#: src/core/mutter.c:52
#: src/core/meta-context-main.c:561
msgid "X Display to use"
msgstr "Lietojamais X displejs"
#: src/core/meta-context-main.c:567
msgid "Disable connection to session manager"
msgstr "Deaktivēt savienojumu ar sesiju pārvaldnieku"
#: src/core/meta-context-main.c:573
msgid "Specify session management ID"
msgstr "Norādiet sesiju pārvaldības ID"
#: src/core/meta-context-main.c:579
msgid "Initialize session from savefile"
msgstr "Inicializēt sesiju no saglabātās datnes"
#: src/core/meta-context-main.c:592
msgid "Run as a wayland compositor"
msgstr "Palaist kā wayland kompozitoru"
#: src/core/meta-context-main.c:598
msgid "Run as a nested compositor"
msgstr "Palaist kā ligzdotu kompozitoru"
#: src/core/meta-context-main.c:604
msgid "Run wayland compositor without starting Xwayland"
msgstr "Palaist wayland kompozitoru nestartējot Xwayland"
#: src/core/meta-context-main.c:610
msgid "Specify Wayland display name to use"
msgstr "Norādiet Wayland displeja nosaukumu, kuru izmantot"
#: src/core/meta-context-main.c:618
msgid "Run as a full display server, rather than nested"
msgstr "Palaist kā pilnu attēlošanas serveri, nevis iegultu"
#: src/core/meta-context-main.c:623
#| msgid "Run as a full display server, rather than nested"
msgid "Run as a headless display server"
msgstr "Palaist kā bezdispleja attēlošanas serveri"
#: src/core/meta-context-main.c:628
msgid "Add persistent virtual monitor (WxH or WxH@R)"
msgstr "Pievienot pastāvīgu virtuālo monitoru (WxH vai WxH@R)"
#: src/core/meta-context-main.c:639
msgid "Run with X11 backend"
msgstr "Palaist ar X11 aizmuguri"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/core/meta-pad-action-mapper.c:782
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Režīma slēdzis (grupa %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/core/meta-pad-action-mapper.c:805
msgid "Switch monitor"
msgstr "Pārslēgt monitoru"
#: src/core/meta-pad-action-mapper.c:807
msgid "Show on-screen help"
msgstr "Rādīt palīdzību uz ekrāna"
#: src/core/mutter.c:48
msgid "Print version"
msgstr "Parādīt versiju"
#: src/core/mutter.c:58
#: src/core/mutter.c:54
msgid "Mutter plugin to use"
msgstr "Izmantojamais mutter spraudnis"
#: src/core/prefs.c:1911
#: src/core/prefs.c:1913
#, c-format
msgid "Workspace %d"
msgstr "Darbvieta %d"
#: src/core/util.c:119
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter tika kompilēts bez detalizētas izvades režīma atbalsta\n"
#: src/core/util.c:148
#| msgid "Mutter was compiled without support for verbose mode\n"
msgid "Mutter was compiled without support for verbose mode"
msgstr "Mutter tika kompilēts bez detalizētas izvades režīma atbalsta"
#: src/wayland/meta-wayland-tablet-pad.c:568
#: src/wayland/meta-wayland-tablet-pad.c:519
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Režīma slēdzis: režīms %d"
#: src/x11/meta-x11-display.c:676
#: src/x11/meta-x11-display.c:673
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
@ -775,26 +800,29 @@ msgstr ""
"Displejam “%s” jau ir logu pārvaldnieks; mēģiniet lietot --replace iespēju, "
"lai aizvietotu pašreizējo logu pārvaldnieku."
#: src/x11/meta-x11-display.c:1089
msgid "Failed to initialize GDK\n"
msgstr "Neizdevās inicializēt GDK\n"
#: src/x11/meta-x11-display.c:1067
#| msgid "Failed to initialize GDK\n"
msgid "Failed to initialize GDK"
msgstr "Neizdevās inicializēt GDK"
#: src/x11/meta-x11-display.c:1113
#: src/x11/meta-x11-display.c:1091
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "Neizdevās atvērt X logu sistēmas displeju “%s”\n"
#| msgid "Failed to open X Window System display “%s”\n"
msgid "Failed to open X Window System display “%s”"
msgstr "Neizdevās atvērt X logu sistēmas displeju “%s”"
#: src/x11/meta-x11-display.c:1196
#: src/x11/meta-x11-display.c:1175
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "Ekrāna %d displejs “%s“ nav derīgs\n"
#| msgid "Screen %d on display “%s” is invalid\n"
msgid "Screen %d on display “%s” is invalid"
msgstr "Ekrāna %d displejs “%s“ nav derīgs"
#: src/x11/meta-x11-selection-input-stream.c:460
#, c-format
msgid "Format %s not supported"
msgstr "%s formāts nav atbalstīts"
#: src/x11/session.c:1821
#: src/x11/session.c:1845
msgid ""
"These windows do not support “save current setup” and will have to be "
"restarted manually next time you log in."
@ -806,3 +834,19 @@ msgstr ""
#, c-format
msgid "%s (on %s)"
msgstr "%s (uz %s)"
#~ msgid "Show the activities overview"
#~ msgstr "Rādīt aktivitāšu pārskatu"
#~ msgid ""
#~ "mutter %s\n"
#~ "Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
#~ "This is free software; see the source for copying conditions.\n"
#~ "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
#~ "PARTICULAR PURPOSE.\n"
#~ msgstr ""
#~ "mutter %s\n"
#~ "Autortiesības © 2001-%d Havoc Pennington, Red Hat, Inc., un citi\n"
#~ "Šī ir brīvā programmatūra; par kopēšanas nosacījumiem skatīt avotu.\n"
#~ "Netiek dota NEKĀDA garantija; pat ne KOMERCIĀLAS VĒRTĪBAS vai DERĪGUMA "
#~ "NOTEIKTAM NOLŪKAM.\n"

View File

@ -473,7 +473,7 @@ static int
sort_by_score (DeviceMatch *match1,
DeviceMatch *match2)
{
return (int) match1->score - match2->score;
return (int) match2->score - match1->score;
}
static void

View File

@ -747,8 +747,13 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
meta_compositor_get_instance_private (compositor);
gint to_indx, from_indx;
to_indx = meta_workspace_index (to);
from_indx = meta_workspace_index (from);
if (direction == META_MOTION_CONTEXT_SWITCH) {
to_indx = meta_workspace_get_id (to);
from_indx = meta_workspace_get_id (from);
} else {
to_indx = meta_workspace_index (to);
from_indx = meta_workspace_index (from);
}
priv->switch_workspace_in_progress++;

View File

@ -3135,9 +3135,13 @@ meta_display_notify_pad_group_switch (MetaDisplay *display,
pretty_name = clutter_input_device_get_device_name (pad);
message = g_string_new (pretty_name);
g_string_append_c (message, '\n');
g_string_append (message, "\n\n");
for (i = 0; i < n_modes; i++)
g_string_append (message, (i == n_mode) ? "" : "");
{
if (i > 0)
g_string_append_c (message, ' ');
g_string_append (message, (i == n_mode) ? "" : "");
}
meta_display_show_osd (display, lookup_tablet_monitor (display, pad),
"input-tablet-symbolic", message->str);

View File

@ -30,6 +30,36 @@
#include "meta/types.h"
#include "meta/meta-workspace-manager.h"
//
// Stores list of MetaWorkspaces and pointer to an active MetaWorkspace. When this context becomes
// the current context, the workspace fields are swapped into the corresponding fields in
// MetaWorkspaceManager.
//
//
struct _MetaWorkspaceContext
{
GObject parent;
// Link back to MetaWorkspaceManager
MetaWorkspaceManager *manager;
// MetaWorkspace list belonging to this context. Copied to field with same name in
// MetaWorkspaceManager when this context is active. Any code which changes this list
// must make sure this context is not currently active in which case the list in
// MetaWorkspaceManager must be changed instead.
GList *workspaces;
// Active MetaWorkspace for this context. Also copied to workspace manager upon activation.
// The rule above about not writing if context is currently active also applies to this field.
MetaWorkspace *active_workspace;
// PID namespace
gchar *namespace;
// A unique ID value for this context.
guint id;
};
struct _MetaWorkspaceManager
{
GObject parent;
@ -37,8 +67,21 @@ struct _MetaWorkspaceManager
MetaDisplay *display;
MetaWorkspace *active_workspace;
GList *all_workspaces;
GList *workspaces;
// List of WorkspaceContext
GList *context_list;
gchar *mutter_namespace;
// Current active WorkspaceContext. MetaWorkspaceManager state (workspaces, active_workspace)
// will be saved here when a new WorkspaceContext is made active.
MetaWorkspaceContext *active_context;
// The next id value to allocate when creating a new WorkspaceContext
guint next_context_id;
int rows_of_workspaces;
int columns_of_workspaces;
MetaDisplayCorner starting_corner;
@ -93,4 +136,30 @@ void meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspa
guint32 timestamp,
int new_num);
MetaWorkspaceContext *meta_workspace_context_new (MetaWorkspaceManager *manager, const char *namespace);
void meta_workspace_context_make_active (MetaWorkspaceContext *context);
MetaWorkspaceContext *meta_workspace_manager_lookup_context (MetaWorkspaceManager *workspace_manager,
guint context_id);
void meta_workspace_manager_append_context_workspace (MetaWorkspaceManager *manager,
MetaWorkspace *workspace);
void meta_workspace_manager_remove_context_workspace (MetaWorkspaceManager *manager,
MetaWorkspace *workspace);
int meta_workspace_manager_context_workspace_index (MetaWorkspaceManager *workspace_manager,
MetaWorkspace *workspace);
int meta_workspace_manager_get_workspace_id (MetaWorkspaceManager *workspace_manager,
MetaWorkspace *workspace);
MetaWorkspace *
meta_workspace_manager_lookup_workspace_by_id (MetaWorkspaceManager *workspace_manager, int workspace_id);
gboolean
meta_workspace_manager_is_window_on_foreign_context (MetaWorkspaceManager *workspace_manager, MetaWindow *window);
#endif /* META_WORKSPACE_MANAGER_PRIVATE_H */

View File

@ -44,6 +44,9 @@ enum
WORKSPACES_REORDERED,
ACTIVE_WORKSPACE_CHANGED,
SHOWING_DESKTOP_CHANGED,
CONTEXT_SWITCHED,
CONTEXT_WINDOW_MOVED,
CONTEXT_REMOVED,
LAST_SIGNAL
};
@ -178,6 +181,29 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass)
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
workspace_manager_signals[CONTEXT_SWITCHED] =
g_signal_new ("context-switched",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
workspace_manager_signals[CONTEXT_WINDOW_MOVED] =
g_signal_new("context-window-moved",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_WINDOW);
workspace_manager_signals[CONTEXT_REMOVED] =
g_signal_new("context-removed",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
G_TYPE_INT);
g_object_class_install_property (object_class,
PROP_LAYOUT_COLUMNS,
g_param_spec_int ("layout-columns",
@ -201,6 +227,7 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass)
"Number of workspaces",
1, G_MAXINT, 1,
G_PARAM_READABLE));
}
static void
@ -213,7 +240,7 @@ meta_workspace_manager_reload_work_areas (MetaWorkspaceManager *workspace_manage
{
GList *l;
for (l = workspace_manager->workspaces; l; l = l->next)
for (l = workspace_manager->all_workspaces; l; l = l->next)
{
MetaWorkspace *workspace = l->data;
@ -230,12 +257,24 @@ meta_workspace_manager_new (MetaDisplay *display)
workspace_manager->display = display;
workspace_manager->active_workspace = NULL;
workspace_manager->all_workspaces = NULL;
workspace_manager->workspaces = NULL;
workspace_manager->rows_of_workspaces = 1;
workspace_manager->columns_of_workspaces = -1;
workspace_manager->vertical_workspaces = FALSE;
workspace_manager->starting_corner = META_DISPLAY_TOPLEFT;
workspace_manager->context_list = NULL;
workspace_manager->active_context = NULL;
workspace_manager->next_context_id = 1;
workspace_manager->mutter_namespace = meta_read_pid_namespace (getpid());
MetaWorkspaceContext *context = meta_workspace_context_new (workspace_manager, NULL);
workspace_manager->workspaces = g_steal_pointer (&context->workspaces);
workspace_manager->active_workspace = g_steal_pointer (&context->active_workspace);
workspace_manager->active_context = context;
/* This is the default layout extracted from default
* variable values in update_num_workspaces ()
* This can be overridden using _NET_DESKTOP_LAYOUT in
@ -246,11 +285,6 @@ meta_workspace_manager_new (MetaDisplay *display)
1,
-1);
/* There must be at least one workspace at all times,
* so create that required workspace.
*/
meta_workspace_new (workspace_manager);
meta_workspace_manager_init_workspaces (workspace_manager);
meta_prefs_add_listener (prefs_changed_callback, workspace_manager);
@ -301,6 +335,9 @@ MetaWorkspace *
meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager,
int idx)
{
if ((idx >> 16) & 0xFFFF) {
return meta_workspace_manager_lookup_workspace_by_id (workspace_manager, idx);
}
return g_list_nth_data (workspace_manager->workspaces, idx);
}
@ -1001,7 +1038,7 @@ meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager)
GList *
meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager)
{
return workspace_manager->workspaces;
return workspace_manager->all_workspaces;
}
int
@ -1015,6 +1052,17 @@ meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspa
return meta_workspace_index (active);
}
int
meta_workspace_manager_get_active_workspace_id (MetaWorkspaceManager *workspace_manager)
{
MetaWorkspace *active = workspace_manager->active_workspace;
if (!active)
return -1;
return meta_workspace_get_id (active);
}
/**
* meta_workspace_manager_get_active_workspace:
* @workspace_manager: A #MetaWorkspaceManager
@ -1033,9 +1081,15 @@ meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manag
int to,
MetaMotionDirection direction)
{
g_signal_emit (workspace_manager,
workspace_manager_signals[WORKSPACE_SWITCHED], 0,
from, to, direction);
if (direction == META_MOTION_CONTEXT_SWITCH) {
g_signal_emit (workspace_manager,
workspace_manager_signals[CONTEXT_SWITCHED],
0, NULL);
} else {
g_signal_emit (workspace_manager,
workspace_manager_signals[WORKSPACE_SWITCHED], 0,
from, to, direction);
}
}
static void
@ -1058,3 +1112,379 @@ prefs_changed_callback (MetaPreference pref,
timestamp, new_num);
}
}
/**
* meta_workspace_manager_set_builtin_struts_all:
* @workspace_manager: a #MetaWorkspaceManager
* @struts: (element-type Meta.Strut) (transfer none): list of #MetaStrut
*
* Sets a list of struts on every workspace that will be used in addition to the struts
* of the windows in the workspace when computing the work area of
* the workspace.
*/
void meta_workspace_manager_set_builtin_struts_all(MetaWorkspaceManager *workspace_manager,
GSList *struts)
{
GList *context_iter = workspace_manager->context_list;
while (context_iter) {
MetaWorkspaceContext *context = context_iter->data;
for (GList *ws_iter = context->workspaces; ws_iter; ws_iter = ws_iter->next) {
MetaWorkspace *workspace = ws_iter->data;
meta_workspace_set_builtin_struts(workspace, struts);
}
context_iter = context_iter->next;
}
}
/**
* meta_workspace_manager_lookup_context:
* @workspace_manager: a #MetaWorkspaceManager
* @context_id: id value of context to look up
*
* Look up WorkspaceContext by id and return it. If no context is found with
* the specified id the return value is %NULL.
*
* Return value: (transfer none) (nullable): the workspace context with the specified id
* or %NULL if no context with matching id exists.
*/
MetaWorkspaceContext *
meta_workspace_manager_lookup_context (MetaWorkspaceManager *workspace_manager, guint context_id)
{
for (GList *iter = workspace_manager->context_list; iter; iter = iter->next) {
MetaWorkspaceContext *context = iter->data;
if (context_id == context->id) {
return context;
}
}
return NULL;
}
const char *
meta_workspace_manager_mutter_namespace (MetaWorkspaceManager *workspace_manager)
{
if (!workspace_manager->mutter_namespace) {
workspace_manager->mutter_namespace = meta_read_pid_namespace (getpid());
}
return workspace_manager->mutter_namespace;
}
/*
* Return pointer to the live workspace list depending on whether or not the context is currently active.
* While a workspace context is active, the list must be accessed through the pointer workspace_manager->workspaces
*/
GList **
meta_workspace_manager_workspace_list_for_context (MetaWorkspaceManager *workspace_manager, guint context_id)
{
if (workspace_manager->active_context && workspace_manager->active_context->id == context_id) {
return &workspace_manager->workspaces;
}
MetaWorkspaceContext *context = meta_workspace_manager_lookup_context (workspace_manager, context_id);
if (context) {
return &context->workspaces;
} else {
g_warning ("MetaWorkspaceManager: Failed to find context workspace list (context_id = %d)", context_id);
return NULL;
}
}
void
meta_workspace_manager_append_context_workspace (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
{
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, workspace->context_id);
if (p_workspaces) {
*p_workspaces = g_list_append (*p_workspaces, workspace);
}
}
void
meta_workspace_manager_remove_context_workspace (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
{
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, workspace->context_id);
if (p_workspaces) {
*p_workspaces = g_list_remove (*p_workspaces, workspace);
}
workspace_manager->all_workspaces = g_list_remove (workspace_manager->all_workspaces, workspace);
}
static int
workspace_index_in_context (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
{
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, workspace->context_id);
if (p_workspaces) {
return g_list_index (*p_workspaces, workspace);
} else {
g_warning ("MetaWorkspaceManager: Could not find context for id=%d in workspace_index_in_context()", workspace->context_id);
return -1;
}
}
int
meta_workspace_manager_get_workspace_id (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
{
int idx = workspace_index_in_context (workspace_manager, workspace);
if (idx >= 0) {
idx |= (int)(workspace->context_id << 16);
} else {
g_warning ("MetaWorkspaceManager: Workspace with context_id = %d not found in meta_workspace_manager_get_workspace_id()", workspace->context_id);
}
return idx;
}
int
meta_workspace_manager_context_workspace_index (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
{
if (!(workspace_manager->active_context && workspace_manager->active_context->id == workspace->context_id)) {
guint active = (workspace_manager->active_context) ? (workspace_manager->active_context->id) : 0;
g_warning ("MetaWorkspaceManager: context_workspace_index() called on workspace not in active context. (ws->context_id = %d, active->context_id=%d)",
workspace->context_id, active);
}
int idx = workspace_index_in_context (workspace_manager, workspace);
if (idx < 0) {
g_warning ("MetaWorkspaceManager: Failed to find workspace with context_id=%d in context_workspace_index()",
workspace->context_id);
}
return idx;
}
MetaWorkspace *
meta_workspace_manager_lookup_workspace_by_id (MetaWorkspaceManager *workspace_manager, int workspace_id)
{
uint context_id = (workspace_id >> 16) & 0xFFFF;
if (context_id) {
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, context_id);
int idx = workspace_id & 0xFFFF;
if (p_workspaces) {
return g_list_nth_data (*p_workspaces, idx);
}
}
return NULL;
}
/**
* meta_workspace_manager_context_for_namespace:
* @workspace_manager: a #MetaWorkspaceManager
* @namespace: namespace of context
*
* Find an existing WorkspaceContext for the specified namespace. If no WorkspaceContext
* currently exists for namespace create a new one.
*
* Return value: (transfer none): the workspace context for the specified namespace
*/
MetaWorkspaceContext *
meta_workspace_manager_context_for_namespace (MetaWorkspaceManager *workspace_manager, const gchar *namespace)
{
MetaWorkspaceContext *anonymous_context = NULL;
for (GList *iter = workspace_manager->context_list; iter; iter = iter->next) {
MetaWorkspaceContext *context = iter->data;
if (context->namespace == NULL && anonymous_context == NULL) {
anonymous_context = context;
} else if (!g_strcmp0 (context->namespace, namespace )) {
return context;
}
}
if (anonymous_context) {
anonymous_context->namespace = g_strdup (namespace);
return anonymous_context;
}
return meta_workspace_context_new (workspace_manager, namespace);
}
guint
meta_workspace_manager_active_context_id (MetaWorkspaceManager *workspace_manager)
{
if (workspace_manager->active_context) {
return workspace_manager->active_context->id;
} else {
return 0;
}
}
G_DEFINE_TYPE (MetaWorkspaceContext, meta_workspace_context, G_TYPE_OBJECT)
guint
meta_workspace_context_id (MetaWorkspaceContext *context)
{
return context->id;
}
void
meta_workspace_context_remove (MetaWorkspaceContext *context)
{
if (meta_workspace_context_is_current (context)) {
g_warning ("MetaWorkspaceManager: attempt to remove active context ignored");
return;
}
for (GList *iter = context->workspaces; iter; iter = iter->next) {
MetaWorkspace *workspace = iter->data;
meta_workspace_relocate_windows (workspace, context->manager->active_workspace);
}
context->active_workspace = NULL;
g_list_free_full (g_steal_pointer(&context->workspaces), (GDestroyNotify) meta_workspace_remove);
g_signal_emit (context->manager, workspace_manager_signals[CONTEXT_REMOVED],
0, context->id);
g_clear_pointer (&context->namespace, g_free);
context->manager->context_list = g_list_remove (context->manager->context_list, context);
g_object_unref (context);
}
static void
meta_workspace_context_class_init (MetaWorkspaceContextClass *klass)
{
}
static void
meta_workspace_context_init (MetaWorkspaceContext *context)
{
}
MetaWorkspaceContext *
meta_workspace_context_new (MetaWorkspaceManager *manager, const char *namespace)
{
guint context_id = manager->next_context_id++;
MetaWorkspaceContext *context = g_object_new (META_TYPE_WORKSPACE_CONTEXT, NULL);
context->manager = manager;
context->workspaces = NULL;
context->active_workspace = NULL;
context->namespace = NULL;
context->id = context_id;
if (namespace) {
context->namespace = g_strdup (namespace);
}
manager->context_list = g_list_append (manager->context_list, context);
context->active_workspace = meta_workspace_new_with_context_id (manager, context_id);
g_object_notify (G_OBJECT (manager), "n-workspaces");
return context;
}
/*
* Synchronize the state stored in the MetaWorkspaceManager to 'context'
* by copying the relevant fields to the WorkspaceContext structure.
*
* The state which is saved is the list of workspaces and the active
* workspace pointer:
*
* workspace_manager->active_workspace
* workspace_manager->workspaces
*/
static void
workspace_context_sync_manager_state (MetaWorkspaceContext *context)
{
context->active_workspace = context->manager->active_workspace;
context->workspaces = context->manager->workspaces;
}
gboolean
meta_workspace_context_is_current (MetaWorkspaceContext *context)
{
return context && context->manager->active_context == context;
}
/**
* meta_workspace_context_get_active_workspace:
* @context: A #MetaWorkspaceContext
*
* Returns: (transfer none): The current workspace for this context
*/
MetaWorkspace *
meta_workspace_context_get_active_workspace (MetaWorkspaceContext *context)
{
if (meta_workspace_context_is_current (context)) {
return context->manager->active_workspace;
} else {
return context->active_workspace;
}
}
void
meta_workspace_context_move_window_to_context (MetaWorkspaceContext *context, MetaWindow *window)
{
if (!context->active_workspace) {
g_warning ("MetaWorkspaceContext: Cannot move window to context (%d) because no workspace is active", context->id);
return;
}
if (window->workspace->context_id != context->id) {
meta_window_change_workspace (window, context->active_workspace);
g_signal_emit (context->manager, workspace_manager_signals[CONTEXT_WINDOW_MOVED], 0, window);
}
}
void
meta_workspace_context_make_active (MetaWorkspaceContext *context) {
MetaWorkspaceManager *manager = context->manager;
workspace_context_sync_manager_state (manager->active_context);
manager->active_context = context;
/*
* Do not update manager->active_workspace because meta_workspace_activate() expects
* old value
*/
/* steal pointer to avoid writing code elsewhere that changes this list while context is active */
manager->workspaces = g_steal_pointer (&context->workspaces);
}
/*
* Activate a WorkspaceContext instance by copying the context state fields
* into the MetaWorkspaceManager structure.
*
* If 'context' is already the current WorkspaceContext do nothing.
*
* If some other context is active, save the context fields by calling
*
* workspace_context_sync_manager_state()
*/
void
meta_workspace_context_activate (MetaWorkspaceContext *context)
{
if (meta_workspace_context_is_current (context)) {
return;
}
meta_workspace_context_make_active (context);
guint32 timestamp;
timestamp = meta_display_get_current_time_roundtrip (context->manager->display);
/* Will set manager->active_workspace from context->active_workspace */
meta_workspace_activate ( g_steal_pointer (&context->active_workspace), timestamp);
}
gboolean
meta_workspace_manager_is_window_on_foreign_context (MetaWorkspaceManager *workspace_manager, MetaWindow *window)
{
const char *ns = meta_window_namespace (window);
if (!ns || !g_strcmp0 (ns, workspace_manager->mutter_namespace) || !window->workspace) {
return FALSE;
}
MetaWorkspaceContext *context = meta_workspace_manager_context_for_namespace (workspace_manager, ns);
return context->id != window->workspace->context_id;
}

View File

@ -58,4 +58,6 @@ void meta_get_clutter_debug_flags (ClutterDebugFlag *debug_flags,
ClutterDrawDebugFlag *draw_flags,
ClutterPickDebugFlag *pick_flags);
char * meta_read_pid_namespace (pid_t pid);
#endif

View File

@ -794,3 +794,51 @@ meta_get_debug_paint_flags (void)
{
return debug_paint_flags;
}
static GFileInfo *
pid_namespace_file_info (pid_t pid)
{
char *filename = g_strdup_printf("/proc/%u/ns/pid", pid);
GFile *file = g_file_new_for_path(filename);
g_free(filename);
GError *error = NULL;
GFileInfo *info = g_file_query_info(file,
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL,
&error);
g_object_unref(file);
if (info == NULL) {
g_warning("MetaWindow: Error attempting to read /proc/%u/ns/pid symlink: %s", pid, error->message);
g_error_free (error);
return NULL;
}
if (!g_file_info_get_is_symlink (info)) {
g_warning("MetaWindow: /proc/%u/ns/pid exists but is not a symlink?", pid);
g_object_unref (info);
return NULL;
}
return info;
}
char *
meta_read_pid_namespace (pid_t pid)
{
char *value = NULL;
GFileInfo *info = pid_namespace_file_info (pid);
const char *target = g_file_info_get_symlink_target (info);
if (target) {
value = g_strdup (target);
}
g_object_unref (info);
return value;
}

View File

@ -568,6 +568,9 @@ struct _MetaWindow
gboolean has_valid_cgroup;
GFile *cgroup_path;
guint namespace_set: 1;
gchar *namespace;
};
struct _MetaWindowClass

View File

@ -356,6 +356,7 @@ meta_window_finalize (GObject *object)
g_free (window->gtk_app_menu_object_path);
g_free (window->gtk_menubar_object_path);
g_free (window->placement.rule);
g_free (window->namespace);
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
}
@ -1578,7 +1579,7 @@ meta_window_unmanage (MetaWindow *window,
g_assert (window->workspace == NULL);
#ifndef G_DISABLE_CHECKS
tmp = workspace_manager->workspaces;
tmp = workspace_manager->all_workspaces;
while (tmp != NULL)
{
MetaWorkspace *workspace = tmp->data;
@ -4903,7 +4904,7 @@ set_workspace_state (MetaWindow *window,
else if (window->on_all_workspaces)
{
GList *l;
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
for (l = workspace_manager->all_workspaces; l != NULL; l = l->next)
{
MetaWorkspace *ws = l->data;
meta_workspace_remove_window (ws, window);
@ -4918,7 +4919,7 @@ set_workspace_state (MetaWindow *window,
else if (window->on_all_workspaces)
{
GList *l;
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
for (l = workspace_manager->all_workspaces; l != NULL; l = l->next)
{
MetaWorkspace *ws = l->data;
meta_workspace_add_window (ws, window);
@ -5279,8 +5280,10 @@ meta_window_change_workspace_by_index (MetaWindow *window,
workspace =
meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index);
if (!workspace && append)
if (!workspace && append) {
workspace = meta_workspace_manager_append_new_workspace (workspace_manager, FALSE, META_CURRENT_TIME);
}
if (workspace)
meta_window_change_workspace (window, workspace);
@ -5621,7 +5624,7 @@ meta_window_get_workspaces (MetaWindow *window)
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
if (window->on_all_workspaces)
return workspace_manager->workspaces;
return workspace_manager->all_workspaces;
else if (window->workspace != NULL)
return window->workspace->list_containing_self;
else if (window->constructing)
@ -8825,3 +8828,31 @@ meta_window_get_client_type (MetaWindow *window)
{
return window->client_type;
}
/**
* meta_window_namespace:
* @window: a #MetaWindow
*
* Returns string identifying PID namespace this window belongs to
* if known
*
* Return value: (transfer none): the pid namespace string, or %NULL
*/
const char *
meta_window_namespace (MetaWindow *window)
{
if (!window->namespace_set) {
window->namespace_set = TRUE;
pid_t pid = meta_window_get_pid (window);
if (pid) {
window->namespace = meta_read_pid_namespace (pid);
}
}
return window->namespace;
}
gboolean
meta_window_is_on_foreign_workspace_context (MetaWindow *window)
{
return meta_workspace_manager_is_window_on_foreign_context (window->display->workspace_manager, window);
}

View File

@ -39,6 +39,7 @@ struct _MetaWorkspace
GObject parent_instance;
MetaDisplay *display;
MetaWorkspaceManager *manager;
guint context_id;
GList *windows;
@ -74,6 +75,8 @@ struct _MetaWorkspaceClass
};
MetaWorkspace* meta_workspace_new (MetaWorkspaceManager *workspace_manager);
MetaWorkspace* meta_workspace_new_with_context_id (MetaWorkspaceManager *workspace_manager,
guint context_id);
void meta_workspace_remove (MetaWorkspace *workspace);
void meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window);

View File

@ -237,7 +237,7 @@ meta_workspace_init (MetaWorkspace *workspace)
}
MetaWorkspace *
meta_workspace_new (MetaWorkspaceManager *workspace_manager)
meta_workspace_new_with_context_id (MetaWorkspaceManager *workspace_manager, guint context_id)
{
MetaDisplay *display = workspace_manager->display;
MetaWorkspace *workspace;
@ -247,9 +247,11 @@ meta_workspace_new (MetaWorkspaceManager *workspace_manager)
workspace->display = display;
workspace->manager = workspace_manager;
workspace->context_id = context_id;
workspace_manager->all_workspaces =
g_list_append (workspace_manager->all_workspaces, workspace);
workspace_manager->workspaces =
g_list_append (workspace_manager->workspaces, workspace);
workspace->windows = NULL;
workspace->mru_list = NULL;
@ -276,9 +278,17 @@ meta_workspace_new (MetaWorkspaceManager *workspace_manager)
meta_workspace_add_window (workspace, l->data);
g_slist_free (windows);
meta_workspace_manager_append_context_workspace (workspace_manager, workspace);
return workspace;
}
MetaWorkspace *
meta_workspace_new (MetaWorkspaceManager *workspace_manager)
{
return meta_workspace_new_with_context_id (workspace_manager, workspace_manager->active_context->id);
}
/**
* workspace_free_all_struts:
* @workspace: The workspace.
@ -333,8 +343,7 @@ meta_workspace_remove (MetaWorkspace *workspace)
assert_workspace_empty (workspace);
manager->workspaces =
g_list_remove (manager->workspaces, workspace);
meta_workspace_manager_remove_context_workspace (manager, workspace);
meta_workspace_clear_logical_monitor_data (workspace);
@ -403,8 +412,8 @@ meta_workspace_add_window (MetaWorkspace *workspace,
if (window->struts)
{
meta_topic (META_DEBUG_WORKAREA,
"Invalidating work area of workspace %d since we're adding window %s to it",
meta_workspace_index (workspace), window->desc);
"Invalidating work area of workspace %08x since we're adding window %s to it",
meta_workspace_get_id (workspace), window->desc);
meta_workspace_invalidate_work_area (workspace);
}
@ -432,8 +441,8 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
if (window->struts)
{
meta_topic (META_DEBUG_WORKAREA,
"Invalidating work area of workspace %d since we're removing window %s from it",
meta_workspace_index (workspace), window->desc);
"Invalidating work area of workspace %08x since we're removing window %s from it",
meta_workspace_get_id (workspace), window->desc);
meta_workspace_invalidate_work_area (workspace);
}
@ -486,6 +495,11 @@ workspace_switch_sound(MetaWorkspace *from,
int i, nw, x, y, fi, ti;
const char *e;
if (from->context_id != to->context_id) {
/* XXX: There is no sound for context switches, but there should be (?) */
return;
}
nw = meta_workspace_manager_get_n_workspaces (from->manager);
fi = meta_workspace_index(from);
ti = meta_workspace_index(to);
@ -566,9 +580,15 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction;
MetaWorkspaceContext *context;
meta_verbose ("Activating workspace %d",
meta_workspace_index (workspace));
meta_verbose ("Activating workspace %08x",
meta_workspace_get_id (workspace));
context = meta_workspace_manager_lookup_context (workspace->manager, workspace->context_id);
if(context && !meta_workspace_context_is_current (context)) {
meta_workspace_context_make_active (context);
}
if (workspace->manager->active_workspace == workspace)
{
@ -631,52 +651,59 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
comp = meta_display_get_compositor (workspace->display);
direction = 0;
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager);
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
current_space, &layout1);
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
if (workspace->context_id != old->context_id) {
direction = META_MOTION_CONTEXT_SWITCH;
current_space = meta_workspace_get_id (old);
new_space = meta_workspace_get_id (workspace);
} else {
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager);
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
current_space, &layout1);
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
new_space, &layout2);
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
{
if (layout1.current_col > layout2.current_col)
direction = META_MOTION_RIGHT;
else if (layout1.current_col < layout2.current_col)
direction = META_MOTION_LEFT;
}
else
{
if (layout1.current_col < layout2.current_col)
direction = META_MOTION_RIGHT;
else if (layout1.current_col > layout2.current_col)
direction = META_MOTION_LEFT;
}
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
{
if (layout1.current_col > layout2.current_col)
direction = META_MOTION_RIGHT;
else if (layout1.current_col < layout2.current_col)
direction = META_MOTION_LEFT;
}
else
{
if (layout1.current_col < layout2.current_col)
direction = META_MOTION_RIGHT;
else if (layout1.current_col > layout2.current_col)
direction = META_MOTION_LEFT;
}
if (layout1.current_row < layout2.current_row)
{
if (!direction)
direction = META_MOTION_DOWN;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_DOWN_RIGHT;
else
direction = META_MOTION_DOWN_LEFT;
}
if (layout1.current_row < layout2.current_row)
{
if (!direction)
direction = META_MOTION_DOWN;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_DOWN_RIGHT;
else
direction = META_MOTION_DOWN_LEFT;
}
if (layout1.current_row > layout2.current_row)
{
if (!direction)
direction = META_MOTION_UP;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_UP_RIGHT;
else
direction = META_MOTION_UP_LEFT;
}
if (layout1.current_row > layout2.current_row)
{
if (!direction)
direction = META_MOTION_UP;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_UP_RIGHT;
else
direction = META_MOTION_UP_LEFT;
}
meta_workspace_manager_free_workspace_layout (&layout1);
meta_workspace_manager_free_workspace_layout (&layout2);
meta_workspace_manager_free_workspace_layout (&layout1);
meta_workspace_manager_free_workspace_layout (&layout2);
}
meta_compositor_switch_workspace (comp, old, workspace, direction);
@ -714,14 +741,19 @@ meta_workspace_activate (MetaWorkspace *workspace,
int
meta_workspace_index (MetaWorkspace *workspace)
{
int ret;
return meta_workspace_manager_context_workspace_index (workspace->manager, workspace);
}
ret = g_list_index (workspace->manager->workspaces, workspace);
int
meta_workspace_get_id (MetaWorkspace *workspace)
{
return meta_workspace_manager_get_workspace_id (workspace->manager, workspace);
}
if (ret < 0)
meta_bug ("Workspace does not exist to index!");
return ret;
guint
meta_workspace_get_context_id (MetaWorkspace *workspace)
{
return workspace->context_id;
}
void
@ -778,14 +810,14 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
if (workspace->work_areas_invalid)
{
meta_topic (META_DEBUG_WORKAREA,
"Work area for workspace %d is already invalid",
meta_workspace_index (workspace));
"Work area for workspace %08x is already invalid",
meta_workspace_get_id (workspace));
return;
}
meta_topic (META_DEBUG_WORKAREA,
"Invalidating work area for workspace %d",
meta_workspace_index (workspace));
"Invalidating work area for workspace %08x",
meta_workspace_get_id (workspace));
/* If we are in the middle of a resize or move operation, we
* might have cached pointers to the workspace's edges */
@ -956,8 +988,8 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
}
workspace->work_area_screen = work_area;
meta_topic (META_DEBUG_WORKAREA,
"Computed work area for workspace %d: %d,%d %d x %d",
meta_workspace_index (workspace),
"Computed work area for workspace %08x: %d,%d %d x %d",
meta_workspace_get_id (workspace),
workspace->work_area_screen.x,
workspace->work_area_screen.y,
workspace->work_area_screen.width,
@ -987,8 +1019,8 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
meta_topic (META_DEBUG_WORKAREA,
"Computed work area for workspace %d "
"monitor %d: %d,%d %d x %d",
meta_workspace_index (workspace),
"monitor %08x: %d,%d %d x %d",
meta_workspace_get_id (workspace),
logical_monitor->number,
data->logical_monitor_work_area.x,
data->logical_monitor_work_area.y,
@ -1230,6 +1262,8 @@ meta_motion_direction_to_string (MetaMotionDirection direction)
return "Up-Left";
case META_MOTION_DOWN_LEFT:
return "Down-Left";
case META_MOTION_CONTEXT_SWITCH:
return "Switch-Context";
}
return "Unknown";

View File

@ -1013,6 +1013,7 @@ libmutter = shared_library(libmutter_name,
libmutter_dep = declare_dependency(
link_with: libmutter,
include_directories: mutter_includes,
sources: mutter_built_sources,
dependencies: [
libmutter_cogl_dep,
libmutter_clutter_dep,

View File

@ -328,6 +328,7 @@ typedef enum
* @META_MOTION_UP_RIGHT: Motion up and to the right
* @META_MOTION_DOWN_LEFT: Motion down and to the left
* @META_MOTION_DOWN_RIGHT: Motion down and to the right
* @META_MOTION_REALM_SWITCH: Workspace switch is a change of current realm
*/
/* Negative to avoid conflicting with real workspace
@ -343,7 +344,8 @@ typedef enum
META_MOTION_UP_LEFT = -5,
META_MOTION_UP_RIGHT = -6,
META_MOTION_DOWN_LEFT = -7,
META_MOTION_DOWN_RIGHT = -8
META_MOTION_DOWN_RIGHT = -8,
META_MOTION_CONTEXT_SWITCH = -9
} MetaMotionDirection;
/**

View File

@ -30,6 +30,14 @@
#include <meta/prefs.h>
#include <meta/types.h>
#define META_TYPE_WORKSPACE_CONTEXT (meta_workspace_context_get_type ())
META_EXPORT
G_DECLARE_FINAL_TYPE (MetaWorkspaceContext,
meta_workspace_context,
META, WORKSPACE_CONTEXT,
GObject)
#define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ())
META_EXPORT
@ -66,6 +74,9 @@ void meta_workspace_manager_reorder_workspace (MetaWorkspaceManager *workspace_m
META_EXPORT
int meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager);
META_EXPORT
int meta_workspace_manager_get_active_workspace_id (MetaWorkspaceManager *workspace_manager);
META_EXPORT
MetaWorkspace *meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager);
@ -75,4 +86,37 @@ void meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *wor
gboolean vertical_layout,
int n_rows,
int n_columns);
META_EXPORT
guint meta_workspace_manager_active_context_id (MetaWorkspaceManager *workspace_manager);
META_EXPORT
void meta_workspace_manager_set_builtin_struts_all(MetaWorkspaceManager *workspace_manager,
GSList *struts);
META_EXPORT
MetaWorkspaceContext *meta_workspace_manager_context_for_namespace (MetaWorkspaceManager *workspace_manager,
const gchar *namespace);
META_EXPORT
const char *meta_workspace_manager_mutter_namespace (MetaWorkspaceManager *workspace_manager);
META_EXPORT
void meta_workspace_context_activate (MetaWorkspaceContext *context);
META_EXPORT
void meta_workspace_context_remove (MetaWorkspaceContext *context);
META_EXPORT
gboolean meta_workspace_context_is_current (MetaWorkspaceContext *context);
META_EXPORT
MetaWorkspace *
meta_workspace_context_get_active_workspace (MetaWorkspaceContext *context);
META_EXPORT
guint meta_workspace_context_id (MetaWorkspaceContext *context);
META_EXPORT
void meta_workspace_context_move_window_to_context (MetaWorkspaceContext *context, MetaWindow *window);
#endif /* META_WORKSPACE_MANAGER_H */

View File

@ -43,6 +43,7 @@ typedef struct _MetaCursorTracker MetaCursorTracker;
typedef struct _MetaDnd MetaDnd;
typedef struct _MetaSettings MetaSettings;
typedef struct _MetaWorkspaceContext MetaWorkspaceContext;
typedef struct _MetaWorkspaceManager MetaWorkspaceManager;
typedef struct _MetaSelection MetaSelection;

View File

@ -450,4 +450,10 @@ uint64_t meta_window_get_id (MetaWindow *window);
META_EXPORT
MetaWindowClientType meta_window_get_client_type (MetaWindow *window);
META_EXPORT
const char *meta_window_namespace (MetaWindow *window);
META_EXPORT
gboolean meta_window_is_on_foreign_workspace_context (MetaWindow *window);
#endif

View File

@ -39,6 +39,12 @@ GType meta_workspace_get_type (void);
META_EXPORT
int meta_workspace_index (MetaWorkspace *workspace);
META_EXPORT
int meta_workspace_get_id (MetaWorkspace *workspace);
META_EXPORT
guint meta_workspace_get_context_id (MetaWorkspace *workspace);
META_EXPORT
MetaDisplay *meta_workspace_get_display (MetaWorkspace *workspace);

View File

@ -276,7 +276,9 @@ data_offer_choose_action (MetaWaylandDataOffer *offer)
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
/* If the user is forcing an action, go for it */
if ((user_action & available_actions) != 0)
if ((user_action & available_actions) != 0 &&
!(user_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK &&
meta_wayland_data_source_get_drop_performed (source)))
return user_action;
/* If the dest side has a preferred DnD action, use it */

View File

@ -702,8 +702,8 @@ broadcast_tilt (MetaWaylandTabletTool *tool,
struct wl_resource *resource;
gdouble xtilt, ytilt;
xtilt = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_XTILT];
ytilt = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_YTILT];
xtilt = event->motion.axes[CLUTTER_INPUT_AXIS_XTILT];
ytilt = event->motion.axes[CLUTTER_INPUT_AXIS_YTILT];
wl_resource_for_each (resource, &tool->focus_resource_list)
{
@ -720,7 +720,7 @@ broadcast_rotation (MetaWaylandTabletTool *tool,
struct wl_resource *resource;
gdouble rotation;
rotation = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_ROTATION];
rotation = event->motion.axes[CLUTTER_INPUT_AXIS_ROTATION];
wl_resource_for_each (resource, &tool->focus_resource_list)
{
@ -737,7 +737,7 @@ broadcast_wheel (MetaWaylandTabletTool *tool,
gdouble angle;
gint32 clicks = 0;
angle = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_WHEEL];
angle = event->motion.axes[CLUTTER_INPUT_AXIS_WHEEL];
/* FIXME: Perform proper angle-to-clicks accumulation elsewhere */
if (angle > 0.01)