Compare commits
212 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c215247a6c | ||
![]() |
96b202c80d | ||
![]() |
0ac2f61a2c | ||
![]() |
2aa6dcd9d8 | ||
![]() |
469b85eb7c | ||
![]() |
673ddfde04 | ||
![]() |
56ca7eeb65 | ||
![]() |
b414955230 | ||
![]() |
af9072e725 | ||
![]() |
9b903e93e3 | ||
![]() |
7966f00a18 | ||
![]() |
9a99a80710 | ||
![]() |
be77874ec9 | ||
![]() |
768286bffb | ||
![]() |
f5c65d9ea1 | ||
![]() |
f328890ed1 | ||
![]() |
945bf626c6 | ||
![]() |
f6869bbbc2 | ||
![]() |
eafe11a7cf | ||
![]() |
daba1b511b | ||
![]() |
87a13d2c00 | ||
![]() |
11a9b4baa0 | ||
![]() |
de71fd0941 | ||
![]() |
87c973c260 | ||
![]() |
644ab0e270 | ||
![]() |
3142220443 | ||
![]() |
1f0ed5483a | ||
![]() |
72f5a36522 | ||
![]() |
7f19db1f7b | ||
![]() |
3f2d658f20 | ||
![]() |
05353c1f7e | ||
![]() |
4d23e7c202 | ||
![]() |
ad90b7dd2f | ||
![]() |
3356a43c04 | ||
![]() |
3a5a647d49 | ||
![]() |
a2ff8f4e1e | ||
![]() |
e294f6df8c | ||
![]() |
422ddeddb9 | ||
![]() |
8ef48a99ae | ||
![]() |
9d7af8a5fc | ||
![]() |
764c3dd137 | ||
![]() |
7e7c8ecbd4 | ||
![]() |
d561b3b18f | ||
![]() |
ce14bde08d | ||
![]() |
b91461ee39 | ||
![]() |
22c13b3144 | ||
![]() |
0bfebc3cae | ||
![]() |
db384a656c | ||
![]() |
1dea1813b1 | ||
![]() |
71c4138933 | ||
![]() |
9d73b4efbb | ||
![]() |
049f67df0a | ||
![]() |
2d878d3f55 | ||
![]() |
3c06f2dc90 | ||
![]() |
460e1fd7ca | ||
![]() |
f083935c6e | ||
![]() |
5c66bee84b | ||
![]() |
ef32bbdc99 | ||
![]() |
5f91a62f6f | ||
![]() |
152b2dab59 | ||
![]() |
625d3de2ee | ||
![]() |
f71315eb1e | ||
![]() |
0484ef142d | ||
![]() |
6609d9c6a4 | ||
![]() |
73c4342580 | ||
![]() |
0d5c24f13d | ||
![]() |
b6d070b06f | ||
![]() |
87eb5f8632 | ||
![]() |
5c60ea6635 | ||
![]() |
9abcf424b8 | ||
![]() |
cc7af83f8a | ||
![]() |
ae91a174e9 | ||
![]() |
9c73e21113 | ||
![]() |
a1d8110221 | ||
![]() |
9d6357f05a | ||
![]() |
1fc58faff9 | ||
![]() |
fea7ac84ee | ||
![]() |
20bee6f48e | ||
![]() |
fb5c0c3352 | ||
![]() |
5bc2bcd109 | ||
![]() |
d12390002a | ||
![]() |
13acf9e35d | ||
![]() |
3beb187cac | ||
![]() |
a3b8dcbd04 | ||
![]() |
3ff8b0051d | ||
![]() |
a8bf7934fb | ||
![]() |
7159845c6e | ||
![]() |
7bccd4f22f | ||
![]() |
e4e00b383e | ||
![]() |
36454542ae | ||
![]() |
34ba868b4c | ||
![]() |
274ea76eea | ||
![]() |
a180e8b87e | ||
![]() |
26c8086190 | ||
![]() |
34fbca0181 | ||
![]() |
4496fb4447 | ||
![]() |
7e66d2a484 | ||
![]() |
12135afa5e | ||
![]() |
cac660a5bc | ||
![]() |
dcce4e64bc | ||
![]() |
4d3511649b | ||
![]() |
d4ea2bbd9c | ||
![]() |
f303ec2eaa | ||
![]() |
2ca4ed6b04 | ||
![]() |
a5ad89dd65 | ||
![]() |
4a4d724e59 | ||
![]() |
8fdbae192a | ||
![]() |
2413e672c8 | ||
![]() |
c8432cc430 | ||
![]() |
015864da09 | ||
![]() |
669c9da2a4 | ||
![]() |
4d1d8e831e | ||
![]() |
9e199e6350 | ||
![]() |
4673d8f245 | ||
![]() |
90111c03a1 | ||
![]() |
23681800d9 | ||
![]() |
b47afe89d3 | ||
![]() |
af7f51b992 | ||
![]() |
f3d30d897f | ||
![]() |
dcc4ce4ff4 | ||
![]() |
b9fb4a5887 | ||
![]() |
d9985cd9bc | ||
![]() |
6e3f7b7ddc | ||
![]() |
2dd1f37820 | ||
![]() |
57af975154 | ||
![]() |
c5940580ed | ||
![]() |
8296d4cdce | ||
![]() |
bf9a00d5c9 | ||
![]() |
c1db9d9181 | ||
![]() |
9d2cd8ff87 | ||
![]() |
d514e8ab41 | ||
![]() |
44a60eb7e9 | ||
![]() |
6b92b45021 | ||
![]() |
ee461b5495 | ||
![]() |
46f3eb0b71 | ||
![]() |
ef32899b4d | ||
![]() |
5e9db422c9 | ||
![]() |
662dd6a289 | ||
![]() |
d5e6177900 | ||
![]() |
34ac80348c | ||
![]() |
8a7a01b0cf | ||
![]() |
2cabc067d1 | ||
![]() |
26c4c21e13 | ||
![]() |
6eda784cf0 | ||
![]() |
fb1459062f | ||
![]() |
bc9547f29e | ||
![]() |
89a371ec98 | ||
![]() |
2db71e73b4 | ||
![]() |
472f2a4b8e | ||
![]() |
db04ac9eb7 | ||
![]() |
75105e254f | ||
![]() |
901a05ad80 | ||
![]() |
ab6c4c82f6 | ||
![]() |
cacb32482c | ||
![]() |
4450b5bb14 | ||
![]() |
34421e90c3 | ||
![]() |
93b7137c62 | ||
![]() |
5ad15bb5e5 | ||
![]() |
cd4206764e | ||
![]() |
b10a017446 | ||
![]() |
d393cba39e | ||
![]() |
578f593d56 | ||
![]() |
55df99447a | ||
![]() |
d45080d32e | ||
![]() |
fa97364fa8 | ||
![]() |
41303101e5 | ||
![]() |
68542ae1ef | ||
![]() |
0c730d8feb | ||
![]() |
aeef98fd19 | ||
![]() |
69079b3b48 | ||
![]() |
ad7292faef | ||
![]() |
2f7843b295 | ||
![]() |
b24cd5ae08 | ||
![]() |
c782078e00 | ||
![]() |
5a86286aba | ||
![]() |
b1ac83d3b6 | ||
![]() |
e73f5cc8ab | ||
![]() |
593b417e5e | ||
![]() |
5e84c8f20b | ||
![]() |
9745f9f8ce | ||
![]() |
99f7be33ad | ||
![]() |
6492845f27 | ||
![]() |
fd1243d881 | ||
![]() |
00535b34b6 | ||
![]() |
a2b2a7a26f | ||
![]() |
9fdf487da1 | ||
![]() |
c5033616e9 | ||
![]() |
a0e038f34b | ||
![]() |
71dab32769 | ||
![]() |
c408cf7aac | ||
![]() |
e96eb0e82e | ||
![]() |
0015963457 | ||
![]() |
b832bc7424 | ||
![]() |
89b14babb9 | ||
![]() |
7ecde19aee | ||
![]() |
d7854794cf | ||
![]() |
f6f5f624d4 | ||
![]() |
7012c82fc7 | ||
![]() |
a0d2d207e7 | ||
![]() |
6e25c37da1 | ||
![]() |
061f434201 | ||
![]() |
638087fe78 | ||
![]() |
286a6ada5a | ||
![]() |
cb66ab5a87 | ||
![]() |
e72c6916aa | ||
![]() |
8b98cb818c | ||
![]() |
f8a4d450a5 | ||
![]() |
681cf95236 | ||
![]() |
90d6734f8c | ||
![]() |
213cd8a334 | ||
![]() |
3b1271d9be | ||
![]() |
13b6bd20ca |
63
NEWS
63
NEWS
@@ -1,3 +1,66 @@
|
||||
3.15.90
|
||||
=======
|
||||
* Initialize MetaOutput even when we can't get the EDID [Rui; #743412]
|
||||
* Expose MetaMonitorManager to introspection [Rui; #743745]
|
||||
* Fix flash on unredirection [Chris; #743858]
|
||||
* Update xdg-shell implementation to v5 [Jonas; #744452]
|
||||
* Do not try to use seat devices that aren't (yet) present [Ray; #744640]
|
||||
* Add keybindings for switching to VT8-VT12 [Ray; #744800]
|
||||
* Misc bug fixes [Jonas, Cosimo; #743678, #744500]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Jasper St. Pierre,
|
||||
Ray Strode, Chris Wilson
|
||||
|
||||
Translations:
|
||||
Yosef Or Boczko [he], Yuri Myasoedov [ru], Kristjan SCHMIDT [eo],
|
||||
Matej Urbančič [sl], Dušan Kazik [sk]
|
||||
|
||||
3.15.4
|
||||
======
|
||||
* Use GTK+ theme for window decorations instead of metacity [Florian; #741917]
|
||||
* Export the same EDID information on X11 and wayland [Carlos; #742882]
|
||||
* Apply input device configuration on wayland [Carlos; #739397]
|
||||
* Implement pointer barriers on wayland [Jonas; #706655]
|
||||
* Misc. bug fixes (Ting-Wei, Rui, Ikey, Florian, Marek, Jonas; #741829,
|
||||
#738630, #737463, #698995, #727893, #742825, #742824, #742841, #743173,
|
||||
#743189, #743217, #743254]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Giovanni Campagna, Marek Chalupa, Ikey Doherty, Adel Gadllah,
|
||||
Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Jasper St. Pierre,
|
||||
Rico Tzschichholz
|
||||
|
||||
Translations:
|
||||
Matej Urbančič [sl], Balázs Úr [hu], Marek Černocký [cs],
|
||||
Inaki Larranaga Murgoitio [eu], Rafael Ferreira [pt_BR],
|
||||
Daniel Mustieles [es], Fran Dieguez [gl]
|
||||
|
||||
3.15.3
|
||||
======
|
||||
* Don't leave left-over frames queued [Owen; #738686]
|
||||
* Set CRTC configuration even if it might be redundant [Rui; #740838]
|
||||
|
||||
Contributors:
|
||||
Rui Matos, Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Trần Ngọc Quân [vi], Muhammet Kara [tr]
|
||||
|
||||
3.15.2
|
||||
======
|
||||
* Don't enable hiDPI on monitors with broken EDID [Bastien; #734839]
|
||||
* Prevent crash applying monitor config for a closed lid [Rui; #739450]
|
||||
* Fix "flicker" during startup transition [Ray; #740377]
|
||||
* Misc. bug fixes [Lan, Florian, Carlos; #731521, #740133, #738890]
|
||||
|
||||
Contributors:
|
||||
Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos,
|
||||
Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode
|
||||
|
||||
Translations:
|
||||
Kjartan Maraas [nb]
|
||||
|
||||
3.15.1
|
||||
======
|
||||
* Use GResources for theme loading [Cosimo; #736936]
|
||||
|
55
configure.ac
55
configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [15])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -72,11 +72,11 @@ CLUTTER_PACKAGE=clutter-1.0
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gtk+-3.0 >= 3.9.11
|
||||
gio-unix-2.0 >= 2.25.10
|
||||
gio-unix-2.0 >= 2.35.1
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
$CLUTTER_PACKAGE >= 1.19.5
|
||||
gsettings-desktop-schemas >= 3.15.4
|
||||
$CLUTTER_PACKAGE >= 1.21.3
|
||||
cogl-1.0 >= 1.17.1
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
@@ -200,22 +200,39 @@ AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [clutter-egl-1.0 libdrm libsystemd libinput gudev-1.0 gbm >= 10.3], [have_native_backend=yes], [have_native_backend=no])
|
||||
if test $have_native_backend = yes; then
|
||||
AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes])
|
||||
MUTTER_NATIVE_BACKEND_MODULES="clutter-egl-1.0 libdrm libsystemd libinput gudev-1.0 gbm >= 10.3"
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_WAYLAND, [clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.5.90], [have_wayland=yes], [have_wayland=no])
|
||||
if test $have_wayland = yes; then
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test $WAYLAND_SCANNER = "no"],
|
||||
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_ARG_ENABLE(native-backend,
|
||||
AS_HELP_STRING([--disable-native-backend], [disable mutter native (KMS) backend]),,
|
||||
enable_native_backend=auto
|
||||
)
|
||||
AS_IF([test "$enable_native_backend" = "yes"], [have_native_backend=yes],
|
||||
[test "$enable_native_backend" = "auto"], PKG_CHECK_EXISTS([$MUTTER_NATIVE_BACKEND_MODULES], [have_native_backend=yes]))
|
||||
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test $have_wayland = yes])
|
||||
AS_IF([test "$have_native_backend" = "yes"], [
|
||||
PKG_CHECK_MODULES([MUTTER_NATIVE_BACKEND], [$MUTTER_NATIVE_BACKEND_MODULES])
|
||||
AC_DEFINE([HAVE_NATIVE_BACKEND],[1], [Define if you want to enable the native (KMS) backend based on systemd])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"])
|
||||
|
||||
MUTTER_WAYLAND_MODULES="clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.6.90"
|
||||
|
||||
AC_ARG_ENABLE(wayland,
|
||||
AS_HELP_STRING([--disable-wayland], [disable mutter on wayland support]),,
|
||||
enable_wayland=auto
|
||||
)
|
||||
AS_IF([test "$enable_wayland" = "yes"], [have_wayland=yes],
|
||||
[test "$enable_wayland" = "auto"], PKG_CHECK_EXISTS([$MUTTER_WAYLAND_MODULES], [have_wayland=yes]))
|
||||
|
||||
AS_IF([test "$have_wayland" = "yes"], [
|
||||
PKG_CHECK_MODULES([MUTTER_WAYLAND], [$MUTTER_WAYLAND_MODULES])
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test $WAYLAND_SCANNER = "no"],
|
||||
[AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])])
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
@@ -416,6 +433,8 @@ mutter-$VERSION
|
||||
libcanberra: ${have_libcanberra}
|
||||
Introspection: ${found_introspection}
|
||||
Session management: ${found_sm}
|
||||
Wayland: ${have_wayland}
|
||||
Native (KMS) backend: ${have_native_backend}
|
||||
"
|
||||
|
||||
|
||||
|
@@ -29,5 +29,25 @@
|
||||
<default><![CDATA[['<Primary><Alt>F7']]]></default>
|
||||
<_summary>Switch to VT 7</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-8" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F8']]]></default>
|
||||
<_summary>Switch to VT 8</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-9" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F9']]]></default>
|
||||
<_summary>Switch to VT 9</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-10" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F10']]]></default>
|
||||
<_summary>Switch to VT 10</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-11" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F11']]]></default>
|
||||
<_summary>Switch to VT 11</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-12" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F12']]]></default>
|
||||
<_summary>Switch to VT 12</_summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
SUBDIRS = man reference
|
||||
|
||||
EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \
|
||||
EXTRA_DIST = dialogs.txt code-overview.txt \
|
||||
how-to-get-focus-right.txt rationales.txt
|
||||
|
@@ -81,6 +81,7 @@ IGNORE_HFILES= \
|
||||
keybindings-private.h \
|
||||
meta-background-actor-private.h \
|
||||
meta-background-group-private.h \
|
||||
meta-dbus-login1.h \
|
||||
meta-module.h \
|
||||
meta-plugin-manager.h \
|
||||
meta-shadow-factory-private.h \
|
||||
@@ -111,6 +112,17 @@ IGNORE_HFILES= \
|
||||
xprops.h \
|
||||
$(NULL)
|
||||
|
||||
if !HAVE_NATIVE_BACKEND
|
||||
IGNORE_HFILES+= \
|
||||
meta-backend-native.h \
|
||||
meta-barrier-native.h \
|
||||
meta-cursor-renderer-native.h \
|
||||
meta-idle-monitor-native.h \
|
||||
meta-input-settings-native.h \
|
||||
meta-monitor-manager-kms.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
if !HAVE_WAYLAND
|
||||
IGNORE_HFILES += \
|
||||
meta-surface-actor-wayland.h \
|
||||
|
@@ -22,7 +22,6 @@
|
||||
<title>Mutter Core Reference</title>
|
||||
<xi:include href="xml/main.xml"/>
|
||||
<xi:include href="xml/common.xml"/>
|
||||
<xi:include href="xml/gradient.xml"/>
|
||||
<xi:include href="xml/prefs.xml"/>
|
||||
<xi:include href="xml/util.xml"/>
|
||||
<xi:include href="xml/errors.xml"/>
|
||||
|
@@ -172,15 +172,6 @@ meta_error_trap_push_with_return
|
||||
meta_error_trap_pop_with_return
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gradient</FILE>
|
||||
MetaGradientType
|
||||
meta_gradient_create_simple
|
||||
meta_gradient_create_multi
|
||||
meta_gradient_create_interwoven
|
||||
meta_gradient_add_alpha
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>group</FILE>
|
||||
MetaGroup
|
||||
|
@@ -1,394 +0,0 @@
|
||||
Themes are in a simple XML-subset format. There are multiple versions
|
||||
of the theme format, and a given theme can support more than one format.
|
||||
|
||||
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
|
||||
(original metacity format)
|
||||
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
|
||||
Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml
|
||||
|
||||
The subdirectory name is "metacity-1" in all versions.
|
||||
|
||||
As you might expect, older versions of metacity will not understand
|
||||
newer theme formats. However, newer versions will use old themes.
|
||||
Metacity will always use the newest theme format it understands that
|
||||
the X server supports. Some format versions are only supported if you
|
||||
have the right X server features.
|
||||
|
||||
Each format *requires* the corresponding filename. If you put version
|
||||
2 format features in the metacity-1/metacity-theme-1.xml file, then
|
||||
metacity will get angry.
|
||||
|
||||
This document has separate sections for each format version. You may
|
||||
want to read the document in reverse order, since the base features
|
||||
are discussed under version 1.
|
||||
|
||||
New Features in Theme Format Version 3.4
|
||||
========================================
|
||||
|
||||
An additional color type is added to pick up custom colors defined
|
||||
in the GTK+ theme's CSS:
|
||||
|
||||
gtk:custom(name,fallback)
|
||||
|
||||
where <name> refers to a custom color defined with @define-color in
|
||||
the GTK+ theme, and <fallback> provides an alternative color definition
|
||||
in case the color referenced by <name> is not found.
|
||||
|
||||
New Features in Theme Format Version 3.3
|
||||
========================================
|
||||
|
||||
Add two additional button background functions - left_single_background and
|
||||
right_single_background - for button groups with just a single button.
|
||||
|
||||
There are now additional frame states to style left/right tiled windows
|
||||
differently ("tiled_left", "tiled_right", "tiled_left_and_shaded",
|
||||
"tiled_right_and_shaded").
|
||||
|
||||
New Features in Theme Format Version 3.2
|
||||
========================================
|
||||
|
||||
A new window type 'attached' is added for modal dialogs which are
|
||||
attached to their parent window. (When the attach_modal_dialogs preference
|
||||
is turned on.) If no style is defined for the 'attached' window type,
|
||||
the 'border' window type will be used instead.
|
||||
|
||||
New Features in Theme Format Version 3.1
|
||||
========================================
|
||||
|
||||
Additional predefined variables are added for positioning expressions:
|
||||
|
||||
frame_x_center: the X center of the entire frame, with respect to the
|
||||
piece currently being drawn.
|
||||
frame_y_center: the Y center of the entire frame, with respect to the
|
||||
piece currently being drawn.
|
||||
|
||||
The <title/> element now supports an "ellipsize_width" attribute. When
|
||||
specified, this gives a width at which to ellipsize the title. If not
|
||||
specified, the title will simply be clipped to the title area.
|
||||
|
||||
New Features in Theme Format Version 3
|
||||
======================================
|
||||
|
||||
Format version 3 has exactly one new feature; any element in the file
|
||||
can now have a version attribute:
|
||||
|
||||
version="[<|<=|=>|>] MAJOR.MINOR"
|
||||
|
||||
(< and > should be to be entity escaped as < and >). If this
|
||||
version check is not met, then the element and its children will be
|
||||
ignored. This allows having alternate sections of the theme file for
|
||||
older and newer version of the Metacity theme format.
|
||||
|
||||
When placed on the toplevel <metacity_theme> element, an unsatisfied
|
||||
version check will not just cause the contents of the file to be
|
||||
ignored, it will also cause the lookup of a theme file to proceed on
|
||||
and look for an older format 2 or format 1 file. This allows making a
|
||||
metacity-theme-3.xml file that is only used the format version 3.2 or
|
||||
newer is supported, and using metacity-theme-1.xml for older window
|
||||
managers.
|
||||
|
||||
New Features in Theme Format Version 2
|
||||
======================================
|
||||
|
||||
The optional attributes rounded_top_left, rounded_top_right,
|
||||
rounded_bottom_left and rounded_bottom_right on <frame_geometry>
|
||||
should now be the radius of the corner in pixels. You may still use
|
||||
the values "false" for 0 and "true" for 5, which means v1 values will
|
||||
still work just fine.
|
||||
|
||||
<frame_geometry> has a new optional attribute, hide_buttons. If this
|
||||
is true, no buttons will be displayed on the titlebar.
|
||||
|
||||
Anywhere you can use a positive integer, you can use an integer constant.
|
||||
|
||||
As well as constant integers and reals, you may define constant colours,
|
||||
thus:
|
||||
<constant name="RevoltingPink" value="#FF00FF"/>
|
||||
<constant name="Background" value="gtk:bg[NORMAL]"/>
|
||||
|
||||
<frame_style> has two new optional attributes, background and alpha.
|
||||
If you specify alpha, you must specify background. background is a
|
||||
colour used for the background of the frame. alpha is the transparency
|
||||
as a real between 0.0 and 1.0. If the current X server does not support
|
||||
alpha channels, the value is ignored.
|
||||
|
||||
The filename attribute of <image> may begin with "theme:". If so, the
|
||||
rest of the string is the name of a theme icon. The 64x64 version of the
|
||||
icon is used, except for fallback mini_icons, which use the 16x16 version.
|
||||
This does not affect ordinary resizing. For example:
|
||||
<button function="close" state="normal">
|
||||
<draw_ops>
|
||||
<include name="active_button"/>
|
||||
<image filename="theme:gnome-logout" x="2" y="2"
|
||||
width="width-4" height="height-4"/>
|
||||
<!-- Note: not "theme:gnome-logout.png" or similar. -->
|
||||
</draw_ops>
|
||||
</button>
|
||||
|
||||
<menu_icon>s are parsed but ignored.
|
||||
|
||||
Fallback icons can be specified using <fallback>. There are two
|
||||
optional arguments, icon and mini_icon. The values of these arguments
|
||||
are identical to that of the filename attribute of <image>. Fallback
|
||||
icons are used when a window does not supply its own icon. If a fallback
|
||||
icon is not specified with <fallback>, Metacity will use a built-in
|
||||
icon, as in metacity-theme-1.
|
||||
|
||||
The <arc> element, as well as the original start_angle and end_angle
|
||||
attributes, may be given from and to attributes. The values of these
|
||||
attributes are given in degrees clockwise, with 0 being straight up.
|
||||
For example:
|
||||
<arc from="0.0" to="90.0" filled="true" color="#FF00FF"
|
||||
x="0" y="5" width="15" height="15"/>
|
||||
|
||||
<frame state="shaded"> may now take an optional resize attribute, with
|
||||
the same interpretation as the resize attribute on <frame state="normal">.
|
||||
If this attribute is omitted for state="shaded", it defaults to "both".
|
||||
(If it is omitted for state="normal", it remains an error.)
|
||||
|
||||
In addition to the four <button> functions which are required in
|
||||
metacity-theme-1, there are six new functions in metacity-theme-2:
|
||||
shade, unshade, above, unabove, stick and unstick.
|
||||
|
||||
Overview of Theme Format Version 1
|
||||
==================================
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<metacity_theme>
|
||||
<!-- Only one info section is allowed -->
|
||||
<info>
|
||||
<name>Foo</name>
|
||||
<author>Foo P. Bar</author>
|
||||
<copyright>whoever, 2002</copyright>
|
||||
<date>Jan 31 2005</date>
|
||||
<description>A sentence about the theme.</description>
|
||||
</info>
|
||||
|
||||
<!-- define a frame geometry to be referenced later -->
|
||||
<!-- frame_geometry has an optional has_title attribute which
|
||||
determines whether the title text height is included in the
|
||||
height calculation. if not specified, defaults to true.
|
||||
It also has an optional text_size="medium" attribute
|
||||
(same sizes as with Pango markup, xx-small thru medium thru
|
||||
xx-large)
|
||||
|
||||
Finally it has optional args rounded_top_left=true,
|
||||
rounded_top_right=true, rounded_bottom_left=true,
|
||||
rounded_bottom_right=true.
|
||||
|
||||
-->
|
||||
<frame_geometry name="normal" has_title="true" title_scale="medium">
|
||||
<distance name="left_width" value="6"/>
|
||||
<distance name="right_width" value="6"/>
|
||||
<distance name="bottom_height" value="7"/>
|
||||
<distance name="left_titlebar_edge" value="6"/>
|
||||
<distance name="right_titlebar_edge" value="6"/>
|
||||
<distance name="button_width" value="17"/>
|
||||
<distance name="button_height" value="17"/>
|
||||
<!-- alternative to button_width button_height distances -->
|
||||
<aspect_ratio name="button" value="1.0"/>
|
||||
<distance name="title_vertical_pad" value="4"/>
|
||||
<border name="title_border" left="3" right="12" top="4" bottom="3"/>
|
||||
<border name="button_border" left="0" right="0" top="1" bottom="1"/>
|
||||
</frame_geometry>
|
||||
|
||||
<!-- inheritance is allowed; simply overwrites values from parent -->
|
||||
<frame_geometry name="borderless" parent="normal">
|
||||
<distance name="left_width" value="0"/>
|
||||
<distance name="right_width" value="0"/>
|
||||
<distance name="bottom_height" value="0"/>
|
||||
<distance name="left_titlebar_edge" value="0"/>
|
||||
<distance name="right_titlebar_edge" value="0"/>
|
||||
</frame_geometry>
|
||||
|
||||
<!-- define a constant to use in positions/sizes of draw operations;
|
||||
constant names must start with a capital letter.
|
||||
-->
|
||||
<constant name="LineOffset" value="3"/>
|
||||
|
||||
<!-- define drawing operations to be referenced later;
|
||||
these draw-op lists can also be placed inline.
|
||||
|
||||
Positions/lengths are given as expressions.
|
||||
Operators are: +,-,*,/,%,`max`,`min`
|
||||
All operators are infix including `max` and `min`,
|
||||
i.e. "2 `max` 5"
|
||||
|
||||
Some variables are predefined, and constants can also
|
||||
be used. Variables are:
|
||||
|
||||
width - width of target area
|
||||
height - height of target area
|
||||
object_width - natural width of object being drawn
|
||||
object_height - natural height of object being drawn
|
||||
left_width - distance from left of frame to client window
|
||||
right_width - distance from right of frame to client window
|
||||
top_height - distance from top of frame to client window
|
||||
bottom_height - distance from bottom of frame to client window
|
||||
mini_icon_width - width of mini icon for window
|
||||
mini_icon_height - height of mini icon
|
||||
icon_width - width of large icon
|
||||
icon_height - height of large icon
|
||||
title_width - width of title text
|
||||
title_height - height of title text
|
||||
|
||||
All these are always defined, except object_width/object_height
|
||||
which only exists for <image> right now.
|
||||
|
||||
-->
|
||||
|
||||
<draw_ops name="demo_all_ops">
|
||||
<line color="#00FF00" x1="LineOffset" y1="0" x2="0" y2="height"/>
|
||||
<line color="gtk:fg[NORMAL]"
|
||||
x1="width - 1" y1="0" x2="width - 1" y2="height"
|
||||
width="3" dash_on_length="2" dash_off_length="3"/>
|
||||
<rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7"
|
||||
x="0" y="0" width="width - 1" height="height - 1" filled="true"/>
|
||||
<arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1"
|
||||
filled="false" start_angle="30" extent_angle="180"/>
|
||||
<tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/>
|
||||
<!-- may be vertical, horizontal, diagonal -->
|
||||
<gradient type="diagonal"
|
||||
x="10" y="30" width="width / 3" height="height / 4">
|
||||
<!-- any number of colors allowed here. A color can be
|
||||
a color name like "blue" (look at gcolorsel), a hex color
|
||||
as in HTML (#FFBB99), or a color from the gtk theme
|
||||
given as "gtk:base[NORMAL]", "gtk:fg[ACTIVE]", etc.
|
||||
-->
|
||||
<color value="gtk:fg[SELECTED]"/>
|
||||
<!-- color obtained by a 0.5 alpha composite of the second color onto the first -->
|
||||
<color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/>
|
||||
</gradient>
|
||||
<image filename="foo.png" alpha="0.7"
|
||||
x="10" y="30" width="width / 3" height="height / 4"/>
|
||||
<gtk_arrow state="normal" shadow="in" arrow="up"
|
||||
filled="true"
|
||||
x="2" y="2" width="width - 4" height="height - 4"/>
|
||||
<gtk_box state="normal" shadow="out"
|
||||
x="2" y="2" width="width - 4" height="height - 4"/>
|
||||
<gtk_vline state="normal" x="2" y1="0" y2="height"/>
|
||||
<!-- window's icon -->
|
||||
<icon alpha="0.7"
|
||||
x="10" y="30" width="width / 3" height="height / 4"/>
|
||||
<!-- window's title -->
|
||||
<title color="gtk:text[NORMAL]" x="20" y="30"/>
|
||||
<!-- include another draw ops list; has optional x/y/width/height attrs -->
|
||||
<include name="some_other_draw_ops"/>
|
||||
<!-- tile another draw ops list; has optional
|
||||
x/y/width/height/tile_xoffset/tile_yoffset -->
|
||||
<tile name="some_other_draw_ops" tile_width="10" tile_height="10"/>
|
||||
</draw_ops>
|
||||
|
||||
<frame_style name="normal" geometry="normal">
|
||||
<!-- How to draw each piece of the frame.
|
||||
For each piece, a draw_ops can be given inline or referenced
|
||||
by name. If a piece is omitted, then nothing will be drawn
|
||||
for that piece.
|
||||
|
||||
For each piece, the "width" and "height" variables in
|
||||
coordinate expressions refers to the dimensions of the piece,
|
||||
the origin is at the top left of the piece.
|
||||
|
||||
So <rectangle x="0" y="0" width="width-1" height="height-1"/>
|
||||
will outline a piece.
|
||||
-->
|
||||
|
||||
<piece position="entire_background" draw_ops="demo_all_ops"/>
|
||||
<piece position="left_titlebar_edge">
|
||||
<draw_ops>
|
||||
<line color="#00FF00" x1="0" y1="0" x2="0" y2="height"/>
|
||||
</draw_ops>
|
||||
</piece>
|
||||
|
||||
<!-- The complete list of frame pieces:
|
||||
|
||||
entire_background: whole frame
|
||||
titlebar: entire area above the app's window
|
||||
titlebar_middle: area of titlebar_background not considered
|
||||
part of an edge
|
||||
left_titlebar_edge: left side of titlebar background
|
||||
right_titlebar_edge: right side of titlebar background
|
||||
top_titlebar_edge: top side of titlebar background
|
||||
bottom_titlebar_edge: bottom side of titlebar background
|
||||
title: the title area (doesn't include buttons)
|
||||
left_edge: left edge of the frame
|
||||
right_edge: right edge of the frame
|
||||
bottom_edge: bottom edge of the frame
|
||||
overlay: same area as entire_background, but drawn after
|
||||
drawing all sub-pieces instead of before
|
||||
|
||||
-->
|
||||
|
||||
<!-- For buttons, drawing methods have to be provided for
|
||||
each of three states:
|
||||
normal, pressed, prelight
|
||||
and the button function or position must be provided:
|
||||
close, maximize, minimize, menu,
|
||||
left_left_background, left_middle_background,
|
||||
left_right_background, right_left_background,
|
||||
right_middle_background, right_right_background
|
||||
So a working theme needs 3*4 = 12 button declarations
|
||||
and a theme may have up to 3*10 = 30 button declarations
|
||||
in order to handle button-rearrangement preferences.
|
||||
|
||||
(The name "function" for the attribute is from before the
|
||||
background values existed.)
|
||||
-->
|
||||
|
||||
<button function="close" state="normal" draw_ops="previously_named"/>
|
||||
<button function="menu" state="normal">
|
||||
<draw_ops>
|
||||
<icon alpha="0.7"
|
||||
x="0" y="0" width="object_width" height="object_height"/>
|
||||
</draw_ops>
|
||||
</button>
|
||||
|
||||
</frame_style>
|
||||
|
||||
<!-- styles can inherit from each other with the parent="" attribute.
|
||||
In a subclass anything can be re-specified to override
|
||||
the parent style. -->
|
||||
<frame_style name="focused" parent="normal">
|
||||
<piece position="title">
|
||||
<draw_ops>
|
||||
<rectangle color="gtk:bg[SELECTED]"
|
||||
x="0" y="0" width="width-1" height="height-1"/>
|
||||
<title color="gtk:fg[SELECTED]" x="(width - title_width) / 2"
|
||||
y="(height - title_height) / 2"/>
|
||||
</draw_ops>
|
||||
</piece>
|
||||
</frame_style>
|
||||
|
||||
<!-- Maps styles to states of frame.
|
||||
|
||||
Focus: yes (focused), no (not focused)
|
||||
Window states: normal, maximized, shaded, maximized_and_shaded
|
||||
Window resizability: none, vertical, horizontal, both
|
||||
|
||||
Everything unspecified just does the same as
|
||||
unfocused/normal/both.
|
||||
|
||||
only state="normal" needs a resize="" attribute.
|
||||
-->
|
||||
<frame_style_set name="normal">
|
||||
<frame focus="yes" state="normal" resize="both" style="focused"/>
|
||||
<frame focus="no" state="normal" resize="both" style="normal"/>
|
||||
</frame_style_set>
|
||||
|
||||
<!-- Each window type needs a style set
|
||||
Types: normal, dialog, modal_dialog, menu, utility, border
|
||||
-->
|
||||
<window type="normal" style_set="normal"/>
|
||||
|
||||
|
||||
<!-- For menu icons, drawing methods are needed for the same
|
||||
four types as the buttons, and GTK states
|
||||
(insensitive,prelight,normal,etc.)
|
||||
-->
|
||||
|
||||
<menu_icon function="close" state="normal" draw_ops="previously_named"/>
|
||||
|
||||
|
||||
</metacity_theme>
|
||||
|
||||
|
@@ -22,9 +22,7 @@ src/core/screen.c
|
||||
src/core/util.c
|
||||
src/core/window.c
|
||||
src/ui/frames.c
|
||||
src/ui/resizepopup.c
|
||||
src/ui/theme.c
|
||||
src/ui/theme-parser.c
|
||||
src/x11/session.c
|
||||
src/x11/window-props.c
|
||||
src/x11/xprops.c
|
||||
|
304
po/hu.po
304
po/hu.po
@@ -7,14 +7,13 @@
|
||||
# Laszlo Dvornik <dvornik at gnome dot hu>, 2004.
|
||||
# Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013.
|
||||
# Balázs Úr <urbalazs at gmail dot com>, 2013, 2014.
|
||||
# Balázs Úr <urbalazs@gmail.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2014-09-11 09:53+0000\n"
|
||||
"PO-Revision-Date: 2014-09-11 18:20+0200\n"
|
||||
"POT-Creation-Date: 2014-12-29 03:21+0000\n"
|
||||
"PO-Revision-Date: 2014-12-29 09:28+0100\n"
|
||||
"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
|
||||
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
|
||||
"Language: hu\n"
|
||||
@@ -45,7 +44,6 @@ msgid "Move window to workspace 4"
|
||||
msgstr "Ablak áthelyezése a 4. munkaterületre"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:6
|
||||
#| msgid "Move window to workspace 1"
|
||||
msgid "Move window to last workspace"
|
||||
msgstr "Ablak áthelyezése az utolsó munkaterületre"
|
||||
|
||||
@@ -86,7 +84,6 @@ msgid "Switch applications"
|
||||
msgstr "Alkalmazásváltás"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:16
|
||||
#| msgid "Switch applications"
|
||||
msgid "Switch to previous application"
|
||||
msgstr "Váltás az előző alkalmazásra"
|
||||
|
||||
@@ -95,7 +92,6 @@ msgid "Switch windows"
|
||||
msgstr "Ablakváltás"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#| msgid "Switch windows"
|
||||
msgid "Switch to previous window"
|
||||
msgstr "Váltás az előző ablakra"
|
||||
|
||||
@@ -104,7 +100,6 @@ msgid "Switch windows of an application"
|
||||
msgstr "Váltás egy alkalmazás ablakai között"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#| msgid "Switch windows of an application"
|
||||
msgid "Switch to previous window of an application"
|
||||
msgstr "Váltás egy alkalmazás előző ablakára"
|
||||
|
||||
@@ -113,7 +108,6 @@ msgid "Switch system controls"
|
||||
msgstr "Váltás a rendszer vezérlői közt"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#| msgid "Switch system controls"
|
||||
msgid "Switch to previous system control"
|
||||
msgstr "Váltás az előző rendszervezérlőre"
|
||||
|
||||
@@ -130,7 +124,6 @@ msgid "Switch windows of an app directly"
|
||||
msgstr "Váltás egy alkalmazás ablakai között közvetlenül"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#| msgid "Switch windows of an application"
|
||||
msgid "Switch directly to previous window of an app"
|
||||
msgstr "Váltás közvetlenül egy alkalmazás előző ablakára"
|
||||
|
||||
@@ -139,7 +132,6 @@ msgid "Switch system controls directly"
|
||||
msgstr "Váltás a rendszer vezérlői közt közvetlenül"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#| msgid "Switch system controls"
|
||||
msgid "Switch directly to previous system control"
|
||||
msgstr "Váltás közvetlenül az előző rendszervezérlőre"
|
||||
|
||||
@@ -164,7 +156,6 @@ msgid "Switch to workspace 4"
|
||||
msgstr "Váltás a 4. munkaterületre"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
#| msgid "Switch to workspace 1"
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Váltás az utolsó munkaterületre"
|
||||
|
||||
@@ -417,70 +408,62 @@ msgid "Cancel tab popup"
|
||||
msgstr "Tab felugró kikapcsolása"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
|
||||
#| msgid "Switch to workspace 1"
|
||||
msgid "Switch to VT 1"
|
||||
msgstr "Váltás az 1. VT-re"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
|
||||
#| msgid "Switch to workspace 2"
|
||||
msgid "Switch to VT 2"
|
||||
msgstr "Váltás a 2. VT-re"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
|
||||
#| msgid "Switch to workspace 3"
|
||||
msgid "Switch to VT 3"
|
||||
msgstr "Váltás a 3. VT-re"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
|
||||
#| msgid "Switch to workspace 4"
|
||||
msgid "Switch to VT 4"
|
||||
msgstr "Váltás a 4. VT-re"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
|
||||
#| msgid "Switch to workspace 5"
|
||||
msgid "Switch to VT 5"
|
||||
msgstr "Váltás az 5. VT-re"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
|
||||
#| msgid "Switch to workspace 6"
|
||||
msgid "Switch to VT 6"
|
||||
msgstr "Váltás a 6. VT-re"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
|
||||
#| msgid "Switch to workspace 7"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Váltás a 7. VT-re"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:412
|
||||
#: ../src/backends/meta-monitor-manager.c:350
|
||||
msgid "Built-in display"
|
||||
msgstr "Beépített kijelző"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:437
|
||||
#: ../src/backends/meta-monitor-manager.c:375
|
||||
msgid "Unknown"
|
||||
msgstr "Ismeretlen"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:439
|
||||
#: ../src/backends/meta-monitor-manager.c:377
|
||||
msgid "Unknown Display"
|
||||
msgstr "Ismeretlen kijelző"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:447
|
||||
#: ../src/backends/meta-monitor-manager.c:385
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:443
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr ""
|
||||
"Már fut egy másik betűszedés-kezelő a(z) %i képernyőn a(z) „%s” "
|
||||
"megjelenítőn."
|
||||
"Már fut egy másik betűszedés-kezelő a(z) %i képernyőn a(z) „%s” megjelenítőn."
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
@@ -511,7 +494,7 @@ msgstr "Vá_rakozás"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Erőltetett kilépés"
|
||||
|
||||
#: ../src/core/display.c:547
|
||||
#: ../src/core/display.c:550
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Nem sikerült megnyitni a(z) „%s” X Window rendszer képernyőt\n"
|
||||
@@ -585,30 +568,28 @@ msgstr "Verzió kinyomtatása"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Használandó Mutter bővítmény"
|
||||
|
||||
#: ../src/core/prefs.c:2101
|
||||
#: ../src/core/prefs.c:2064
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "%d. munkaterület"
|
||||
|
||||
#: ../src/core/screen.c:548
|
||||
#: ../src/core/screen.c:525
|
||||
#, c-format
|
||||
#| msgid ""
|
||||
#| "Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
#| "replace option to replace the current window manager.\n"
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
msgstr ""
|
||||
"A(z) „%s” kijelző már rendelkezik ablakkezelővel; próbálja a --replace "
|
||||
"kapcsolóval helyettesíteni a jelenlegi ablakkezelőt."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "A(z) %d képernyő a(z) „%s” megjelenítőn érvénytelen\n"
|
||||
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
"replace option to replace the current window manager.\n"
|
||||
msgstr ""
|
||||
"A(z) %d képernyő a(z) „%s” megjelenítőn már rendelkezik egy ablakkezelővel; "
|
||||
"próbálja a --replace opcióval helyettesíteni a jelenlegi ablakkezelőt.\n"
|
||||
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "A(z) %d képernyőnek a(z) „%s” megjelenítőn már van ablakkezelője\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "A Mutter ablakkezelőt a részletes mód támogatása nélkül fordították\n"
|
||||
@@ -621,48 +602,48 @@ msgstr "A Mutter ablakkezelőt a részletes mód támogatása nélkül fordítot
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:233
|
||||
#: ../src/ui/theme.c:154
|
||||
msgid "top"
|
||||
msgstr "fent"
|
||||
|
||||
#: ../src/ui/theme.c:235
|
||||
#: ../src/ui/theme.c:156
|
||||
msgid "bottom"
|
||||
msgstr "lent"
|
||||
|
||||
#: ../src/ui/theme.c:237
|
||||
#: ../src/ui/theme.c:158
|
||||
msgid "left"
|
||||
msgstr "bal"
|
||||
|
||||
#: ../src/ui/theme.c:239
|
||||
#: ../src/ui/theme.c:160
|
||||
msgid "right"
|
||||
msgstr "jobb"
|
||||
|
||||
#: ../src/ui/theme.c:267
|
||||
#: ../src/ui/theme.c:188
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "a keretgeometria nem határoz meg „%s” dimenziót"
|
||||
|
||||
#: ../src/ui/theme.c:286
|
||||
#: ../src/ui/theme.c:207
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr "a keretgeometria nem határoz meg „%s” dimenziót „%s” szegélynek"
|
||||
|
||||
#: ../src/ui/theme.c:323
|
||||
#: ../src/ui/theme.c:244
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "%g gomb méretaránya nem fogadható el"
|
||||
|
||||
#: ../src/ui/theme.c:335
|
||||
#: ../src/ui/theme.c:256
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "A keretgeometria nem határozza meg a gombok méretét"
|
||||
|
||||
#: ../src/ui/theme.c:1061
|
||||
#: ../src/ui/theme.c:1024
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "A színátmenetnek legalább két színűnek kell lennie"
|
||||
|
||||
#: ../src/ui/theme.c:1211
|
||||
#: ../src/ui/theme.c:1174
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
@@ -672,7 +653,7 @@ msgstr ""
|
||||
"tartalékot, például gtk:custom(foo,bar); nem sikerült értelmezni a "
|
||||
"következőt: „%s”"
|
||||
|
||||
#: ../src/ui/theme.c:1227
|
||||
#: ../src/ui/theme.c:1190
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
@@ -681,7 +662,7 @@ msgstr ""
|
||||
"Érvénytelen karakter („%c”) a gtk:custom color_name paraméterében, csak az A-"
|
||||
"Za-z0-9-_ érvényes"
|
||||
|
||||
#: ../src/ui/theme.c:1241
|
||||
#: ../src/ui/theme.c:1204
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
@@ -690,7 +671,7 @@ msgstr ""
|
||||
"A Gtk:custom formátuma: „gtk:custom(színnév,tartalék)”, „%s” nem felel meg "
|
||||
"ennek"
|
||||
|
||||
#: ../src/ui/theme.c:1286
|
||||
#: ../src/ui/theme.c:1249
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
@@ -700,7 +681,7 @@ msgstr ""
|
||||
"gtk:fg[NORMAL] ahol NORMAL az állapot; nem lehetett feldolgozni a "
|
||||
"következőt: „%s”"
|
||||
|
||||
#: ../src/ui/theme.c:1300
|
||||
#: ../src/ui/theme.c:1263
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
@@ -710,17 +691,17 @@ msgstr ""
|
||||
"után, például gtk:fg[NORMAL], ahol NORMAL az állapot; nem sikerült "
|
||||
"értelmezni a következőt: „%s”"
|
||||
|
||||
#: ../src/ui/theme.c:1311
|
||||
#: ../src/ui/theme.c:1274
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "Nem sikerült a(z) „%s” állapotot értelmezni a szín meghatározásban"
|
||||
|
||||
#: ../src/ui/theme.c:1324
|
||||
#: ../src/ui/theme.c:1287
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "Nem sikerült értelmezni „%s” színösszetevőt a színmeghatározásban"
|
||||
|
||||
#: ../src/ui/theme.c:1352
|
||||
#: ../src/ui/theme.c:1315
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
@@ -729,44 +710,44 @@ msgstr ""
|
||||
"A keverés formátuma: „blend/bg_color/fg_color/alpha”, „%s” nem felel meg "
|
||||
"ennek"
|
||||
|
||||
#: ../src/ui/theme.c:1363
|
||||
#: ../src/ui/theme.c:1326
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Nem sikerült értelmezni a(z) „%s” alfa értéket a kevert színben"
|
||||
|
||||
#: ../src/ui/theme.c:1373
|
||||
#: ../src/ui/theme.c:1336
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr "A(z) „%s” alfa érték a kevert színben nem 0.0 és 1.0 között van"
|
||||
|
||||
#: ../src/ui/theme.c:1419
|
||||
#: ../src/ui/theme.c:1382
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
msgstr ""
|
||||
"Az árnyék formátuma: „shade/base_color/factor”, „%s” nem felel meg ennek"
|
||||
|
||||
#: ../src/ui/theme.c:1430
|
||||
#: ../src/ui/theme.c:1393
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "Nem sikerült a(z) „%s” árnyéktényezőt feldolgozni az árnyékolt színben"
|
||||
|
||||
#: ../src/ui/theme.c:1440
|
||||
#: ../src/ui/theme.c:1403
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "„%s” árnyéktényező az árnyékolt színben negatív"
|
||||
|
||||
#: ../src/ui/theme.c:1469
|
||||
#: ../src/ui/theme.c:1432
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Nem sikerült feldolgozni a(z) „%s” színt"
|
||||
|
||||
#: ../src/ui/theme.c:1778
|
||||
#: ../src/ui/theme.c:1741
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr "A koordinátakifejezés „%s” karaktert tartalmaz, ami nem megengedett"
|
||||
|
||||
#: ../src/ui/theme.c:1805
|
||||
#: ../src/ui/theme.c:1768
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
@@ -775,14 +756,14 @@ msgstr ""
|
||||
"A koordinátakifejezés „%s” lebegőpontos számot tartalmaz, amit nem sikerült "
|
||||
"feldolgozni"
|
||||
|
||||
#: ../src/ui/theme.c:1819
|
||||
#: ../src/ui/theme.c:1782
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr ""
|
||||
"A koordinátakifejezés „%s” egész számot tartalmaz, amit nem sikerült "
|
||||
"feldolgozni"
|
||||
|
||||
#: ../src/ui/theme.c:1940
|
||||
#: ../src/ui/theme.c:1903
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
@@ -791,40 +772,40 @@ msgstr ""
|
||||
"A koordinátakifejezés ismeretlen operátort tartalmaz ennek a szövegnek az "
|
||||
"elején: „%s”"
|
||||
|
||||
#: ../src/ui/theme.c:1997
|
||||
#: ../src/ui/theme.c:1960
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "A koordinátakifejezés üres vagy értelmezhetetlen volt"
|
||||
|
||||
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
|
||||
#: ../src/ui/theme.c:2073 ../src/ui/theme.c:2083 ../src/ui/theme.c:2117
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "A koordinátakifejezés nullával való osztást okozott"
|
||||
|
||||
#: ../src/ui/theme.c:2162
|
||||
#: ../src/ui/theme.c:2125
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
msgstr ""
|
||||
"A koordinátakifejezés mod operátort próbált használni lebegőpontos számon"
|
||||
|
||||
#: ../src/ui/theme.c:2218
|
||||
#: ../src/ui/theme.c:2181
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr "A koordinátakifejezésben egy operandus helyén „%s” operátor volt"
|
||||
|
||||
#: ../src/ui/theme.c:2227
|
||||
#: ../src/ui/theme.c:2190
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr "A koordinátakifejezésben a várt operátor helyett operandus szerepelt"
|
||||
|
||||
#: ../src/ui/theme.c:2235
|
||||
#: ../src/ui/theme.c:2198
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr "A koordinátakifejezés operátorral végződött, nem operandussal"
|
||||
|
||||
#: ../src/ui/theme.c:2245
|
||||
#: ../src/ui/theme.c:2208
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
@@ -833,38 +814,38 @@ msgstr ""
|
||||
"A koordinátakifejezésben „%c” operátort „%c” operátor követi úgy, hogy nincs "
|
||||
"köztük operandus"
|
||||
|
||||
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
|
||||
#: ../src/ui/theme.c:2359 ../src/ui/theme.c:2404
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr "A koordinátakifejezésben „%s” változó vagy állandó ismeretlen volt"
|
||||
|
||||
#: ../src/ui/theme.c:2495
|
||||
#: ../src/ui/theme.c:2458
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "A koordinátakifejezés-elemző túlcsordította a pufferét."
|
||||
|
||||
#: ../src/ui/theme.c:2524
|
||||
#: ../src/ui/theme.c:2487
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr "A koordinátakifejezésben záró zárójel szerepelt kezdő nélkül"
|
||||
|
||||
#: ../src/ui/theme.c:2588
|
||||
#: ../src/ui/theme.c:2551
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr "A koordinátakifejezésben kezdő zárójel szerepelt záró nélkül"
|
||||
|
||||
#: ../src/ui/theme.c:2599
|
||||
#: ../src/ui/theme.c:2562
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr ""
|
||||
"A koordinátakifejezésben úgy tűnik nincsenek sem operátorok, sem operandusok"
|
||||
|
||||
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
|
||||
#: ../src/ui/theme.c:2775 ../src/ui/theme.c:2795 ../src/ui/theme.c:2815
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "A téma által tartalmazott kifejezés hibát okozott: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4455
|
||||
#: ../src/ui/theme.c:4055
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
@@ -873,25 +854,25 @@ msgstr ""
|
||||
"Ehhez a keretstílushoz meg kell határozni a következő elemet: <button "
|
||||
"function=\"%s\" state=\"%s\" draw_ops=\"bármi\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
|
||||
#: ../src/ui/theme.c:4570 ../src/ui/theme.c:4595
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr ""
|
||||
"Hiányzó <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"bármi\"/> elem"
|
||||
|
||||
#: ../src/ui/theme.c:5041
|
||||
#: ../src/ui/theme.c:4641
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Hiba a(z) „%s” téma betöltése közben: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
|
||||
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
|
||||
#: ../src/ui/theme.c:4777 ../src/ui/theme.c:4784 ../src/ui/theme.c:4791
|
||||
#: ../src/ui/theme.c:4798 ../src/ui/theme.c:4805
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Nincs <%s> beállítva a(z) „%s” témához"
|
||||
|
||||
#: ../src/ui/theme.c:5213
|
||||
#: ../src/ui/theme.c:4813
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -900,7 +881,7 @@ msgstr ""
|
||||
"Nincs keretstílus beállítva a(z) „%s” ablaktípushoz a(z) „%s” témában, adjon "
|
||||
"hozzá egy <window type=\"%s\" style_set=\"bármi\"/> elemet"
|
||||
|
||||
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
|
||||
#: ../src/ui/theme.c:5220 ../src/ui/theme.c:5282 ../src/ui/theme.c:5345
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
@@ -908,7 +889,7 @@ msgstr ""
|
||||
"A felhasználó által meghatározott konstansoknak nagybetűvel kell kezdődniük, "
|
||||
"a(z) „%s” nem ilyen"
|
||||
|
||||
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
|
||||
#: ../src/ui/theme.c:5228 ../src/ui/theme.c:5290 ../src/ui/theme.c:5353
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "A(z) „%s” konstans már definiálva van"
|
||||
@@ -972,14 +953,14 @@ msgstr "A logikai értékek „true” vagy „false” kell legyenek, nem pedig
|
||||
msgid "Angle must be between 0.0 and 360.0, was %g\n"
|
||||
msgstr "Szögnek 0.0 és 360.0 között kell lennie, %g volt\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:800
|
||||
#: ../src/ui/theme-parser.c:797
|
||||
#, c-format
|
||||
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
|
||||
msgstr ""
|
||||
"Az alfának 0.0 (átlátszó) és 1.0 (teljesen átlátszatlan) között kell lennie, "
|
||||
"%g volt\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:865
|
||||
#: ../src/ui/theme-parser.c:862
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
|
||||
@@ -988,60 +969,60 @@ msgstr ""
|
||||
" „%s” érvénytelen címméret (lehetséges értékek: xx-small,x-small,small,"
|
||||
"medium,large,x-large,xx-large)\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084
|
||||
#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221
|
||||
#: ../src/ui/theme-parser.c:1018 ../src/ui/theme-parser.c:1081
|
||||
#: ../src/ui/theme-parser.c:1115 ../src/ui/theme-parser.c:1218
|
||||
#, c-format
|
||||
msgid "<%s> name \"%s\" used a second time"
|
||||
msgstr "<%s> „%s” név másodszor lett használva"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130
|
||||
#: ../src/ui/theme-parser.c:1233
|
||||
#: ../src/ui/theme-parser.c:1030 ../src/ui/theme-parser.c:1127
|
||||
#: ../src/ui/theme-parser.c:1230
|
||||
#, c-format
|
||||
msgid "<%s> parent \"%s\" has not been defined"
|
||||
msgstr "<%s> „%s” szülő nincs meghatározva"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1143
|
||||
#: ../src/ui/theme-parser.c:1140
|
||||
#, c-format
|
||||
msgid "<%s> geometry \"%s\" has not been defined"
|
||||
msgstr "<%s> „%s” geometria nincs meghatározva"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1156
|
||||
#: ../src/ui/theme-parser.c:1153
|
||||
#, c-format
|
||||
msgid "<%s> must specify either a geometry or a parent that has a geometry"
|
||||
msgstr ""
|
||||
"<%s> vagy meg kell határozni a geometriát vagy szükség van egy szülőre "
|
||||
"aminek van geometriája"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1198
|
||||
#: ../src/ui/theme-parser.c:1195
|
||||
msgid "You must specify a background for an alpha value to be meaningful"
|
||||
msgstr "Meg kell adnia egy hátteret, hogy az alfa értéknek értelme legyen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1266
|
||||
#: ../src/ui/theme-parser.c:1263
|
||||
#, c-format
|
||||
msgid "Unknown type \"%s\" on <%s> element"
|
||||
msgstr "„%s” típus ismeretlen a(z) <%s> elemen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1277
|
||||
#: ../src/ui/theme-parser.c:1274
|
||||
#, c-format
|
||||
msgid "Unknown style_set \"%s\" on <%s> element"
|
||||
msgstr "„%s” ismeretlen style_set a(z) <%s> elemen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1285
|
||||
#: ../src/ui/theme-parser.c:1282
|
||||
#, c-format
|
||||
msgid "Window type \"%s\" has already been assigned a style set"
|
||||
msgstr "„%s” ablak típushoz már hozzá van rendelve egy stílus beállítás"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379
|
||||
#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840
|
||||
#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036
|
||||
#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310
|
||||
#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386
|
||||
#: ../src/ui/theme-parser.c:1312 ../src/ui/theme-parser.c:1376
|
||||
#: ../src/ui/theme-parser.c:1602 ../src/ui/theme-parser.c:2821
|
||||
#: ../src/ui/theme-parser.c:2867 ../src/ui/theme-parser.c:3017
|
||||
#: ../src/ui/theme-parser.c:3253 ../src/ui/theme-parser.c:3291
|
||||
#: ../src/ui/theme-parser.c:3329 ../src/ui/theme-parser.c:3367
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed below <%s>"
|
||||
msgstr "<%s> elem nem engedélyezett <%s> alatt"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443
|
||||
#: ../src/ui/theme-parser.c:1488
|
||||
#: ../src/ui/theme-parser.c:1426 ../src/ui/theme-parser.c:1440
|
||||
#: ../src/ui/theme-parser.c:1485
|
||||
msgid ""
|
||||
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
|
||||
"for buttons"
|
||||
@@ -1049,125 +1030,125 @@ msgstr ""
|
||||
"Nem lehet egyszerre megadni a gombok „button_width” vagy „button_height” és "
|
||||
"az „aspect_ratio” paraméterét"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1452
|
||||
#: ../src/ui/theme-parser.c:1449
|
||||
#, c-format
|
||||
msgid "Distance \"%s\" is unknown"
|
||||
msgstr "„%s” távolság ismeretlen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1497
|
||||
#: ../src/ui/theme-parser.c:1494
|
||||
#, c-format
|
||||
msgid "Aspect ratio \"%s\" is unknown"
|
||||
msgstr "„%s” méretarány ismeretlen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1559
|
||||
#: ../src/ui/theme-parser.c:1556
|
||||
#, c-format
|
||||
msgid "Border \"%s\" is unknown"
|
||||
msgstr "„%s” határ ismeretlen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1870
|
||||
#: ../src/ui/theme-parser.c:1867
|
||||
#, c-format
|
||||
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
msgstr "A(z) <%s> elemnek nincs „start_angle” vagy „from” attribútuma"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1877
|
||||
#: ../src/ui/theme-parser.c:1874
|
||||
#, c-format
|
||||
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
|
||||
msgstr "A(z) <%s> elemnek nincs „extent_angle” vagy „to” attribútuma"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2117
|
||||
#: ../src/ui/theme-parser.c:2114
|
||||
#, c-format
|
||||
msgid "Did not understand value \"%s\" for type of gradient"
|
||||
msgstr "Nem sikerült „%s” értéket értelmezni színátmenet típusaként"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570
|
||||
#: ../src/ui/theme-parser.c:2189 ../src/ui/theme-parser.c:2551
|
||||
#, c-format
|
||||
msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
msgstr "Nem sikerült a(z) „%s” fájltípust értelmezni a(z) <%s> elem számára"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445
|
||||
#: ../src/ui/theme-parser.c:2508
|
||||
#: ../src/ui/theme-parser.c:2343 ../src/ui/theme-parser.c:2426
|
||||
#: ../src/ui/theme-parser.c:2489
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" for <%s> element"
|
||||
msgstr "Nem sikerült értelmezni a(z) „%s” állapotot a(z) <%s> elem számára"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455
|
||||
#: ../src/ui/theme-parser.c:2353 ../src/ui/theme-parser.c:2436
|
||||
#, c-format
|
||||
msgid "Did not understand shadow \"%s\" for <%s> element"
|
||||
msgstr "Nem sikerült „%s” árnyékot értelmezni a(z) <%s> elem számára"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2382
|
||||
#: ../src/ui/theme-parser.c:2363
|
||||
#, c-format
|
||||
msgid "Did not understand arrow \"%s\" for <%s> element"
|
||||
msgstr "Nem sikerült értelmezni a(z) „%s” nyilat a(z) <%s> elem számára"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792
|
||||
#: ../src/ui/theme-parser.c:2677 ../src/ui/theme-parser.c:2773
|
||||
#, c-format
|
||||
msgid "No <draw_ops> called \"%s\" has been defined"
|
||||
msgstr "Nincsen „%s” nevű <draw_ops> meghatározva"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804
|
||||
#: ../src/ui/theme-parser.c:2689 ../src/ui/theme-parser.c:2785
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr "„%s” draw_ops ide beépítésével körkörös hivatkozás alakulna ki"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2919
|
||||
#: ../src/ui/theme-parser.c:2900
|
||||
#, c-format
|
||||
msgid "Unknown position \"%s\" for frame piece"
|
||||
msgstr "„%s” pozíció ismeretlen a keretdarabhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2927
|
||||
#: ../src/ui/theme-parser.c:2908
|
||||
#, c-format
|
||||
msgid "Frame style already has a piece at position %s"
|
||||
msgstr "A keretstílusnak már van egy darabja a(z) „%s” pozícióban"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021
|
||||
#: ../src/ui/theme-parser.c:2925 ../src/ui/theme-parser.c:3002
|
||||
#, c-format
|
||||
msgid "No <draw_ops> with the name \"%s\" has been defined"
|
||||
msgstr "Nincs „%s” nevű <draw_ops> meghatározva"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2974
|
||||
#: ../src/ui/theme-parser.c:2955
|
||||
#, c-format
|
||||
msgid "Unknown function \"%s\" for button"
|
||||
msgstr "„%s” funkció ismeretlen a gombhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2984
|
||||
#: ../src/ui/theme-parser.c:2965
|
||||
#, c-format
|
||||
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
msgstr ""
|
||||
"A(z) „%s” gombfunkció nem létezik ebben a verzióban (%d, szükséges: %d)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2996
|
||||
#: ../src/ui/theme-parser.c:2977
|
||||
#, c-format
|
||||
msgid "Unknown state \"%s\" for button"
|
||||
msgstr "„%s” állapot ismeretlen a gombhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3004
|
||||
#: ../src/ui/theme-parser.c:2985
|
||||
#, c-format
|
||||
msgid "Frame style already has a button for function %s state %s"
|
||||
msgstr ""
|
||||
"A keretstílusnak már van gombja a(z) „%s” funkcióra a(z) „%s” állapotban"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#: ../src/ui/theme-parser.c:3056
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgstr "„%s” érték érvénytelen a fókusz attribútumhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3084
|
||||
#: ../src/ui/theme-parser.c:3065
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for state attribute"
|
||||
msgstr "„%s” érték érvénytelen az állapot attribútumhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3094
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#, c-format
|
||||
msgid "A style called \"%s\" has not been defined"
|
||||
msgstr "„%s” nevű stílus nincs meghatározva"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138
|
||||
#: ../src/ui/theme-parser.c:3096 ../src/ui/theme-parser.c:3119
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for resize attribute"
|
||||
msgstr "„%s” érték érvénytelen az átméretezés attribútumhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3149
|
||||
#: ../src/ui/theme-parser.c:3130
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
@@ -1176,7 +1157,7 @@ msgstr ""
|
||||
"A(z) <%s> elemnek nem szabadna „resize” attribútummal rendelkeznie a teljes "
|
||||
"méretű/felgördített állapothoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3163
|
||||
#: ../src/ui/theme-parser.c:3144
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized states"
|
||||
@@ -1184,20 +1165,20 @@ msgstr ""
|
||||
"A(z) <%s> elemnek nem szabadna „resize” attribútummal rendelkeznie a teljes "
|
||||
"méretű állapothoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221
|
||||
#: ../src/ui/theme-parser.c:3158 ../src/ui/theme-parser.c:3202
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s resize %s focus %s"
|
||||
msgstr ""
|
||||
"%s állapothoz, %s átméretezéshez és %s fókuszhoz már meg van határozva stílus"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199
|
||||
#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232
|
||||
#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254
|
||||
#: ../src/ui/theme-parser.c:3169 ../src/ui/theme-parser.c:3180
|
||||
#: ../src/ui/theme-parser.c:3191 ../src/ui/theme-parser.c:3213
|
||||
#: ../src/ui/theme-parser.c:3224 ../src/ui/theme-parser.c:3235
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s focus %s"
|
||||
msgstr "%s állapothoz és %s fókuszhoz már meg van határozva stílus"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3293
|
||||
#: ../src/ui/theme-parser.c:3274
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1206,7 +1187,7 @@ msgstr ""
|
||||
"draw_ops attribútumot és egy <draw_ops> elemet, vagy két elemet határozott "
|
||||
"meg)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3331
|
||||
#: ../src/ui/theme-parser.c:3312
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1214,7 +1195,7 @@ msgstr ""
|
||||
"Nem lehet két draw_ops-a egy <button> elemnek (a téma meghatározott egy "
|
||||
"draw_ops attribútumot és egy <draw_ops> elemet, vagy két elemet)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3369
|
||||
#: ../src/ui/theme-parser.c:3350
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
|
||||
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1222,12 +1203,12 @@ msgstr ""
|
||||
"Nem lehet két draw_ops-a egy <menu_icon> elemnek (a téma meghatározott egy "
|
||||
"draw_ops attribútumot és egy <draw_ops> elemet, vagy két elemet)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3433
|
||||
#: ../src/ui/theme-parser.c:3414
|
||||
#, c-format
|
||||
msgid "Bad version specification '%s'"
|
||||
msgstr "Hibás verziómeghatározás: „%s”"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3506
|
||||
#: ../src/ui/theme-parser.c:3487
|
||||
msgid ""
|
||||
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
|
||||
"theme-2.xml"
|
||||
@@ -1235,68 +1216,68 @@ msgstr ""
|
||||
"A „version” attribútum nem használható a metacity-theme-1.xml vagy metacity-"
|
||||
"theme-2.xml fájlban"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3529
|
||||
#: ../src/ui/theme-parser.c:3510
|
||||
#, c-format
|
||||
msgid "Theme requires version %s but latest supported theme version is %d.%d"
|
||||
msgstr ""
|
||||
"A téma a(z) %s verziót igényli, de az utolsó támogatott témaverzió %d.%d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3561
|
||||
#: ../src/ui/theme-parser.c:3542
|
||||
#, c-format
|
||||
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
|
||||
msgstr "A téma legkülső eleme <metacity_theme> kell legyen, nem pedig <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3581
|
||||
#: ../src/ui/theme-parser.c:3562
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a name/author/date/description element"
|
||||
msgstr ""
|
||||
"A(z) <%s> elem nem megengedett egy name/author/date/description elemen belül"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3586
|
||||
#: ../src/ui/theme-parser.c:3567
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <constant> element"
|
||||
msgstr "A(z) <%s> elem nem megengedett egy <constant> elemen belül"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3598
|
||||
#: ../src/ui/theme-parser.c:3579
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
|
||||
msgstr ""
|
||||
"<%s> elem nem megengedett egy distance/border/aspect_ratio elemen belül"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3620
|
||||
#: ../src/ui/theme-parser.c:3601
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a draw operation element"
|
||||
msgstr "<%s> elem nem megengedett egy rajzoló művelet elemen belül"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660
|
||||
#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670
|
||||
#: ../src/ui/theme-parser.c:3611 ../src/ui/theme-parser.c:3641
|
||||
#: ../src/ui/theme-parser.c:3646 ../src/ui/theme-parser.c:3651
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <%s> element"
|
||||
msgstr "<%s> elem nem megengedett egy <%s> elemen belül"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3898
|
||||
#: ../src/ui/theme-parser.c:3879
|
||||
msgid "No draw_ops provided for frame piece"
|
||||
msgstr "Nincsen draw_ops a keretdarabhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3913
|
||||
#: ../src/ui/theme-parser.c:3894
|
||||
msgid "No draw_ops provided for button"
|
||||
msgstr "Nincs draw_ops megadva a gombhoz"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3967
|
||||
#: ../src/ui/theme-parser.c:3948
|
||||
#, c-format
|
||||
msgid "No text is allowed inside element <%s>"
|
||||
msgstr "Nincs szöveg engedélyezve a(z) <%s> elemen belül"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037
|
||||
#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061
|
||||
#: ../src/ui/theme-parser.c:4073
|
||||
#: ../src/ui/theme-parser.c:4006 ../src/ui/theme-parser.c:4018
|
||||
#: ../src/ui/theme-parser.c:4030 ../src/ui/theme-parser.c:4042
|
||||
#: ../src/ui/theme-parser.c:4054
|
||||
#, c-format
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> kétszer lett megadva ehhez a témához"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4335
|
||||
#: ../src/ui/theme-parser.c:4316
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Nem található érvényes fájl a következő témához: %s\n"
|
||||
@@ -1310,11 +1291,14 @@ msgstr ""
|
||||
"mentését", emiatt ezeket a legközelebbi bejelentkezéskor manuálisan "
|
||||
"újra kell indítania."
|
||||
|
||||
#: ../src/x11/window-props.c:515
|
||||
#: ../src/x11/window-props.c:558
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (ezen: %s)"
|
||||
|
||||
#~ msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
#~ msgstr "A(z) %d képernyőnek a(z) „%s” megjelenítőn már van ablakkezelője\n"
|
||||
|
||||
#~ msgid "background texture could not be created from file"
|
||||
#~ msgstr "nem hozható létre a háttér textúrája fájlból"
|
||||
|
||||
|
273
po/nb.po
273
po/nb.po
@@ -4,10 +4,10 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter 3.13.x\n"
|
||||
"Project-Id-Version: mutter 3.15.x\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-09-06 14:13+0200\n"
|
||||
"PO-Revision-Date: 2014-08-23 13:37+0200\n"
|
||||
"POT-Creation-Date: 2014-11-15 18:32+0100\n"
|
||||
"PO-Revision-Date: 2014-11-15 18:34+0100\n"
|
||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
||||
"Language-Team: Norwegian bokmål <i18n-no@lister.ping.uio.no>\n"
|
||||
"Language: \n"
|
||||
@@ -351,7 +351,7 @@ msgid ""
|
||||
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
msgstr ""
|
||||
msgstr "Hvis denne settes til «true» og fokusmodus er enten «sloppy» eller «mouse» så vil fokus ikke endres med en gang markøren kommer inn i et vindu, men i stedet når markørens bevegelse stopper."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
|
||||
msgid "Draggable border width"
|
||||
@@ -385,7 +385,7 @@ msgstr "Plasser nye vinduer i senter"
|
||||
msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
msgstr ""
|
||||
msgstr "Når denne er «true» vil mye vinduer alltid plasseres midt på aktivt område på skjermen."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
|
||||
msgid "Select window from tab popup"
|
||||
@@ -423,29 +423,29 @@ msgstr "Bytt til VT 6"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Bytt til VT 7"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:412
|
||||
#: ../src/backends/meta-monitor-manager.c:350
|
||||
msgid "Built-in display"
|
||||
msgstr "Innebygget skjerm"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:437
|
||||
#: ../src/backends/meta-monitor-manager.c:375
|
||||
msgid "Unknown"
|
||||
msgstr "Ukjent"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:439
|
||||
#: ../src/backends/meta-monitor-manager.c:377
|
||||
msgid "Unknown Display"
|
||||
msgstr "Ukjent skjerm"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:447
|
||||
#: ../src/backends/meta-monitor-manager.c:385
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:443
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -481,7 +481,7 @@ msgstr "_Vent"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Tvungen nedstenging"
|
||||
|
||||
#: ../src/core/display.c:547
|
||||
#: ../src/core/display.c:550
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Feil under åpning av X Window System skjerm «%s»\n"
|
||||
@@ -518,12 +518,12 @@ msgstr "Kjør som en wayland-kompositør"
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Kjør som en full skjermtjener, heller enn nøstet"
|
||||
|
||||
#: ../src/core/main.c:459
|
||||
#: ../src/core/main.c:451
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Feil under søk i temakatalog: %s\n"
|
||||
|
||||
#: ../src/core/main.c:475
|
||||
#: ../src/core/main.c:467
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -553,17 +553,17 @@ msgstr "Skriv versjonsnummer"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Mutter-tillegg som skal brukes"
|
||||
|
||||
#: ../src/core/prefs.c:2101
|
||||
#: ../src/core/prefs.c:2064
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Arbeidsområde %d"
|
||||
|
||||
#: ../src/core/screen.c:548
|
||||
#: ../src/core/screen.c:543
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Skjerm %d på display «%s» er ugyldig\n"
|
||||
|
||||
#: ../src/core/screen.c:564
|
||||
#: ../src/core/screen.c:559
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -572,7 +572,7 @@ msgstr ""
|
||||
"Skjerm %d på display «%s» har allerede en vindushåndterer; prøv å bruke "
|
||||
"flagget --replace for å erstatte aktiv vindushåndterer.\n"
|
||||
|
||||
#: ../src/core/screen.c:657
|
||||
#: ../src/core/screen.c:652
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Skjerm %d på display «%s» har allerede en vinduhåndterer\n"
|
||||
@@ -589,48 +589,48 @@ msgstr "Mutter er kompilert uten støtte for «verbose» modus\n"
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:233
|
||||
#: ../src/ui/theme.c:154
|
||||
msgid "top"
|
||||
msgstr "topp"
|
||||
|
||||
#: ../src/ui/theme.c:235
|
||||
#: ../src/ui/theme.c:156
|
||||
msgid "bottom"
|
||||
msgstr "bunn"
|
||||
|
||||
#: ../src/ui/theme.c:237
|
||||
#: ../src/ui/theme.c:158
|
||||
msgid "left"
|
||||
msgstr "venstre"
|
||||
|
||||
#: ../src/ui/theme.c:239
|
||||
#: ../src/ui/theme.c:160
|
||||
msgid "right"
|
||||
msgstr "høyre"
|
||||
|
||||
#: ../src/ui/theme.c:267
|
||||
#: ../src/ui/theme.c:188
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "rammegeometrien spesifiserer ikke «%s»-dimensjon"
|
||||
|
||||
#: ../src/ui/theme.c:286
|
||||
#: ../src/ui/theme.c:207
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr "rammegeometri spesifiserer ikke dimensjon «%s» for kant «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:323
|
||||
#: ../src/ui/theme.c:244
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "Aspektrate %g for knapp er ikke fornuftig"
|
||||
|
||||
#: ../src/ui/theme.c:335
|
||||
#: ../src/ui/theme.c:256
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "Rammegeometrien spesifiserer ikke størrelse på knapper"
|
||||
|
||||
#: ../src/ui/theme.c:1061
|
||||
#: ../src/ui/theme.c:1024
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "Gradienter må ha minst to farger"
|
||||
|
||||
#: ../src/ui/theme.c:1211
|
||||
#: ../src/ui/theme.c:1174
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
@@ -639,7 +639,7 @@ msgstr ""
|
||||
"Egendefinert GTK-fargespesifikasjon må ha fargenavn og reserve i parantes, f."
|
||||
"eks gtk:custom(foo,bar); kunne ikke lese «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1227
|
||||
#: ../src/ui/theme.c:1190
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
@@ -648,7 +648,7 @@ msgstr ""
|
||||
"Ugyldig tegn «%c» i parameter color_name for gtk:custom, kun A-Za-z0-9-_ er "
|
||||
"gyldig"
|
||||
|
||||
#: ../src/ui/theme.c:1241
|
||||
#: ../src/ui/theme.c:1204
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
@@ -657,7 +657,7 @@ msgstr ""
|
||||
"Gtk:custom-format er «gtk:custom(color_name,fallback)», «%s» passer ikke i "
|
||||
"formatet"
|
||||
|
||||
#: ../src/ui/theme.c:1286
|
||||
#: ../src/ui/theme.c:1249
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
@@ -666,7 +666,7 @@ msgstr ""
|
||||
"GTK-fargespesifikasjon må ha tilstand i klammer, f.eks. gtk:fg[NORMAL], hvor "
|
||||
"NORMAL er tilstanden; kunne ikke lese «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1300
|
||||
#: ../src/ui/theme.c:1263
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
@@ -675,17 +675,17 @@ msgstr ""
|
||||
"GTK-fargespesifikasjon må ha en avsluttende klamme etter tilstanden, f.eks. "
|
||||
"gtk:fg[NORMAL], hvor NORMAL er tilstanden; kunne ikke lese «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1311
|
||||
#: ../src/ui/theme.c:1274
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "Forsto ikke tilstand «%s» i fargespesifikasjonen"
|
||||
|
||||
#: ../src/ui/theme.c:1324
|
||||
#: ../src/ui/theme.c:1287
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "Forsto ikke fargekomponent «%s» i fargespesifikasjonen"
|
||||
|
||||
#: ../src/ui/theme.c:1352
|
||||
#: ../src/ui/theme.c:1315
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
@@ -694,56 +694,56 @@ msgstr ""
|
||||
"Blandingsformat er «blend/bg_color/fg_color/alpha», «%s» passer ikke i "
|
||||
"formatet"
|
||||
|
||||
#: ../src/ui/theme.c:1363
|
||||
#: ../src/ui/theme.c:1326
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Kunne ikke lese alpha-verdi «%s» i blandet farge"
|
||||
|
||||
#: ../src/ui/theme.c:1373
|
||||
#: ../src/ui/theme.c:1336
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr "Alpha-verdi «%s» i blandet farge er ikke mellom 0.0 og 1.0"
|
||||
|
||||
#: ../src/ui/theme.c:1419
|
||||
#: ../src/ui/theme.c:1382
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
msgstr ""
|
||||
"Skyggeformatet er «shade/base_color/factor», «%s» passer ikke i formatet"
|
||||
|
||||
#: ../src/ui/theme.c:1430
|
||||
#: ../src/ui/theme.c:1393
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "Kunne ikke lese skyggefaktor «%s» i skyggelagt farge"
|
||||
|
||||
#: ../src/ui/theme.c:1440
|
||||
#: ../src/ui/theme.c:1403
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "Skyggefaktor «%s» i skyggelagt farge er negativ"
|
||||
|
||||
#: ../src/ui/theme.c:1469
|
||||
#: ../src/ui/theme.c:1432
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Kunne ikke lese farge «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1778
|
||||
#: ../src/ui/theme.c:1741
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr "Koordinatuttrykk inneholder tegn «%s» som ikke er tillatt"
|
||||
|
||||
#: ../src/ui/theme.c:1805
|
||||
#: ../src/ui/theme.c:1768
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
"parsed"
|
||||
msgstr "Koordinatuttrykk inneholder flyttall «%s» som ikke kunne tolkes"
|
||||
|
||||
#: ../src/ui/theme.c:1819
|
||||
#: ../src/ui/theme.c:1782
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr "Koordinatuttrykk inneholder heltall «%s» som ikke kunne tolkes"
|
||||
|
||||
#: ../src/ui/theme.c:1940
|
||||
#: ../src/ui/theme.c:1903
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
@@ -752,39 +752,39 @@ msgstr ""
|
||||
"Koordinatuttrykket inneholdt en ukjent operator ved begynnelsen av denne "
|
||||
"teksten: «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1997
|
||||
#: ../src/ui/theme.c:1960
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "Koordinatuttrykket var tomt eller ble ikke forstått"
|
||||
|
||||
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
|
||||
#: ../src/ui/theme.c:2073 ../src/ui/theme.c:2083 ../src/ui/theme.c:2117
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "Koordinatuttrykket resulterer i divisjon med null"
|
||||
|
||||
#: ../src/ui/theme.c:2162
|
||||
#: ../src/ui/theme.c:2125
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
msgstr "Koordinatuttrykket prøver å bruke mod-operator på et flyttall"
|
||||
|
||||
#: ../src/ui/theme.c:2218
|
||||
#: ../src/ui/theme.c:2181
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr "Koordinatuttrykket har en operator «%s» hvor en operand var ventet"
|
||||
|
||||
#: ../src/ui/theme.c:2227
|
||||
#: ../src/ui/theme.c:2190
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr "Koordinatuttrykket hadde en operand hvor en operator var ventet"
|
||||
|
||||
#: ../src/ui/theme.c:2235
|
||||
#: ../src/ui/theme.c:2198
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr "Koordinatuttrykket sluttet med en operator i stedet for en operand"
|
||||
|
||||
#: ../src/ui/theme.c:2245
|
||||
#: ../src/ui/theme.c:2208
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
@@ -793,38 +793,38 @@ msgstr ""
|
||||
"Koordinatuttrykket har en operator «%c» etter en operator «%c» og ingen "
|
||||
"operand mellom dem."
|
||||
|
||||
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
|
||||
#: ../src/ui/theme.c:2359 ../src/ui/theme.c:2404
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr "Koordinatuttrykket haddeen ukjent variabel eller konstant «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:2495
|
||||
#: ../src/ui/theme.c:2458
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "Tolkeren for koordinatuttrykk oversteg buffergrensen."
|
||||
|
||||
#: ../src/ui/theme.c:2524
|
||||
#: ../src/ui/theme.c:2487
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr "Koordinatuttrykket hadde en parantes slutt uten parantes start"
|
||||
|
||||
#: ../src/ui/theme.c:2588
|
||||
#: ../src/ui/theme.c:2551
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr "Koordinatuttrykket hadde en åpen parantes uten en avsluttende parantes"
|
||||
|
||||
#: ../src/ui/theme.c:2599
|
||||
#: ../src/ui/theme.c:2562
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr ""
|
||||
"Koordinatuttrykket ser ikke ut til å ha noen operatorer eller operander"
|
||||
|
||||
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
|
||||
#: ../src/ui/theme.c:2775 ../src/ui/theme.c:2795 ../src/ui/theme.c:2815
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "Tema inneholdt et uttrykk som resulterte i en feil: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4455
|
||||
#: ../src/ui/theme.c:4055
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
@@ -833,25 +833,25 @@ msgstr ""
|
||||
"<button function=«%s» state=«%s» draw_ops=«ett-eller-annet»/> må "
|
||||
"spesifiseres for denne rammestilen"
|
||||
|
||||
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
|
||||
#: ../src/ui/theme.c:4570 ../src/ui/theme.c:4595
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr ""
|
||||
"Mangler <frame state=«%s» resize=«%s» focus=«%s» stil=«ett-eller-annet»/>"
|
||||
|
||||
#: ../src/ui/theme.c:5041
|
||||
#: ../src/ui/theme.c:4641
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Klarte ikke å laste tema «%s»: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
|
||||
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
|
||||
#: ../src/ui/theme.c:4777 ../src/ui/theme.c:4784 ../src/ui/theme.c:4791
|
||||
#: ../src/ui/theme.c:4798 ../src/ui/theme.c:4805
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "<%s> er ikke satt for tema «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:5213
|
||||
#: ../src/ui/theme.c:4813
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -860,14 +860,14 @@ msgstr ""
|
||||
"Ingen rammestil satt for vindutype «%s» i tema «%s», legg til et <window "
|
||||
"type=«%s» style_set=«ett-eller-annet»/>-element"
|
||||
|
||||
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
|
||||
#: ../src/ui/theme.c:5220 ../src/ui/theme.c:5282 ../src/ui/theme.c:5345
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
msgstr ""
|
||||
"Brukerdefinerte konstanter må begynne med stor bokstav; «%s» gjør ikke det"
|
||||
|
||||
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
|
||||
#: ../src/ui/theme.c:5228 ../src/ui/theme.c:5290 ../src/ui/theme.c:5353
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "Konstant «%s» er allerede definert"
|
||||
@@ -930,13 +930,13 @@ msgstr "Bolske verdier må være «sann» eller «usann» ikke «%s»"
|
||||
msgid "Angle must be between 0.0 and 360.0, was %g\n"
|
||||
msgstr "Vinkelen må være mellom 0.0 og 360.0, var %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:800
|
||||
#: ../src/ui/theme-parser.c:797
|
||||
#, c-format
|
||||
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
|
||||
msgstr ""
|
||||
"Alpha må være mellom 0.0 (usynlig) og 1.0 (helt ugjennomsiktig), var %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:865
|
||||
#: ../src/ui/theme-parser.c:862
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
|
||||
@@ -945,58 +945,58 @@ msgstr ""
|
||||
"Ugyldig skalering av tittel «%s» (må være en av xx-small,x-small,small,"
|
||||
"medium,large,x-large,xx-large)\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084
|
||||
#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221
|
||||
#: ../src/ui/theme-parser.c:1018 ../src/ui/theme-parser.c:1081
|
||||
#: ../src/ui/theme-parser.c:1115 ../src/ui/theme-parser.c:1218
|
||||
#, c-format
|
||||
msgid "<%s> name \"%s\" used a second time"
|
||||
msgstr "<%s> navn «%s» brukt på nytt"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130
|
||||
#: ../src/ui/theme-parser.c:1233
|
||||
#: ../src/ui/theme-parser.c:1030 ../src/ui/theme-parser.c:1127
|
||||
#: ../src/ui/theme-parser.c:1230
|
||||
#, c-format
|
||||
msgid "<%s> parent \"%s\" has not been defined"
|
||||
msgstr "<%s> opphav «%s» er ikke definert"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1143
|
||||
#: ../src/ui/theme-parser.c:1140
|
||||
#, c-format
|
||||
msgid "<%s> geometry \"%s\" has not been defined"
|
||||
msgstr "<%s> geometri «%s» er ikke definert"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1156
|
||||
#: ../src/ui/theme-parser.c:1153
|
||||
#, c-format
|
||||
msgid "<%s> must specify either a geometry or a parent that has a geometry"
|
||||
msgstr "<%s> må spesifisere enten en geometri eller et opphav som har geometri"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1198
|
||||
#: ../src/ui/theme-parser.c:1195
|
||||
msgid "You must specify a background for an alpha value to be meaningful"
|
||||
msgstr "Du må oppgi en bakgrunn for at en alpha-verdi skal ha mening"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1266
|
||||
#: ../src/ui/theme-parser.c:1263
|
||||
#, c-format
|
||||
msgid "Unknown type \"%s\" on <%s> element"
|
||||
msgstr "Ukjent type «%s» på <%s>-element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1277
|
||||
#: ../src/ui/theme-parser.c:1274
|
||||
#, c-format
|
||||
msgid "Unknown style_set \"%s\" on <%s> element"
|
||||
msgstr "Ukjent style_set «%s» på <%s>-element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1285
|
||||
#: ../src/ui/theme-parser.c:1282
|
||||
#, c-format
|
||||
msgid "Window type \"%s\" has already been assigned a style set"
|
||||
msgstr "Vindutype «%s» er allerede tildelt et stilsett"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379
|
||||
#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840
|
||||
#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036
|
||||
#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310
|
||||
#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386
|
||||
#: ../src/ui/theme-parser.c:1312 ../src/ui/theme-parser.c:1376
|
||||
#: ../src/ui/theme-parser.c:1602 ../src/ui/theme-parser.c:2821
|
||||
#: ../src/ui/theme-parser.c:2867 ../src/ui/theme-parser.c:3017
|
||||
#: ../src/ui/theme-parser.c:3253 ../src/ui/theme-parser.c:3291
|
||||
#: ../src/ui/theme-parser.c:3329 ../src/ui/theme-parser.c:3367
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed below <%s>"
|
||||
msgstr "Element <%s> er ikke tillatt under <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443
|
||||
#: ../src/ui/theme-parser.c:1488
|
||||
#: ../src/ui/theme-parser.c:1426 ../src/ui/theme-parser.c:1440
|
||||
#: ../src/ui/theme-parser.c:1485
|
||||
msgid ""
|
||||
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
|
||||
"for buttons"
|
||||
@@ -1004,123 +1004,123 @@ msgstr ""
|
||||
"Kan ikke spesifisere både «button_width»/«button_height» og «aspect_ratio» "
|
||||
"for knapper"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1452
|
||||
#: ../src/ui/theme-parser.c:1449
|
||||
#, c-format
|
||||
msgid "Distance \"%s\" is unknown"
|
||||
msgstr "Avstand «%s» er ukjent"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1497
|
||||
#: ../src/ui/theme-parser.c:1494
|
||||
#, c-format
|
||||
msgid "Aspect ratio \"%s\" is unknown"
|
||||
msgstr "Aspektrate «%s» er ukjent"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1559
|
||||
#: ../src/ui/theme-parser.c:1556
|
||||
#, c-format
|
||||
msgid "Border \"%s\" is unknown"
|
||||
msgstr "Grense «%s» er ukjent"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1870
|
||||
#: ../src/ui/theme-parser.c:1867
|
||||
#, c-format
|
||||
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
msgstr "Ingen «start_angle» eller «from»-attributt på element <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1877
|
||||
#: ../src/ui/theme-parser.c:1874
|
||||
#, c-format
|
||||
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
|
||||
msgstr "Ingen «extent_angle» eller «to»-attributt <%s>-element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2117
|
||||
#: ../src/ui/theme-parser.c:2114
|
||||
#, c-format
|
||||
msgid "Did not understand value \"%s\" for type of gradient"
|
||||
msgstr "Forsto ikke verdi «%s» for gradienttype"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570
|
||||
#: ../src/ui/theme-parser.c:2189 ../src/ui/theme-parser.c:2551
|
||||
#, c-format
|
||||
msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
msgstr "Forsto ikke fyll-type «%s» for <%s>-element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445
|
||||
#: ../src/ui/theme-parser.c:2508
|
||||
#: ../src/ui/theme-parser.c:2343 ../src/ui/theme-parser.c:2426
|
||||
#: ../src/ui/theme-parser.c:2489
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" for <%s> element"
|
||||
msgstr "Forsto ikke tilstand «%s» for element <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455
|
||||
#: ../src/ui/theme-parser.c:2353 ../src/ui/theme-parser.c:2436
|
||||
#, c-format
|
||||
msgid "Did not understand shadow \"%s\" for <%s> element"
|
||||
msgstr "Forsto ikke skygge «%s» for element <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2382
|
||||
#: ../src/ui/theme-parser.c:2363
|
||||
#, c-format
|
||||
msgid "Did not understand arrow \"%s\" for <%s> element"
|
||||
msgstr "Forsto ikke pil «%s» for element <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792
|
||||
#: ../src/ui/theme-parser.c:2677 ../src/ui/theme-parser.c:2773
|
||||
#, c-format
|
||||
msgid "No <draw_ops> called \"%s\" has been defined"
|
||||
msgstr "Ingen <draw_ops> kalt «%s» er definert"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804
|
||||
#: ../src/ui/theme-parser.c:2689 ../src/ui/theme-parser.c:2785
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr "Hvis du tar med draw_ops «%s» her vil dette lage en sirkulær referanse"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2919
|
||||
#: ../src/ui/theme-parser.c:2900
|
||||
#, c-format
|
||||
msgid "Unknown position \"%s\" for frame piece"
|
||||
msgstr "Ukjent posisjon «%s» for rammesdel"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2927
|
||||
#: ../src/ui/theme-parser.c:2908
|
||||
#, c-format
|
||||
msgid "Frame style already has a piece at position %s"
|
||||
msgstr "Rammestil har allerede en del i posisjon %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021
|
||||
#: ../src/ui/theme-parser.c:2925 ../src/ui/theme-parser.c:3002
|
||||
#, c-format
|
||||
msgid "No <draw_ops> with the name \"%s\" has been defined"
|
||||
msgstr "Ingen <draw_ops> med navn «%s» er definert"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2974
|
||||
#: ../src/ui/theme-parser.c:2955
|
||||
#, c-format
|
||||
msgid "Unknown function \"%s\" for button"
|
||||
msgstr "Ukjent funksjon «%s» for knapp"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2984
|
||||
#: ../src/ui/theme-parser.c:2965
|
||||
#, c-format
|
||||
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
msgstr "Knappefunksjon «%s» eksisterer ikke i denne versjonen (%d, trenger %d)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2996
|
||||
#: ../src/ui/theme-parser.c:2977
|
||||
#, c-format
|
||||
msgid "Unknown state \"%s\" for button"
|
||||
msgstr "Ukjent tilstand «%s» for knapp"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3004
|
||||
#: ../src/ui/theme-parser.c:2985
|
||||
#, c-format
|
||||
msgid "Frame style already has a button for function %s state %s"
|
||||
msgstr "Rammestil har allerede en knapp for funksjon %s tilstand %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#: ../src/ui/theme-parser.c:3056
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgstr "«%s» er ikke en gyldig verdi for fokusattributt"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3084
|
||||
#: ../src/ui/theme-parser.c:3065
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for state attribute"
|
||||
msgstr "«%s» er ikke en gyldig verdi for tilstandsattributt"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3094
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#, c-format
|
||||
msgid "A style called \"%s\" has not been defined"
|
||||
msgstr "En stil med navn «%s» er ikke definert"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138
|
||||
#: ../src/ui/theme-parser.c:3096 ../src/ui/theme-parser.c:3119
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for resize attribute"
|
||||
msgstr "«%s» er ikke en gyldig verdi for attributt for endring av størrelse"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3149
|
||||
#: ../src/ui/theme-parser.c:3130
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
@@ -1129,27 +1129,27 @@ msgstr ""
|
||||
"Skal ikke være noen «resize»-attributt på <%s>-element for maksimert/"
|
||||
"skyggelagt tilstand"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3163
|
||||
#: ../src/ui/theme-parser.c:3144
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized states"
|
||||
msgstr ""
|
||||
"Skal ikke være noen «resize»-attributt på <%s>-element for maksimert tilstand"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221
|
||||
#: ../src/ui/theme-parser.c:3158 ../src/ui/theme-parser.c:3202
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s resize %s focus %s"
|
||||
msgstr ""
|
||||
"Stil er allerede spesifisert for tilstand %s størrelsesendring %s fokus %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199
|
||||
#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232
|
||||
#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254
|
||||
#: ../src/ui/theme-parser.c:3169 ../src/ui/theme-parser.c:3180
|
||||
#: ../src/ui/theme-parser.c:3191 ../src/ui/theme-parser.c:3213
|
||||
#: ../src/ui/theme-parser.c:3224 ../src/ui/theme-parser.c:3235
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s focus %s"
|
||||
msgstr "Stil er allerede spesifisert for tilstand %s fokus %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3293
|
||||
#: ../src/ui/theme-parser.c:3274
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1158,7 +1158,7 @@ msgstr ""
|
||||
"draw_ops-attributt i tillegg til et <draw_ops>-element, eller så "
|
||||
"spesifiserte det to elementer)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3331
|
||||
#: ../src/ui/theme-parser.c:3312
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1167,7 +1167,7 @@ msgstr ""
|
||||
"draw_ops-attributt i tillegg til et <draw_ops>-element, eller det "
|
||||
"spesifiserte to elementer)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3369
|
||||
#: ../src/ui/theme-parser.c:3350
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
|
||||
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1176,12 +1176,12 @@ msgstr ""
|
||||
"draw_ops-attributt i tillegg til et <draw_ops>-element, eller det "
|
||||
"spesifiserte to elementer)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3433
|
||||
#: ../src/ui/theme-parser.c:3414
|
||||
#, c-format
|
||||
msgid "Bad version specification '%s'"
|
||||
msgstr "Ugyldig versjonspesifikasjon «%s»"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3506
|
||||
#: ../src/ui/theme-parser.c:3487
|
||||
msgid ""
|
||||
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
|
||||
"theme-2.xml"
|
||||
@@ -1189,66 +1189,66 @@ msgstr ""
|
||||
"«version»-attributt kan ikke brukes i metacity-theme-1.xml eller metacity-"
|
||||
"theme-2.xml"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3529
|
||||
#: ../src/ui/theme-parser.c:3510
|
||||
#, c-format
|
||||
msgid "Theme requires version %s but latest supported theme version is %d.%d"
|
||||
msgstr "Tema krever versjon %s men siste støttede temaversjon er %d.%d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3561
|
||||
#: ../src/ui/theme-parser.c:3542
|
||||
#, c-format
|
||||
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
|
||||
msgstr "Ytterste element i temaet må være <metacity_theme> ikke <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3581
|
||||
#: ../src/ui/theme-parser.c:3562
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a name/author/date/description element"
|
||||
msgstr ""
|
||||
"Element <%s> er ikke tillatt inne i et name/author/date/description element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3586
|
||||
#: ../src/ui/theme-parser.c:3567
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <constant> element"
|
||||
msgstr "Element <%s> er ikke tillatt inne i et <constand> element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3598
|
||||
#: ../src/ui/theme-parser.c:3579
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
|
||||
msgstr "Element <%s> er ikke tillatt inne i et avstand/kant/aspektrate-element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3620
|
||||
#: ../src/ui/theme-parser.c:3601
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a draw operation element"
|
||||
msgstr "Element <%s> er ikke tillatt inne i et element for tegneoperasjon"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660
|
||||
#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670
|
||||
#: ../src/ui/theme-parser.c:3611 ../src/ui/theme-parser.c:3641
|
||||
#: ../src/ui/theme-parser.c:3646 ../src/ui/theme-parser.c:3651
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <%s> element"
|
||||
msgstr "Element <%s> er ikke tillatt inne i et <%s>-element"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3898
|
||||
#: ../src/ui/theme-parser.c:3879
|
||||
msgid "No draw_ops provided for frame piece"
|
||||
msgstr "Ingen draw_ops tilbys for rammedelen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3913
|
||||
#: ../src/ui/theme-parser.c:3894
|
||||
msgid "No draw_ops provided for button"
|
||||
msgstr "Ingen draw_ops tilbys for knappen"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3967
|
||||
#: ../src/ui/theme-parser.c:3948
|
||||
#, c-format
|
||||
msgid "No text is allowed inside element <%s>"
|
||||
msgstr "Ingen tekst er tillatt inne i element <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037
|
||||
#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061
|
||||
#: ../src/ui/theme-parser.c:4073
|
||||
#: ../src/ui/theme-parser.c:4006 ../src/ui/theme-parser.c:4018
|
||||
#: ../src/ui/theme-parser.c:4030 ../src/ui/theme-parser.c:4042
|
||||
#: ../src/ui/theme-parser.c:4054
|
||||
#, c-format
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> spesifisert to ganger for dette temaet"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4335
|
||||
#: ../src/ui/theme-parser.c:4316
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Fant ikke en gyldig fil for tema %s\n"
|
||||
@@ -1261,10 +1261,7 @@ msgstr ""
|
||||
"Disse vinduene støtter ikke "lagre aktiv konfigurasjon"og vil "
|
||||
"måtte startes på nytt manuelt neste gang du logger inn."
|
||||
|
||||
#: ../src/x11/window-props.c:515
|
||||
#: ../src/x11/window-props.c:558
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (på %s)"
|
||||
|
||||
#~ msgid "background texture could not be created from file"
|
||||
#~ msgstr "bakgrunnstekstur kunne ikke lages fra fil"
|
||||
|
1264
po/pt_BR.po
1264
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@ lib_LTLIBRARIES = libmutter.la
|
||||
SUBDIRS=compositor/plugins
|
||||
|
||||
EXTRA_DIST =
|
||||
NULL =
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DCLUTTER_ENABLE_COMPOSITOR_API \
|
||||
@@ -31,31 +32,37 @@ AM_CPPFLAGS = \
|
||||
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\" \
|
||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
|
||||
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"
|
||||
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\" \
|
||||
$(NULL)
|
||||
|
||||
mutter_built_sources = \
|
||||
$(dbus_idle_built_sources) \
|
||||
$(dbus_display_config_built_sources) \
|
||||
$(dbus_login1_built_sources) \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c
|
||||
mutter-enum-types.c \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_WAYLAND
|
||||
mutter_built_sources += \
|
||||
gtk-shell-protocol.c \
|
||||
gtk-shell-server-protocol.h \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-server-protocol.h
|
||||
xdg-shell-server-protocol.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
wayland_protocols = \
|
||||
wayland_protocols = \
|
||||
wayland/protocol/gtk-shell.xml \
|
||||
wayland/protocol/xdg-shell.xml
|
||||
wayland/protocol/xdg-shell.xml \
|
||||
$(NULL)
|
||||
|
||||
libmutter_la_SOURCES = \
|
||||
backends/meta-backend.c \
|
||||
meta/meta-backend.h \
|
||||
backends/meta-backend-private.h \
|
||||
backends/meta-barrier.c \
|
||||
backends/meta-barrier-private.h \
|
||||
backends/meta-cursor.c \
|
||||
backends/meta-cursor.h \
|
||||
backends/meta-cursor-private.h \
|
||||
@@ -68,10 +75,13 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-idle-monitor-private.h \
|
||||
backends/meta-idle-monitor-dbus.c \
|
||||
backends/meta-idle-monitor-dbus.h \
|
||||
backends/meta-input-settings.c \
|
||||
backends/meta-input-settings-private.h \
|
||||
backends/meta-monitor-config.c \
|
||||
backends/meta-monitor-config.h \
|
||||
backends/meta-monitor-manager.c \
|
||||
backends/meta-monitor-manager.h \
|
||||
meta/meta-monitor-manager.h \
|
||||
backends/meta-monitor-manager-private.h \
|
||||
backends/meta-monitor-manager-dummy.c \
|
||||
backends/meta-monitor-manager-dummy.h \
|
||||
backends/meta-stage.h \
|
||||
@@ -80,15 +90,18 @@ libmutter_la_SOURCES = \
|
||||
backends/edid.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-x11.h \
|
||||
backends/x11/meta-barrier-x11.c \
|
||||
backends/x11/meta-barrier-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
backends/x11/meta-cursor-renderer-x11.h \
|
||||
backends/x11/meta-idle-monitor-xsync.c \
|
||||
backends/x11/meta-idle-monitor-xsync.h \
|
||||
backends/x11/meta-input-settings-x11.c \
|
||||
backends/x11/meta-input-settings-x11.h \
|
||||
backends/x11/meta-monitor-manager-xrandr.c \
|
||||
backends/x11/meta-monitor-manager-xrandr.h \
|
||||
core/meta-accel-parse.c \
|
||||
core/meta-accel-parse.h \
|
||||
core/barrier.c \
|
||||
meta/barrier.h \
|
||||
core/bell.c \
|
||||
core/bell.h \
|
||||
@@ -193,9 +206,6 @@ libmutter_la_SOURCES = \
|
||||
ui/ui.h \
|
||||
ui/frames.c \
|
||||
ui/frames.h \
|
||||
ui/resizepopup.c \
|
||||
ui/resizepopup.h \
|
||||
ui/theme-parser.c \
|
||||
ui/theme.c \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
@@ -220,7 +230,8 @@ libmutter_la_SOURCES = \
|
||||
x11/window-x11-private.h \
|
||||
x11/xprops.c \
|
||||
x11/xprops.h \
|
||||
x11/mutter-Xatomtype.h
|
||||
x11/mutter-Xatomtype.h \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_WAYLAND
|
||||
libmutter_la_SOURCES += \
|
||||
@@ -242,6 +253,8 @@ libmutter_la_SOURCES += \
|
||||
wayland/meta-wayland-keyboard.h \
|
||||
wayland/meta-wayland-pointer.c \
|
||||
wayland/meta-wayland-pointer.h \
|
||||
wayland/meta-wayland-popup.c \
|
||||
wayland/meta-wayland-popup.h \
|
||||
wayland/meta-wayland-seat.c \
|
||||
wayland/meta-wayland-seat.h \
|
||||
wayland/meta-wayland-touch.c \
|
||||
@@ -253,29 +266,35 @@ libmutter_la_SOURCES += \
|
||||
wayland/meta-wayland-outputs.c \
|
||||
wayland/meta-wayland-outputs.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
wayland/window-wayland.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
if HAVE_NATIVE_BACKEND
|
||||
libmutter_la_SOURCES += \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-backend-native-private.h \
|
||||
backends/native/meta-barrier-native.c \
|
||||
backends/native/meta-barrier-native.h \
|
||||
backends/native/meta-cursor-renderer-native.c \
|
||||
backends/native/meta-cursor-renderer-native.h \
|
||||
backends/native/meta-idle-monitor-native.c \
|
||||
backends/native/meta-idle-monitor-native.h \
|
||||
backends/native/meta-input-settings-native.c \
|
||||
backends/native/meta-input-settings-native.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/native/dbus-utils.c \
|
||||
backends/native/dbus-utils.h
|
||||
backends/native/dbus-utils.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
nodist_libmutter_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
nodist_libmutter_la_SOURCES = $(mutter_built_sources)
|
||||
|
||||
libmutter_la_LDFLAGS = -no-undefined
|
||||
libmutter_la_LDFLAGS = -no-undefined -export-symbols-regex "^(meta|ag)_.*"
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
|
||||
|
||||
# Headers installed for plugins; introspected information will
|
||||
@@ -299,6 +318,7 @@ libmutterinclude_headers = \
|
||||
meta/meta-cursor-tracker.h \
|
||||
meta/meta-idle-monitor.h \
|
||||
meta/meta-plugin.h \
|
||||
meta/meta-monitor-manager.h \
|
||||
meta/meta-shaped-texture.h \
|
||||
meta/meta-shadow-factory.h \
|
||||
meta/meta-window-actor.h \
|
||||
@@ -308,7 +328,8 @@ libmutterinclude_headers = \
|
||||
meta/types.h \
|
||||
meta/util.h \
|
||||
meta/window.h \
|
||||
meta/workspace.h
|
||||
meta/workspace.h \
|
||||
$(NULL)
|
||||
|
||||
libmutterinclude_built_headers = \
|
||||
meta/meta-version.h
|
||||
@@ -389,14 +410,15 @@ DISTCLEANFILES = \
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libmutter.pc
|
||||
|
||||
EXTRA_DIST += \
|
||||
$(wayland_protocols) \
|
||||
libmutter.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
org.freedesktop.login1.xml \
|
||||
EXTRA_DIST += \
|
||||
$(wayland_protocols) \
|
||||
libmutter.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
org.freedesktop.login1.xml \
|
||||
org.gnome.Mutter.DisplayConfig.xml \
|
||||
org.gnome.Mutter.IdleMonitor.xml
|
||||
org.gnome.Mutter.IdleMonitor.xml \
|
||||
$(NULL)
|
||||
|
||||
BUILT_SOURCES = \
|
||||
$(mutter_built_sources) \
|
||||
|
@@ -33,7 +33,7 @@
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define DEFAULT_XKB_RULES_FILE "evdev"
|
||||
#define DEFAULT_XKB_MODEL "pc105+inet"
|
||||
@@ -49,8 +49,7 @@ struct _MetaBackend
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaIdleMonitor *device_monitors[256];
|
||||
int device_id_max;
|
||||
GHashTable *device_monitors;
|
||||
};
|
||||
|
||||
struct _MetaBackendClass
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-input-settings-private.h"
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
@@ -34,6 +35,10 @@
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
|
||||
static MetaBackend *_backend;
|
||||
|
||||
/**
|
||||
@@ -53,6 +58,7 @@ struct _MetaBackendPrivate
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
MetaInputSettings *input_settings;
|
||||
|
||||
ClutterActor *stage;
|
||||
};
|
||||
@@ -65,15 +71,11 @@ meta_backend_finalize (GObject *object)
|
||||
{
|
||||
MetaBackend *backend = META_BACKEND (object);
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
int i;
|
||||
|
||||
g_clear_object (&priv->monitor_manager);
|
||||
g_clear_object (&priv->input_settings);
|
||||
|
||||
for (i = 0; i <= backend->device_id_max; i++)
|
||||
{
|
||||
if (backend->device_monitors[i])
|
||||
g_object_unref (backend->device_monitors[i]);
|
||||
}
|
||||
g_hash_table_destroy (backend->device_monitors);
|
||||
|
||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -108,27 +110,19 @@ static void
|
||||
create_device_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
g_assert (backend->device_monitors[device_id] == NULL);
|
||||
MetaIdleMonitor *idle_monitor;
|
||||
|
||||
backend->device_monitors[device_id] = meta_backend_create_idle_monitor (backend, device_id);
|
||||
backend->device_id_max = MAX (backend->device_id_max, device_id);
|
||||
g_assert (g_hash_table_lookup (backend->device_monitors, &device_id) == NULL);
|
||||
|
||||
idle_monitor = meta_backend_create_idle_monitor (backend, device_id);
|
||||
g_hash_table_insert (backend->device_monitors, &idle_monitor->device_id, idle_monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_device_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
g_clear_object (&backend->device_monitors[device_id]);
|
||||
|
||||
if (device_id == backend->device_id_max)
|
||||
{
|
||||
/* Reset the max device ID */
|
||||
int i, new_max = 0;
|
||||
for (i = 0; i < backend->device_id_max; i++)
|
||||
if (backend->device_monitors[i] != NULL)
|
||||
new_max = i;
|
||||
backend->device_id_max = new_max;
|
||||
}
|
||||
g_hash_table_remove (backend->device_monitors, &device_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -153,6 +147,15 @@ on_device_removed (ClutterDeviceManager *device_manager,
|
||||
destroy_device_monitor (backend, device_id);
|
||||
}
|
||||
|
||||
static MetaMonitorManager *
|
||||
create_monitor_manager (MetaBackend *backend)
|
||||
{
|
||||
if (g_getenv ("META_DUMMY_MONITORS"))
|
||||
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
||||
|
||||
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_post_init (MetaBackend *backend)
|
||||
{
|
||||
@@ -162,7 +165,7 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
clutter_actor_realize (priv->stage);
|
||||
META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
|
||||
|
||||
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
||||
priv->monitor_manager = create_monitor_manager (backend);
|
||||
|
||||
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), backend);
|
||||
@@ -170,6 +173,9 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
|
||||
backend->device_monitors = g_hash_table_new_full (g_int_hash, g_int_equal,
|
||||
NULL, (GDestroyNotify) g_object_unref);
|
||||
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
GSList *devices, *l;
|
||||
@@ -193,6 +199,8 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
priv->input_settings = meta_input_settings_create ();
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
@@ -281,9 +289,7 @@ MetaIdleMonitor *
|
||||
meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL);
|
||||
|
||||
return backend->device_monitors[device_id];
|
||||
return g_hash_table_lookup (backend->device_monitors, &device_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
81
src/backends/meta-barrier-private.h
Normal file
81
src/backends/meta-barrier-private.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BARRIER_PRIVATE_H
|
||||
#define META_BARRIER_PRIVATE_H
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_BARRIER_IMPL (meta_barrier_impl_get_type ())
|
||||
#define META_BARRIER_IMPL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImpl))
|
||||
#define META_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
|
||||
#define META_IS_BARRIER_IMPL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL))
|
||||
#define META_IS_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL))
|
||||
#define META_BARRIER_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
|
||||
|
||||
typedef struct _MetaBarrierImpl MetaBarrierImpl;
|
||||
typedef struct _MetaBarrierImplClass MetaBarrierImplClass;
|
||||
|
||||
struct _MetaBarrierImpl
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _MetaBarrierImplClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (*is_active) (MetaBarrierImpl *barrier);
|
||||
void (*release) (MetaBarrierImpl *barrier,
|
||||
MetaBarrierEvent *event);
|
||||
void (*destroy) (MetaBarrierImpl *barrier);
|
||||
};
|
||||
|
||||
GType meta_barrier_impl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _meta_barrier_emit_hit_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event);
|
||||
void _meta_barrier_emit_left_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event);
|
||||
|
||||
void meta_barrier_event_unref (MetaBarrierEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
struct _MetaBarrierPrivate
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
|
||||
MetaBarrierDirection directions;
|
||||
|
||||
MetaBarrierImpl *impl;
|
||||
};
|
||||
|
||||
#endif /* META_BARRIER_PRIVATE_H */
|
@@ -10,15 +10,16 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <meta/util.h>
|
||||
#include <meta/barrier.h>
|
||||
#include "display-private.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/meta-barrier-x11.h"
|
||||
#include "mutter-enum-types.h"
|
||||
#include "core.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaBarrier, meta_barrier, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE (MetaBarrierImpl, meta_barrier_impl, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@@ -45,21 +46,6 @@ enum {
|
||||
|
||||
static guint obj_signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaBarrierPrivate
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
|
||||
MetaBarrierDirection directions;
|
||||
|
||||
PointerBarrier xbarrier;
|
||||
};
|
||||
|
||||
static void meta_barrier_event_unref (MetaBarrierEvent *event);
|
||||
|
||||
static void
|
||||
meta_barrier_get_property (GObject *object,
|
||||
@@ -133,13 +119,11 @@ static void
|
||||
meta_barrier_dispose (GObject *object)
|
||||
{
|
||||
MetaBarrier *barrier = META_BARRIER (object);
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
|
||||
if (meta_barrier_is_active (barrier))
|
||||
{
|
||||
meta_bug ("MetaBarrier wrapper %p for X barrier %ld was destroyed"
|
||||
" while the X barrier is still active.",
|
||||
barrier, priv->xbarrier);
|
||||
meta_bug ("MetaBarrier %p was destroyed while it was still active.",
|
||||
barrier);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_barrier_parent_class)->dispose (object);
|
||||
@@ -148,7 +132,12 @@ meta_barrier_dispose (GObject *object)
|
||||
gboolean
|
||||
meta_barrier_is_active (MetaBarrier *barrier)
|
||||
{
|
||||
return barrier->priv->xbarrier != 0;
|
||||
MetaBarrierImpl *impl = barrier->priv->impl;
|
||||
|
||||
if (impl)
|
||||
return META_BARRIER_IMPL_GET_CLASS (impl)->is_active (impl);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,15 +154,10 @@ void
|
||||
meta_barrier_release (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
#ifdef HAVE_XI23
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
if (META_DISPLAY_HAS_XINPUT_23 (priv->display))
|
||||
{
|
||||
XIBarrierReleasePointer (priv->display->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
priv->xbarrier, event->event_id);
|
||||
}
|
||||
#endif /* HAVE_XI23 */
|
||||
MetaBarrierImpl *impl = barrier->priv->impl;
|
||||
|
||||
if (impl)
|
||||
META_BARRIER_IMPL_GET_CLASS (impl)->release (impl, event);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -181,31 +165,26 @@ meta_barrier_constructed (GObject *object)
|
||||
{
|
||||
MetaBarrier *barrier = META_BARRIER (object);
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
Display *dpy;
|
||||
Window root;
|
||||
|
||||
g_return_if_fail (priv->x1 == priv->x2 || priv->y1 == priv->y2);
|
||||
|
||||
if (priv->display == NULL)
|
||||
{
|
||||
g_warning ("A display must be provided when constructing a barrier.");
|
||||
return;
|
||||
}
|
||||
#if defined(HAVE_NATIVE_BACKEND)
|
||||
if (META_IS_BACKEND_NATIVE (meta_get_backend ()))
|
||||
priv->impl = meta_barrier_impl_native_new (barrier);
|
||||
#endif
|
||||
#if defined(HAVE_XI23)
|
||||
if (META_IS_BACKEND_X11 (meta_get_backend ()) &&
|
||||
!meta_is_wayland_compositor ())
|
||||
priv->impl = meta_barrier_impl_x11_new (barrier);
|
||||
#endif
|
||||
|
||||
dpy = priv->display->xdisplay;
|
||||
root = DefaultRootWindow (dpy);
|
||||
if (priv->impl == NULL)
|
||||
g_warning ("Created a non-working barrier");
|
||||
|
||||
priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
|
||||
priv->x1, priv->y1,
|
||||
priv->x2, priv->y2,
|
||||
priv->directions, 0, NULL);
|
||||
|
||||
/* Take a ref that we'll release when the XID dies inside destroy(),
|
||||
* so that the object stays alive and doesn't get GC'd. */
|
||||
/* Take a ref that we'll release in destroy() so that the object stays
|
||||
* alive while active. */
|
||||
g_object_ref (barrier);
|
||||
|
||||
g_hash_table_insert (priv->display->xids, &priv->xbarrier, barrier);
|
||||
|
||||
G_OBJECT_CLASS (meta_barrier_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
@@ -306,20 +285,10 @@ meta_barrier_class_init (MetaBarrierClass *klass)
|
||||
void
|
||||
meta_barrier_destroy (MetaBarrier *barrier)
|
||||
{
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
Display *dpy;
|
||||
MetaBarrierImpl *impl = barrier->priv->impl;
|
||||
|
||||
if (priv->display == NULL)
|
||||
return;
|
||||
|
||||
dpy = priv->display->xdisplay;
|
||||
|
||||
if (!meta_barrier_is_active (barrier))
|
||||
return;
|
||||
|
||||
XFixesDestroyPointerBarrier (dpy, priv->xbarrier);
|
||||
g_hash_table_remove (priv->display->xids, &priv->xbarrier);
|
||||
priv->xbarrier = 0;
|
||||
if (impl)
|
||||
return META_BARRIER_IMPL_GET_CLASS (impl)->destroy (impl);
|
||||
|
||||
g_object_unref (barrier);
|
||||
}
|
||||
@@ -330,71 +299,32 @@ meta_barrier_init (MetaBarrier *barrier)
|
||||
barrier->priv = G_TYPE_INSTANCE_GET_PRIVATE (barrier, META_TYPE_BARRIER, MetaBarrierPrivate);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
void
|
||||
_meta_barrier_emit_hit_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
g_signal_emit (barrier, obj_signals[HIT], 0, event);
|
||||
}
|
||||
|
||||
void
|
||||
_meta_barrier_emit_left_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
g_signal_emit (barrier, obj_signals[LEFT], 0, event);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_fire_event (MetaBarrier *barrier,
|
||||
XIBarrierEvent *xevent)
|
||||
meta_barrier_impl_class_init (MetaBarrierImplClass *klass)
|
||||
{
|
||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||
|
||||
event->ref_count = 1;
|
||||
event->event_id = xevent->eventid;
|
||||
event->time = xevent->time;
|
||||
event->dt = xevent->dtime;
|
||||
|
||||
event->x = xevent->root_x;
|
||||
event->y = xevent->root_y;
|
||||
event->dx = xevent->dx;
|
||||
event->dy = xevent->dy;
|
||||
|
||||
event->released = (xevent->flags & XIBarrierPointerReleased) != 0;
|
||||
event->grabbed = (xevent->flags & XIBarrierDeviceIsGrabbed) != 0;
|
||||
|
||||
switch (xevent->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
g_signal_emit (barrier, obj_signals[HIT], 0, event);
|
||||
break;
|
||||
case XI_BarrierLeave:
|
||||
g_signal_emit (barrier, obj_signals[LEFT], 0, event);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
meta_barrier_event_unref (event);
|
||||
klass->is_active = NULL;
|
||||
klass->release = NULL;
|
||||
klass->destroy = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIEvent *event)
|
||||
static void
|
||||
meta_barrier_impl_init (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
XIBarrierEvent *xev;
|
||||
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (event->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
case XI_BarrierLeave:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xev = (XIBarrierEvent *) event;
|
||||
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
||||
if (barrier != NULL)
|
||||
{
|
||||
meta_barrier_fire_event (barrier, xev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* HAVE_XI23 */
|
||||
|
||||
static MetaBarrierEvent *
|
||||
meta_barrier_event_ref (MetaBarrierEvent *event)
|
||||
@@ -406,7 +336,7 @@ meta_barrier_event_ref (MetaBarrierEvent *event)
|
||||
return event;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
meta_barrier_event_unref (MetaBarrierEvent *event)
|
||||
{
|
||||
g_return_if_fail (event != NULL);
|
@@ -25,7 +25,10 @@
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include <gbm.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
|
@@ -30,8 +30,6 @@
|
||||
#include <meta/screen.h>
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
|
||||
#define META_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer))
|
||||
#define META_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
|
||||
|
@@ -27,7 +27,9 @@
|
||||
* pointer abstraction"
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/util.h>
|
||||
@@ -38,11 +40,10 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
|
@@ -55,7 +55,8 @@ meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
static void
|
||||
meta_cursor_image_free (MetaCursorImage *image)
|
||||
{
|
||||
cogl_object_unref (image->texture);
|
||||
if (image->texture)
|
||||
cogl_object_unref (image->texture);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (image->bo)
|
||||
@@ -255,22 +256,30 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor_image (MetaCursorReference *cursor)
|
||||
{
|
||||
XcursorImage *image;
|
||||
|
||||
/* Either cursors are loaded from X cursors or buffers. Since
|
||||
* buffers are converted over immediately, we can make sure to
|
||||
* load this directly. */
|
||||
g_assert (cursor->cursor != META_CURSOR_NONE);
|
||||
|
||||
image = load_cursor_on_client (cursor->cursor);
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
|
||||
XcursorImageDestroy (image);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_from_theme (MetaCursor cursor)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
XcursorImage *image;
|
||||
|
||||
image = load_cursor_on_client (cursor);
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
MetaCursorReference *self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->cursor = cursor;
|
||||
meta_cursor_image_load_from_xcursor_image (&self->image, image);
|
||||
|
||||
XcursorImageDestroy (image);
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -308,6 +317,8 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
@@ -335,6 +346,8 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
(uint8_t *) wl_shm_buffer_get_data (shm_buffer),
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -380,10 +393,14 @@ meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
if (!cursor->image.texture)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
|
||||
return COGL_TEXTURE (cursor->image.texture);
|
||||
}
|
||||
|
||||
@@ -393,6 +410,9 @@ meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
if (!cursor->image.bo)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
|
83
src/backends/meta-input-settings-private.h
Normal file
83
src/backends/meta-input-settings-private.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_SETTINGS_PRIVATE_H
|
||||
#define META_INPUT_SETTINGS_PRIVATE_H
|
||||
|
||||
#include "display-private.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ())
|
||||
#define META_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettings))
|
||||
#define META_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
|
||||
#define META_IS_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS))
|
||||
#define META_IS_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS))
|
||||
#define META_INPUT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
|
||||
|
||||
typedef struct _MetaInputSettings MetaInputSettings;
|
||||
typedef struct _MetaInputSettingsClass MetaInputSettingsClass;
|
||||
|
||||
struct _MetaInputSettings
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* set_send_events) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopDeviceSendEvents mode);
|
||||
void (* set_matrix) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gfloat matrix[6]);
|
||||
void (* set_speed) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble speed);
|
||||
void (* set_left_handed) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled);
|
||||
void (* set_tap_enabled) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled);
|
||||
void (* set_invert_scroll) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted);
|
||||
void (* set_scroll_method) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode);
|
||||
void (* set_scroll_button) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button);
|
||||
|
||||
void (* set_keyboard_repeat) (MetaInputSettings *settings,
|
||||
gboolean repeat,
|
||||
guint delay,
|
||||
guint interval);
|
||||
};
|
||||
|
||||
GType meta_input_settings_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaInputSettings * meta_input_settings_create (void);
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
|
838
src/backends/meta-input-settings.c
Normal file
838
src/backends/meta-input-settings.c
Normal file
@@ -0,0 +1,838 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:input-settings
|
||||
* @title: MetaInputSettings
|
||||
* @short_description: Mutter input device configuration
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-input-settings-private.h"
|
||||
#include "x11/meta-input-settings-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "native/meta-backend-native.h"
|
||||
#include "native/meta-input-settings-native.h"
|
||||
#endif
|
||||
|
||||
#include <meta/util.h>
|
||||
|
||||
typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate;
|
||||
typedef struct _DeviceMappingInfo DeviceMappingInfo;
|
||||
|
||||
struct _DeviceMappingInfo
|
||||
{
|
||||
MetaInputSettings *input_settings;
|
||||
ClutterInputDevice *device;
|
||||
GSettings *settings;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsPrivate
|
||||
{
|
||||
ClutterDeviceManager *device_manager;
|
||||
MetaMonitorManager *monitor_manager;
|
||||
guint monitors_changed_id;
|
||||
|
||||
GSettings *mouse_settings;
|
||||
GSettings *touchpad_settings;
|
||||
GSettings *trackball_settings;
|
||||
GSettings *keyboard_settings;
|
||||
|
||||
GHashTable *mappable_devices;
|
||||
};
|
||||
|
||||
typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean setting);
|
||||
typedef void (*ConfigDoubleFunc) (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble value);
|
||||
typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
guint value);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
|
||||
|
||||
static GSList *
|
||||
meta_input_settings_get_devices (MetaInputSettings *settings,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices;
|
||||
GSList *list = NULL;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
while (devices)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == type &&
|
||||
clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER)
|
||||
list = g_slist_prepend (list, device);
|
||||
|
||||
devices = devices->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_dispose (GObject *object)
|
||||
{
|
||||
MetaInputSettings *settings = META_INPUT_SETTINGS (object);
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (settings);
|
||||
|
||||
g_clear_object (&priv->mouse_settings);
|
||||
g_clear_object (&priv->touchpad_settings);
|
||||
g_clear_object (&priv->trackball_settings);
|
||||
g_clear_object (&priv->keyboard_settings);
|
||||
g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
|
||||
|
||||
if (priv->monitors_changed_id && priv->monitor_manager)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->monitor_manager,
|
||||
priv->monitors_changed_id);
|
||||
priv->monitors_changed_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->monitor_manager);
|
||||
|
||||
G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_device_set_bool_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
ConfigBoolFunc func,
|
||||
gboolean enabled)
|
||||
{
|
||||
func (input_settings, device, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_set_bool_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type,
|
||||
ConfigBoolFunc func,
|
||||
gboolean enabled)
|
||||
{
|
||||
GSList *devices, *d;
|
||||
|
||||
devices = meta_input_settings_get_devices (input_settings, type);
|
||||
|
||||
for (d = devices; d; d = d->next)
|
||||
settings_device_set_bool_setting (input_settings, d->data, func, enabled);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_device_set_double_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
ConfigDoubleFunc func,
|
||||
gdouble value)
|
||||
{
|
||||
func (input_settings, device, value);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_set_double_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type,
|
||||
ConfigDoubleFunc func,
|
||||
gdouble value)
|
||||
{
|
||||
GSList *devices, *d;
|
||||
|
||||
devices = meta_input_settings_get_devices (input_settings, type);
|
||||
|
||||
for (d = devices; d; d = d->next)
|
||||
settings_device_set_double_setting (input_settings, d->data, func, value);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_device_set_uint_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
ConfigUintFunc func,
|
||||
guint value)
|
||||
{
|
||||
(func) (input_settings, device, value);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_set_uint_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type,
|
||||
ConfigUintFunc func,
|
||||
guint value)
|
||||
{
|
||||
GSList *devices, *d;
|
||||
|
||||
devices = meta_input_settings_get_devices (input_settings, type);
|
||||
|
||||
for (d = devices; d; d = d->next)
|
||||
settings_device_set_uint_setting (input_settings, d->data, func, value);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_left_handed (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadHandedness handedness;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled = FALSE;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
|
||||
|
||||
switch (handedness)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT:
|
||||
enabled = FALSE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT:
|
||||
enabled = TRUE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE:
|
||||
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHPAD_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_mouse_left_handed (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
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->mouse_settings, "left-handed");
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_POINTER_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
GDesktopTouchpadHandedness touchpad_handedness;
|
||||
|
||||
settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
|
||||
touchpad_handedness = g_settings_get_enum (priv->touchpad_settings,
|
||||
"left-handed");
|
||||
|
||||
/* Also update touchpads if they're following mouse settings */
|
||||
if (touchpad_handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE)
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_speed (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
gdouble speed;
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
speed = g_settings_get_double (settings, "speed");
|
||||
|
||||
if (device)
|
||||
settings_device_set_double_setting (input_settings, device,
|
||||
input_settings_class->set_speed,
|
||||
speed);
|
||||
else
|
||||
settings_set_double_setting (input_settings, type,
|
||||
input_settings_class->set_speed,
|
||||
speed);
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_natural_scroll (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
gboolean enabled;
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (settings, "natural-scroll");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_invert_scroll,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, type,
|
||||
input_settings_class->set_invert_scroll,
|
||||
enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
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-to-click");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_tap_enabled,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
input_settings_class->set_tap_enabled,
|
||||
enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
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, "scroll-method");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_uint_setting (input_settings, device,
|
||||
input_settings_class->set_scroll_method,
|
||||
method);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
(ConfigUintFunc) input_settings_class->set_scroll_method,
|
||||
method);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_send_events (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
GDesktopDeviceSendEvents mode;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_uint_setting (input_settings, device,
|
||||
input_settings_class->set_send_events,
|
||||
mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
input_settings_class->set_send_events,
|
||||
mode);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_is_trackball (ClutterInputDevice *device)
|
||||
{
|
||||
gboolean is_trackball;
|
||||
char *name;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return FALSE;
|
||||
|
||||
name = g_ascii_strdown (clutter_input_device_get_device_name (device), -1);
|
||||
is_trackball = strstr (name, "trackball") != NULL;
|
||||
g_free (name);
|
||||
|
||||
return is_trackball;
|
||||
}
|
||||
|
||||
static void
|
||||
update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint button;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
button = g_settings_get_uint (priv->trackball_settings, "scroll-wheel-emulation-button");
|
||||
|
||||
if (device && device_is_trackball (device))
|
||||
{
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
}
|
||||
else if (!device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
while (devices)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
|
||||
if (device_is_trackball (device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
|
||||
devices = devices->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_keyboard_repeat (MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint delay, interval;
|
||||
gboolean repeat;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat");
|
||||
delay = g_settings_get_uint (priv->keyboard_settings, "delay");
|
||||
interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval");
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
input_settings_class->set_keyboard_repeat (input_settings,
|
||||
repeat, delay, interval);
|
||||
}
|
||||
|
||||
static MetaOutput *
|
||||
meta_input_settings_find_output (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint n_values, n_outputs, i;
|
||||
MetaOutput *outputs;
|
||||
gchar **edid;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
edid = g_settings_get_strv (settings, "display");
|
||||
n_values = g_strv_length (edid);
|
||||
|
||||
if (n_values != 3)
|
||||
{
|
||||
g_warning ("EDID configuration for device '%s' "
|
||||
"is incorrect, must have 3 values",
|
||||
clutter_input_device_get_device_name (device));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!*edid[0] && !*edid[1] && !*edid[2])
|
||||
return NULL;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (priv->monitor_manager,
|
||||
&n_outputs);
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (g_strcmp0 (outputs[i].vendor, edid[0]) == 0 &&
|
||||
g_strcmp0 (outputs[i].product, edid[1]) == 0 &&
|
||||
g_strcmp0 (outputs[i].serial, edid[2]) == 0)
|
||||
return &outputs[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_display (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
|
||||
MetaOutput *output;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
output = meta_input_settings_find_output (input_settings, settings, device);
|
||||
|
||||
if (output)
|
||||
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
|
||||
output, matrix);
|
||||
|
||||
input_settings_class->set_matrix (input_settings, device, matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_changed_cb (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
if (settings == priv->mouse_settings)
|
||||
{
|
||||
if (strcmp (key, "left-handed") == 0)
|
||||
update_mouse_left_handed (input_settings, NULL);
|
||||
else if (strcmp (key, "speed") == 0)
|
||||
update_device_speed (input_settings, settings, NULL,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, settings,
|
||||
NULL, CLUTTER_POINTER_DEVICE);
|
||||
}
|
||||
else if (settings == priv->touchpad_settings)
|
||||
{
|
||||
if (strcmp (key, "left-handed") == 0)
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
else if (strcmp (key, "speed") == 0)
|
||||
update_device_speed (input_settings, settings, NULL,
|
||||
CLUTTER_TOUCHPAD_DEVICE);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, settings,
|
||||
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
||||
else if (strcmp (key, "tap-to-click") == 0)
|
||||
update_touchpad_tap_enabled (input_settings, NULL);
|
||||
else if (strcmp (key, "send-events") == 0)
|
||||
update_touchpad_send_events (input_settings, NULL);
|
||||
else if (strcmp (key, "scroll-method") == 0)
|
||||
update_touchpad_scroll_method (input_settings, NULL);
|
||||
}
|
||||
else if (settings == priv->trackball_settings)
|
||||
{
|
||||
if (strcmp (key, "scroll-wheel-emulation-button") == 0)
|
||||
update_trackball_scroll_button (input_settings, NULL);
|
||||
}
|
||||
else if (settings == priv->keyboard_settings)
|
||||
{
|
||||
if (strcmp (key, "repeat") == 0 ||
|
||||
strcmp (key, "repeat-interval") == 0 ||
|
||||
strcmp (key, "delay") == 0)
|
||||
update_keyboard_repeat (input_settings);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mapped_device_changed_cb (GSettings *settings,
|
||||
const gchar *key,
|
||||
DeviceMappingInfo *info)
|
||||
{
|
||||
if (strcmp (key, "display") == 0)
|
||||
update_device_display (info->input_settings, settings, info->device);
|
||||
}
|
||||
|
||||
static GSettings *
|
||||
lookup_device_settings (ClutterInputDevice *device)
|
||||
{
|
||||
const gchar *group, *schema, *vendor, *product;
|
||||
ClutterInputDeviceType type;
|
||||
GSettings *settings;
|
||||
gchar *path;
|
||||
|
||||
type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
group = "touchscreens";
|
||||
schema = "org.gnome.desktop.peripherals.touchscreen";
|
||||
}
|
||||
else if (type == CLUTTER_TABLET_DEVICE ||
|
||||
type == CLUTTER_PEN_DEVICE ||
|
||||
type == CLUTTER_ERASER_DEVICE ||
|
||||
type == CLUTTER_CURSOR_DEVICE)
|
||||
{
|
||||
group = "tablets";
|
||||
schema = "org.gnome.desktop.peripherals.tablet";
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
vendor = clutter_input_device_get_vendor_id (device);
|
||||
product = clutter_input_device_get_product_id (device);
|
||||
path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/",
|
||||
group, vendor, product);
|
||||
|
||||
settings = g_settings_new_with_path (schema, path);
|
||||
g_free (path);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
static void
|
||||
monitors_changed_cb (MetaMonitorManager *monitor_manager,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
ClutterInputDevice *device;
|
||||
GSettings *settings;
|
||||
GHashTableIter iter;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
g_hash_table_iter_init (&iter, priv->mappable_devices);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &device,
|
||||
(gpointer *) &settings))
|
||||
update_device_display (input_settings, settings, device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_add_mappable_device (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
DeviceMappingInfo *info;
|
||||
GSettings *settings;
|
||||
|
||||
settings = lookup_device_settings (device);
|
||||
|
||||
if (!settings)
|
||||
return FALSE;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
info = g_new0 (DeviceMappingInfo, 1);
|
||||
info->input_settings = input_settings;
|
||||
info->device = device;
|
||||
info->settings = settings;
|
||||
|
||||
g_signal_connect_data (settings, "changed",
|
||||
G_CALLBACK (mapped_device_changed_cb),
|
||||
info, (GClosureNotify) g_free, 0);
|
||||
|
||||
g_hash_table_insert (priv->mappable_devices, device, settings);
|
||||
|
||||
update_device_display (input_settings, settings, device);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_device_added (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
ClutterInputDeviceType type;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (type == CLUTTER_POINTER_DEVICE)
|
||||
{
|
||||
update_mouse_left_handed (input_settings, device);
|
||||
update_device_speed (input_settings, priv->mouse_settings, device, type);
|
||||
|
||||
if (device_is_trackball (device))
|
||||
update_trackball_scroll_button (input_settings, device);
|
||||
}
|
||||
else if (type == CLUTTER_TOUCHPAD_DEVICE)
|
||||
{
|
||||
update_touchpad_left_handed (input_settings, device);
|
||||
update_touchpad_tap_enabled (input_settings, device);
|
||||
update_touchpad_scroll_method (input_settings, device);
|
||||
update_touchpad_send_events (input_settings, device);
|
||||
|
||||
update_device_speed (input_settings, priv->touchpad_settings,
|
||||
device, type);
|
||||
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
||||
device, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_add_mappable_device (input_settings, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_device_removed (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
g_hash_table_remove (priv->mappable_devices, device);
|
||||
}
|
||||
|
||||
static void
|
||||
check_mappable_devices (MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices, *l;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
ClutterInputDevice *device = l->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
check_add_mappable_device (input_settings, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_constructed (GObject *object)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (object);
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
update_mouse_left_handed (input_settings, NULL);
|
||||
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
update_touchpad_tap_enabled (input_settings, NULL);
|
||||
update_touchpad_send_events (input_settings, NULL);
|
||||
|
||||
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
||||
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, priv->touchpad_settings, NULL,
|
||||
CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, priv->mouse_settings, NULL,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
update_keyboard_repeat (input_settings);
|
||||
|
||||
check_mappable_devices (input_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_class_init (MetaInputSettingsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_input_settings_dispose;
|
||||
object_class->constructed = meta_input_settings_constructed;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_init (MetaInputSettings *settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (settings);
|
||||
priv->device_manager = clutter_device_manager_get_default ();
|
||||
g_signal_connect (priv->device_manager, "device-added",
|
||||
G_CALLBACK (meta_input_settings_device_added), settings);
|
||||
g_signal_connect (priv->device_manager, "device-removed",
|
||||
G_CALLBACK (meta_input_settings_device_removed), settings);
|
||||
|
||||
priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse");
|
||||
g_signal_connect (priv->mouse_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
|
||||
g_signal_connect (priv->touchpad_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->trackball_settings = g_settings_new ("org.gnome.desktop.peripherals.trackball");
|
||||
g_signal_connect (priv->trackball_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->keyboard_settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
|
||||
g_signal_connect (priv->keyboard_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->mappable_devices =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
|
||||
|
||||
priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
|
||||
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (monitors_changed_cb), settings);
|
||||
}
|
||||
|
||||
MetaInputSettings *
|
||||
meta_input_settings_create (void)
|
||||
{
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend;
|
||||
|
||||
backend = meta_get_backend ();
|
||||
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
|
||||
#endif
|
||||
if (!meta_is_wayland_compositor ())
|
||||
return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "boxes-private.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -897,6 +898,20 @@ key_is_laptop (MetaOutputKey *key)
|
||||
g_str_has_prefix (key->connector, "eDP");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_is_laptop (MetaOutput *output)
|
||||
{
|
||||
/* FIXME: extend with better heuristics */
|
||||
switch (output->connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_eDP:
|
||||
case META_CONNECTOR_TYPE_LVDS:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
laptop_display_is_on (MetaConfiguration *config)
|
||||
{
|
||||
@@ -914,6 +929,19 @@ laptop_display_is_on (MetaConfiguration *config)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
multiple_outputs_are_enabled (MetaConfiguration *config)
|
||||
{
|
||||
unsigned int i, enabled;
|
||||
|
||||
enabled = 0;
|
||||
for (i = 0; i < config->n_outputs; i++)
|
||||
if (config->outputs[i].enabled)
|
||||
enabled++;
|
||||
|
||||
return enabled > 1;
|
||||
}
|
||||
|
||||
static MetaConfiguration *
|
||||
make_laptop_lid_config (MetaConfiguration *reference)
|
||||
{
|
||||
@@ -923,7 +951,7 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
int x_after, y_after;
|
||||
int x_offset, y_offset;
|
||||
|
||||
g_assert (reference->n_outputs > 1);
|
||||
g_assert (multiple_outputs_are_enabled (reference));
|
||||
|
||||
new = config_new ();
|
||||
new->n_outputs = reference->n_outputs;
|
||||
@@ -942,8 +970,7 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
new->keys[i].product = g_strdup (current_key->product);
|
||||
new->keys[i].serial = g_strdup (current_key->serial);
|
||||
|
||||
if (g_str_has_prefix (current_key->connector, "LVDS") ||
|
||||
g_str_has_prefix (current_key->connector, "eDP"))
|
||||
if (key_is_laptop (current_key))
|
||||
{
|
||||
new->outputs[i].enabled = FALSE;
|
||||
x_after = current_output->rect.x;
|
||||
@@ -986,7 +1013,7 @@ apply_configuration_with_lid (MetaMonitorConfig *self,
|
||||
MetaMonitorManager *manager)
|
||||
{
|
||||
if (self->lid_is_closed &&
|
||||
config->n_outputs > 1 &&
|
||||
multiple_outputs_are_enabled (config) &&
|
||||
laptop_display_is_on (config))
|
||||
{
|
||||
MetaConfiguration *laptop_lid_config = make_laptop_lid_config (config);
|
||||
@@ -1047,8 +1074,7 @@ find_primary_output (MetaOutput *outputs,
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (g_str_has_prefix (outputs[i].name, "LVDS") ||
|
||||
g_str_has_prefix (outputs[i].name, "eDP"))
|
||||
if (output_is_laptop (&outputs[i]))
|
||||
return &outputs[i];
|
||||
}
|
||||
|
||||
@@ -1068,47 +1094,123 @@ find_primary_output (MetaOutput *outputs,
|
||||
return best;
|
||||
}
|
||||
|
||||
static MetaConfiguration *
|
||||
make_default_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height)
|
||||
static void
|
||||
init_config_from_preferred_mode (MetaOutputConfig *config,
|
||||
MetaOutput *output)
|
||||
{
|
||||
unsigned i, j;
|
||||
int x, y;
|
||||
MetaConfiguration *ret;
|
||||
config->enabled = TRUE;
|
||||
config->rect.x = 0;
|
||||
config->rect.y = 0;
|
||||
config->rect.width = output->preferred_mode->width;
|
||||
config->rect.height = output->preferred_mode->height;
|
||||
config->refresh_rate = output->preferred_mode->refresh_rate;
|
||||
config->transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
config->is_primary = FALSE;
|
||||
config->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
/* This function handles configuring the outputs when the driver provides a
|
||||
* suggested layout position for each output. This is done in recent versions
|
||||
* of qxl and allows displays to be aligned on the guest in the same order as
|
||||
* they are aligned on the client.
|
||||
*/
|
||||
static gboolean
|
||||
make_suggested_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
unsigned int i;
|
||||
MetaOutput *primary;
|
||||
GList *region = NULL;
|
||||
|
||||
ret = config_new ();
|
||||
make_config_key (ret, outputs, n_outputs, -1);
|
||||
ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
|
||||
/* Special case the simple case: one output, primary at preferred mode,
|
||||
nothing else to do */
|
||||
if (n_outputs == 1)
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
ret->outputs[0].enabled = TRUE;
|
||||
ret->outputs[0].rect.x = 0;
|
||||
ret->outputs[0].rect.y = 0;
|
||||
ret->outputs[0].rect.width = outputs[0].preferred_mode->width;
|
||||
ret->outputs[0].rect.height = outputs[0].preferred_mode->height;
|
||||
ret->outputs[0].refresh_rate = outputs[0].preferred_mode->refresh_rate;
|
||||
ret->outputs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[0].is_primary = TRUE;
|
||||
gboolean is_primary = (&outputs[i] == primary);
|
||||
|
||||
return ret;
|
||||
if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
|
||||
return FALSE;
|
||||
|
||||
init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
|
||||
config->outputs[i].is_primary = is_primary;
|
||||
|
||||
config->outputs[i].rect.x = outputs[i].suggested_x;
|
||||
config->outputs[i].rect.y = outputs[i].suggested_y;
|
||||
|
||||
/* Reject the configuration if the suggested positions result in
|
||||
* overlapping displays */
|
||||
if (meta_rectangle_overlaps_with_region (region, &config->outputs[i].rect))
|
||||
{
|
||||
g_warning ("Overlapping outputs, rejecting suggested configuration");
|
||||
g_list_free (region);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
region = g_list_prepend (region, &config->outputs[i].rect);
|
||||
}
|
||||
|
||||
/* If we reach this point, this is either the first time mutter runs
|
||||
on this system ever, or we just hotplugged a new screen.
|
||||
In the latter case, search for a configuration that includes one
|
||||
less screen, then add the new one as a presentation screen
|
||||
in preferred mode.
|
||||
g_list_free (region);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
XXX: but presentation mode is not implemented in the control-center
|
||||
or in mutter core, so let's do extended for now.
|
||||
static void
|
||||
make_linear_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
MetaOutput *primary;
|
||||
unsigned i;
|
||||
int x;
|
||||
|
||||
g_return_if_fail (config != NULL);
|
||||
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
|
||||
x = primary->preferred_mode->width;
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
gboolean is_primary = (&outputs[i] == primary);
|
||||
|
||||
init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
|
||||
config->outputs[i].is_primary = is_primary;
|
||||
|
||||
if (is_primary)
|
||||
{
|
||||
config->outputs[i].rect.x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
config->outputs[i].rect.x = x;
|
||||
x += config->outputs[i].rect.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for a configuration that includes one less screen, then add the new
|
||||
* one as a presentation screen in preferred mode.
|
||||
*
|
||||
* XXX: but presentation mode is not implemented in the control-center or in
|
||||
* mutter core, so let's do extended for now.
|
||||
*/
|
||||
static gboolean
|
||||
extend_stored_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
int x, y;
|
||||
unsigned i, j;
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
@@ -1126,69 +1228,80 @@ make_default_config (MetaMonitorConfig *self,
|
||||
{
|
||||
if (j < i)
|
||||
{
|
||||
g_assert (output_key_equal (&ret->keys[j], &ref->keys[j]));
|
||||
ret->outputs[j] = ref->outputs[j];
|
||||
g_assert (output_key_equal (&config->keys[j], &ref->keys[j]));
|
||||
config->outputs[j] = ref->outputs[j];
|
||||
x = MAX (x, ref->outputs[j].rect.x + ref->outputs[j].rect.width);
|
||||
y = MAX (y, ref->outputs[j].rect.y + ref->outputs[j].rect.height);
|
||||
}
|
||||
else if (j > i)
|
||||
{
|
||||
g_assert (output_key_equal (&ret->keys[j], &ref->keys[j - 1]));
|
||||
ret->outputs[j] = ref->outputs[j - 1];
|
||||
g_assert (output_key_equal (&config->keys[j], &ref->keys[j - 1]));
|
||||
config->outputs[j] = ref->outputs[j - 1];
|
||||
x = MAX (x, ref->outputs[j - 1].rect.x + ref->outputs[j - 1].rect.width);
|
||||
y = MAX (y, ref->outputs[j - 1].rect.y + ref->outputs[j - 1].rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->outputs[j].enabled = TRUE;
|
||||
ret->outputs[j].rect.x = 0;
|
||||
ret->outputs[j].rect.y = 0;
|
||||
ret->outputs[j].rect.width = outputs[0].preferred_mode->width;
|
||||
ret->outputs[j].rect.height = outputs[0].preferred_mode->height;
|
||||
ret->outputs[j].refresh_rate = outputs[0].preferred_mode->refresh_rate;
|
||||
ret->outputs[j].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[j].is_primary = FALSE;
|
||||
ret->outputs[j].is_presentation = FALSE;
|
||||
init_config_from_preferred_mode (&config->outputs[j], &outputs[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Place the new output at the right end of the screen, if it fits,
|
||||
otherwise below it, otherwise disable it (or apply_configuration will fail) */
|
||||
if (x + ret->outputs[i].rect.width <= max_width)
|
||||
ret->outputs[i].rect.x = x;
|
||||
else if (y + ret->outputs[i].rect.height <= max_height)
|
||||
ret->outputs[i].rect.y = y;
|
||||
if (x + config->outputs[i].rect.width <= max_width)
|
||||
config->outputs[i].rect.x = x;
|
||||
else if (y + config->outputs[i].rect.height <= max_height)
|
||||
config->outputs[i].rect.y = y;
|
||||
else
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
config->outputs[i].enabled = FALSE;
|
||||
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* No previous configuration found, try with a really default one, which
|
||||
is one primary that goes first and the rest to the right of it, extended.
|
||||
*/
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
x = primary->preferred_mode->width;
|
||||
static MetaConfiguration *
|
||||
make_default_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
gboolean use_stored_config)
|
||||
{
|
||||
MetaConfiguration *ret = NULL;
|
||||
unsigned i;
|
||||
|
||||
ret = config_new ();
|
||||
make_config_key (ret, outputs, n_outputs, -1);
|
||||
ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
|
||||
/* Special case the simple case: one output, primary at preferred mode,
|
||||
nothing else to do */
|
||||
if (n_outputs == 1)
|
||||
{
|
||||
init_config_from_preferred_mode (&ret->outputs[0], &outputs[0]);
|
||||
ret->outputs[0].is_primary = TRUE;
|
||||
goto check_limits;
|
||||
}
|
||||
|
||||
if (make_suggested_config (self, outputs, n_outputs, max_width, max_height, ret))
|
||||
goto check_limits;
|
||||
|
||||
if (use_stored_config &&
|
||||
extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
|
||||
goto check_limits;
|
||||
|
||||
make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
|
||||
|
||||
check_limits:
|
||||
/* Disable outputs that would go beyond framebuffer limits */
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutput *output = &outputs[i];
|
||||
|
||||
ret->outputs[i].enabled = TRUE;
|
||||
ret->outputs[i].rect.x = (output == primary) ? 0 : x;
|
||||
ret->outputs[i].rect.y = 0;
|
||||
ret->outputs[i].rect.width = output->preferred_mode->width;
|
||||
ret->outputs[i].rect.height = output->preferred_mode->height;
|
||||
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = (output == primary);
|
||||
|
||||
/* Disable outputs that would go beyond framebuffer limits */
|
||||
if (ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
else if (output != primary)
|
||||
x += output->preferred_mode->width;
|
||||
if ((ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
|
||||
|| (ret->outputs[i].rect.y + ret->outputs[i].rect.height > max_height))
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1219,17 +1332,11 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutput *output = &outputs[i];
|
||||
gboolean is_primary = (&outputs[i] == primary);
|
||||
|
||||
if (output == primary)
|
||||
if (is_primary)
|
||||
{
|
||||
config->outputs[i].enabled = TRUE;
|
||||
config->outputs[i].rect.x = 0;
|
||||
config->outputs[i].rect.y = 0;
|
||||
config->outputs[i].rect.width = output->preferred_mode->width;
|
||||
config->outputs[i].rect.height = output->preferred_mode->height;
|
||||
config->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
|
||||
config->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
init_config_from_preferred_mode (&config->outputs[i], &outputs[0]);
|
||||
config->outputs[i].is_primary = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -1252,6 +1359,7 @@ meta_monitor_config_make_default (MetaMonitorConfig *self,
|
||||
unsigned n_outputs;
|
||||
gboolean ok = FALSE;
|
||||
int max_width, max_height;
|
||||
gboolean use_stored_config;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
|
||||
meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
|
||||
@@ -1262,7 +1370,16 @@ meta_monitor_config_make_default (MetaMonitorConfig *self,
|
||||
return;
|
||||
}
|
||||
|
||||
default_config = make_default_config (self, outputs, n_outputs, max_width, max_height);
|
||||
/* if the device has hotplug_mode_update, it's possible that the
|
||||
* current display configuration does not match a stored configuration.
|
||||
* Since extend_existing_config() tries to build a configuration that is
|
||||
* based on a previously-stored configuration, it's quite likely that the
|
||||
* resulting config will fail. Even if it doesn't fail, it may result in
|
||||
* an unexpected configuration, so don't attempt to use a stored config
|
||||
* in this situation. */
|
||||
use_stored_config = !meta_monitor_manager_has_hotplug_mode_update (manager);
|
||||
default_config = make_default_config (self, outputs, n_outputs, max_width, max_height, use_stored_config);
|
||||
|
||||
if (default_config != NULL)
|
||||
{
|
||||
ok = apply_configuration_with_lid (self, default_config, manager);
|
||||
@@ -1353,7 +1470,7 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
||||
{
|
||||
MetaConfiguration *new;
|
||||
|
||||
if (self->current->n_outputs == 1)
|
||||
if (!multiple_outputs_are_enabled (self->current))
|
||||
return;
|
||||
|
||||
new = make_laptop_lid_config (self->current);
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_CONFIG_H
|
||||
#define META_MONITOR_CONFIG_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ())
|
||||
#define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig))
|
||||
|
@@ -95,6 +95,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
manager->outputs[0].backlight = -1;
|
||||
manager->outputs[0].backlight_min = 0;
|
||||
manager->outputs[0].backlight_max = 0;
|
||||
manager->outputs[0].connector_type = META_CONNECTOR_TYPE_LVDS;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_MANAGER_DUMMY_H
|
||||
#define META_MONITOR_MANAGER_DUMMY_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ())
|
||||
#define META_MONITOR_MANAGER_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy))
|
||||
|
@@ -41,18 +41,17 @@
|
||||
#include "display-private.h"
|
||||
#include <meta/screen.h>
|
||||
#include "stack-tracker.h"
|
||||
#include <meta/meta-monitor-manager.h>
|
||||
|
||||
#include "meta-display-config-shared.h"
|
||||
#include "meta-dbus-display-config.h"
|
||||
#include "meta-cursor.h"
|
||||
|
||||
typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass;
|
||||
typedef struct _MetaMonitorManager MetaMonitorManager;
|
||||
typedef struct _MetaMonitorConfigClass MetaMonitorConfigClass;
|
||||
typedef struct _MetaMonitorConfig MetaMonitorConfig;
|
||||
|
||||
typedef struct _MetaOutput MetaOutput;
|
||||
typedef struct _MetaCRTC MetaCRTC;
|
||||
typedef struct _MetaOutput MetaOutput;
|
||||
typedef struct _MetaMonitorMode MetaMonitorMode;
|
||||
typedef struct _MetaMonitorInfo MetaMonitorInfo;
|
||||
typedef struct _MetaCRTCInfo MetaCRTCInfo;
|
||||
@@ -69,6 +68,27 @@ typedef enum {
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
} MetaMonitorTransform;
|
||||
|
||||
/* This matches the values in drm_mode.h */
|
||||
typedef enum {
|
||||
META_CONNECTOR_TYPE_Unknown = 0,
|
||||
META_CONNECTOR_TYPE_VGA = 1,
|
||||
META_CONNECTOR_TYPE_DVII = 2,
|
||||
META_CONNECTOR_TYPE_DVID = 3,
|
||||
META_CONNECTOR_TYPE_DVIA = 4,
|
||||
META_CONNECTOR_TYPE_Composite = 5,
|
||||
META_CONNECTOR_TYPE_SVIDEO = 6,
|
||||
META_CONNECTOR_TYPE_LVDS = 7,
|
||||
META_CONNECTOR_TYPE_Component = 8,
|
||||
META_CONNECTOR_TYPE_9PinDIN = 9,
|
||||
META_CONNECTOR_TYPE_DisplayPort = 10,
|
||||
META_CONNECTOR_TYPE_HDMIA = 11,
|
||||
META_CONNECTOR_TYPE_HDMIB = 12,
|
||||
META_CONNECTOR_TYPE_TV = 13,
|
||||
META_CONNECTOR_TYPE_eDP = 14,
|
||||
META_CONNECTOR_TYPE_VIRTUAL = 15,
|
||||
META_CONNECTOR_TYPE_DSI = 16,
|
||||
} MetaConnectorType;
|
||||
|
||||
struct _MetaOutput
|
||||
{
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
@@ -84,6 +104,8 @@ struct _MetaOutput
|
||||
CoglSubpixelOrder subpixel_order;
|
||||
int scale;
|
||||
|
||||
MetaConnectorType connector_type;
|
||||
|
||||
MetaMonitorMode *preferred_mode;
|
||||
MetaMonitorMode **modes;
|
||||
unsigned int n_modes;
|
||||
@@ -116,6 +138,8 @@ struct _MetaOutput
|
||||
|
||||
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
|
||||
gboolean hotplug_mode_update;
|
||||
gint suggested_x;
|
||||
gint suggested_y;
|
||||
};
|
||||
|
||||
struct _MetaCRTC
|
||||
@@ -297,10 +321,6 @@ struct _MetaMonitorManagerClass
|
||||
unsigned short *);
|
||||
};
|
||||
|
||||
GType meta_monitor_manager_get_type (void);
|
||||
|
||||
MetaMonitorManager *meta_monitor_manager_get (void);
|
||||
|
||||
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
|
||||
|
||||
MetaMonitorInfo *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
|
||||
@@ -336,6 +356,9 @@ void meta_monitor_manager_apply_configuration (MetaMonitorManager
|
||||
void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
|
||||
gboolean ok);
|
||||
|
||||
void meta_output_parse_edid (MetaOutput *output,
|
||||
GBytes *edid);
|
||||
|
||||
void meta_crtc_info_free (MetaCRTCInfo *info);
|
||||
void meta_output_info_free (MetaOutputInfo *info);
|
||||
|
||||
@@ -343,6 +366,10 @@ gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorMana
|
||||
void meta_monitor_manager_read_current_config (MetaMonitorManager *manager);
|
||||
void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager);
|
||||
|
||||
gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
gfloat matrix[6]);
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
static inline gboolean
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||
#include "meta-backend-private.h"
|
||||
@@ -44,6 +45,18 @@ enum {
|
||||
SIGNALS_LAST
|
||||
};
|
||||
|
||||
/* Array index matches MetaMonitorTransform */
|
||||
static gfloat transform_matrices[][6] = {
|
||||
{ 1, 0, 0, 0, 1, 0 }, /* normal */
|
||||
{ 0, -1, 1, 1, 0, 0 }, /* 90° */
|
||||
{ -1, 0, 1, 0, -1, 1 }, /* 180° */
|
||||
{ 0, 1, 0, -1, 0, 1 }, /* 270° */
|
||||
{ -1, 0, 1, 0, 1, 0 }, /* normal flipped */
|
||||
{ 0, 1, 0, 1, 0, 0 }, /* 90° flipped */
|
||||
{ 1, 0, 0, 0, -1, 1 }, /* 180° flipped */
|
||||
{ 0, -1, 1, -1, 0, 1 }, /* 270° flipped */
|
||||
};
|
||||
|
||||
static int signals[SIGNALS_LAST];
|
||||
|
||||
static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface);
|
||||
@@ -344,11 +357,14 @@ make_display_name (MetaMonitorManager *manager,
|
||||
char *vendor_name = NULL;
|
||||
char *ret;
|
||||
|
||||
if (g_str_has_prefix (output->name, "LVDS") ||
|
||||
g_str_has_prefix (output->name, "eDP"))
|
||||
switch (output->connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_LVDS:
|
||||
case META_CONNECTOR_TYPE_eDP:
|
||||
ret = g_strdup (_("Built-in display"));
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (output->width_mm > 0 && output->height_mm > 0)
|
||||
@@ -396,6 +412,32 @@ make_display_name (MetaMonitorManager *manager,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_connector_type_name (MetaConnectorType connector_type)
|
||||
{
|
||||
switch (connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_Unknown: return "Unknown";
|
||||
case META_CONNECTOR_TYPE_VGA: return "VGA";
|
||||
case META_CONNECTOR_TYPE_DVII: return "DVII";
|
||||
case META_CONNECTOR_TYPE_DVID: return "DVID";
|
||||
case META_CONNECTOR_TYPE_DVIA: return "DVIA";
|
||||
case META_CONNECTOR_TYPE_Composite: return "Composite";
|
||||
case META_CONNECTOR_TYPE_SVIDEO: return "SVIDEO";
|
||||
case META_CONNECTOR_TYPE_LVDS: return "LVDS";
|
||||
case META_CONNECTOR_TYPE_Component: return "Component";
|
||||
case META_CONNECTOR_TYPE_9PinDIN: return "9PinDIN";
|
||||
case META_CONNECTOR_TYPE_DisplayPort: return "DisplayPort";
|
||||
case META_CONNECTOR_TYPE_HDMIA: return "HDMIA";
|
||||
case META_CONNECTOR_TYPE_HDMIB: return "HDMIB";
|
||||
case META_CONNECTOR_TYPE_TV: return "TV";
|
||||
case META_CONNECTOR_TYPE_eDP: return "eDP";
|
||||
case META_CONNECTOR_TYPE_VIRTUAL: return "VIRTUAL";
|
||||
case META_CONNECTOR_TYPE_DSI: return "DSI";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
GDBusMethodInvocation *invocation)
|
||||
@@ -476,6 +518,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
g_variant_new_boolean (output->is_primary));
|
||||
g_variant_builder_add (&properties, "{sv}", "presentation",
|
||||
g_variant_new_boolean (output->is_presentation));
|
||||
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
||||
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
||||
|
||||
edid_file = manager_class->get_edid_file (manager, output);
|
||||
if (edid_file)
|
||||
@@ -1063,6 +1107,13 @@ initialize_dbus_interface (MetaMonitorManager *manager)
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_monitor_manager_get:
|
||||
*
|
||||
* Accessor for the singleton MetaMonitorManager.
|
||||
*
|
||||
* Returns: (transfer none): The only #MetaMonitorManager there is.
|
||||
*/
|
||||
MetaMonitorManager *
|
||||
meta_monitor_manager_get (void)
|
||||
{
|
||||
@@ -1179,6 +1230,42 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
|
||||
g_free (old_monitor_infos);
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_parse_edid (MetaOutput *meta_output,
|
||||
GBytes *edid)
|
||||
{
|
||||
MonitorInfo *parsed_edid;
|
||||
gsize len;
|
||||
|
||||
if (!edid)
|
||||
goto out;
|
||||
|
||||
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
|
||||
|
||||
if (parsed_edid)
|
||||
{
|
||||
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
if (parsed_edid->dsc_product_name[0])
|
||||
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
else
|
||||
meta_output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
|
||||
if (parsed_edid->dsc_serial_number[0])
|
||||
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
else
|
||||
meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
|
||||
|
||||
g_free (parsed_edid);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!meta_output->vendor)
|
||||
{
|
||||
meta_output->vendor = g_strdup ("unknown");
|
||||
meta_output->product = g_strdup ("unknown");
|
||||
meta_output->serial = g_strdup ("unknown");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
|
||||
{
|
||||
@@ -1198,3 +1285,86 @@ meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
|
||||
if (!applied_config)
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
calculate_viewport_matrix (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
gfloat viewport[6])
|
||||
{
|
||||
gfloat x, y, width, height;
|
||||
|
||||
if (!output->crtc)
|
||||
return FALSE;
|
||||
|
||||
x = (float) output->crtc->rect.x / manager->screen_width;
|
||||
y = (float) output->crtc->rect.y / manager->screen_height;
|
||||
width = (float) output->crtc->rect.width / manager->screen_width;
|
||||
height = (float) output->crtc->rect.height / manager->screen_height;
|
||||
|
||||
viewport[0] = width;
|
||||
viewport[1] = 0.0f;
|
||||
viewport[2] = x;
|
||||
viewport[3] = 0.0f;
|
||||
viewport[4] = height;
|
||||
viewport[5] = y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
multiply_matrix (float a[6],
|
||||
float b[6],
|
||||
float res[6])
|
||||
{
|
||||
res[0] = a[0] * b[0] + a[1] * b[3];
|
||||
res[1] = a[0] * b[1] + a[1] * b[4];
|
||||
res[2] = a[0] * b[2] + a[1] * b[5] + a[2];
|
||||
res[3] = a[3] * b[0] + a[4] * b[3];
|
||||
res[4] = a[3] * b[1] + a[4] * b[4];
|
||||
res[5] = a[3] * b[2] + a[4] * b[5] + a[5];
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
gfloat matrix[6])
|
||||
{
|
||||
gfloat viewport[9];
|
||||
|
||||
if (!calculate_viewport_matrix (manager, output, viewport))
|
||||
return FALSE;
|
||||
|
||||
multiply_matrix (viewport, transform_matrices[output->crtc->transform],
|
||||
matrix);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_monitor_manager_get_output_geometry:
|
||||
* @manager: A #MetaMonitorManager
|
||||
* @id: A valid #MetaOutput id
|
||||
*
|
||||
* Returns: The monitor index or -1 if @id isn't valid or the output
|
||||
* isn't associated with a logical monitor.
|
||||
*/
|
||||
gint
|
||||
meta_monitor_manager_get_monitor_for_output (MetaMonitorManager *manager,
|
||||
guint id)
|
||||
{
|
||||
MetaOutput *output;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (META_IS_MONITOR_MANAGER (manager), -1);
|
||||
g_return_val_if_fail (id < manager->n_outputs, -1);
|
||||
|
||||
output = &manager->outputs[id];
|
||||
if (!output || !output->crtc)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < manager->n_monitor_infos; i++)
|
||||
if (meta_rectangle_contains_rect (&manager->monitor_infos[i].rect,
|
||||
&output->crtc->rect))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
32
src/backends/native/meta-backend-native-private.h
Normal file
32
src/backends/native/meta-backend-native-private.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BACKEND_NATIVE_PRIVATE_H
|
||||
#define META_BACKEND_NATIVE_PRIVATE_H
|
||||
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
|
||||
MetaBarrierManagerNative *meta_backend_native_get_barrier_manager (MetaBackendNative *native);
|
||||
|
||||
#endif /* META_BACKEND_NATIVE_PRIVATE_H */
|
@@ -24,10 +24,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-backend-native.h"
|
||||
#include "meta-backend-native-private.h"
|
||||
|
||||
#include <meta/main.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
#include "meta-backend-native.h"
|
||||
|
||||
#include "meta-barrier-native.h"
|
||||
#include "meta-idle-monitor-native.h"
|
||||
#include "meta-monitor-manager-kms.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
@@ -37,6 +40,8 @@ struct _MetaBackendNativePrivate
|
||||
{
|
||||
MetaLauncher *launcher;
|
||||
|
||||
MetaBarrierManagerNative *barrier_manager;
|
||||
|
||||
GSettings *keyboard_settings;
|
||||
};
|
||||
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
|
||||
@@ -49,11 +54,27 @@ meta_backend_native_finalize (GObject *object)
|
||||
MetaBackendNative *native = META_BACKEND_NATIVE (object);
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
|
||||
g_clear_object (&priv->keyboard_settings);
|
||||
meta_launcher_free (priv->launcher);
|
||||
|
||||
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constrain_to_barriers (ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *new_x,
|
||||
float *new_y)
|
||||
{
|
||||
MetaBackendNative *native = META_BACKEND_NATIVE (meta_get_backend ());
|
||||
MetaBackendNativePrivate *priv =
|
||||
meta_backend_native_get_instance_private (native);
|
||||
|
||||
meta_barrier_manager_native_process (priv->barrier_manager,
|
||||
device,
|
||||
time,
|
||||
new_x, new_y);
|
||||
}
|
||||
|
||||
/*
|
||||
* The pointer constrain code is mostly a rip-off of the XRandR code from Xorg.
|
||||
* (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder)
|
||||
@@ -143,6 +164,9 @@ pointer_constrain_callback (ClutterInputDevice *device,
|
||||
unsigned int n_monitors;
|
||||
gboolean ret;
|
||||
|
||||
/* Constrain to barriers */
|
||||
constrain_to_barriers (device, time, new_x, new_y);
|
||||
|
||||
monitor_manager = meta_monitor_manager_get ();
|
||||
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
|
||||
|
||||
@@ -155,46 +179,15 @@ pointer_constrain_callback (ClutterInputDevice *device,
|
||||
constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
|
||||
}
|
||||
|
||||
static void
|
||||
set_keyboard_repeat (MetaBackendNative *native)
|
||||
{
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
gboolean repeat;
|
||||
unsigned int delay, interval;
|
||||
|
||||
repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat");
|
||||
delay = g_settings_get_uint (priv->keyboard_settings, "delay");
|
||||
interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval");
|
||||
|
||||
clutter_evdev_set_keyboard_repeat (manager, repeat, delay, interval);
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer data)
|
||||
{
|
||||
MetaBackendNative *native = data;
|
||||
set_keyboard_repeat (native);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
||||
|
||||
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
|
||||
NULL, NULL);
|
||||
|
||||
priv->keyboard_settings = g_settings_new ("org.gnome.settings-daemon.peripherals.keyboard");
|
||||
g_signal_connect (priv->keyboard_settings, "changed",
|
||||
G_CALLBACK (keyboard_settings_changed), native);
|
||||
set_keyboard_repeat (native);
|
||||
}
|
||||
|
||||
static MetaIdleMonitor *
|
||||
@@ -302,6 +295,8 @@ meta_backend_native_init (MetaBackendNative *native)
|
||||
|
||||
/* We're a display server, so start talking to weston-launch. */
|
||||
priv->launcher = meta_launcher_new ();
|
||||
|
||||
priv->barrier_manager = meta_barrier_manager_native_new ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -314,6 +309,15 @@ meta_activate_vt (int vt, GError **error)
|
||||
return meta_launcher_activate_vt (priv->launcher, vt, error);
|
||||
}
|
||||
|
||||
MetaBarrierManagerNative *
|
||||
meta_backend_native_get_barrier_manager (MetaBackendNative *native)
|
||||
{
|
||||
MetaBackendNativePrivate *priv =
|
||||
meta_backend_native_get_instance_private (native);
|
||||
|
||||
return priv->barrier_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_activate_session:
|
||||
*
|
||||
|
744
src/backends/native/meta-barrier-native.c
Normal file
744
src/backends/native/meta-barrier-native.c
Normal file
@@ -0,0 +1,744 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:barrier-native
|
||||
* @Title: MetaBarrierImplNative
|
||||
* @Short_Description: Pointer barriers implementation for the native backend
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <meta/barrier.h>
|
||||
#include <meta/util.h>
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-barrier-private.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-backend-native-private.h"
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
|
||||
struct _MetaBarrierManagerNative
|
||||
{
|
||||
GHashTable *barriers;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
/* The barrier is active and responsive to pointer motion. */
|
||||
META_BARRIER_STATE_ACTIVE,
|
||||
|
||||
/* An intermediate state after a pointer hit the pointer barrier. */
|
||||
META_BARRIER_STATE_HIT,
|
||||
|
||||
/* The barrier was hit by a pointer and is still within the hit box and
|
||||
* has not been released.*/
|
||||
META_BARRIER_STATE_HELD,
|
||||
|
||||
/* The pointer was released by the user. If the following motion hits
|
||||
* the barrier, it will pass through. */
|
||||
META_BARRIER_STATE_RELEASE,
|
||||
|
||||
/* An intermediate state when the pointer has left the barrier. */
|
||||
META_BARRIER_STATE_LEFT,
|
||||
} MetaBarrierState;
|
||||
|
||||
struct _MetaBarrierImplNativePrivate
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
MetaBarrierManagerNative *manager;
|
||||
|
||||
gboolean is_active;
|
||||
MetaBarrierState state;
|
||||
int trigger_serial;
|
||||
guint32 last_event_time;
|
||||
MetaBarrierDirection blocked_dir;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrierImplNative, meta_barrier_impl_native,
|
||||
META_TYPE_BARRIER_IMPL)
|
||||
|
||||
static int
|
||||
next_serial (void)
|
||||
{
|
||||
static int barrier_serial = 1;
|
||||
|
||||
barrier_serial++;
|
||||
|
||||
/* If it wraps, avoid 0 as it's not a valid serial. */
|
||||
if (barrier_serial == 0)
|
||||
barrier_serial++;
|
||||
|
||||
return barrier_serial;
|
||||
}
|
||||
|
||||
typedef struct _Vector2
|
||||
{
|
||||
float x, y;
|
||||
} Vector2;
|
||||
|
||||
static float
|
||||
vector2_cross_product (Vector2 a, Vector2 b)
|
||||
{
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
static Vector2
|
||||
vector2_add (Vector2 a, Vector2 b)
|
||||
{
|
||||
return (Vector2) {
|
||||
.x = a.x + b.x,
|
||||
.y = a.y + b.y,
|
||||
};
|
||||
}
|
||||
|
||||
static Vector2
|
||||
vector2_subtract (Vector2 a, Vector2 b)
|
||||
{
|
||||
return (Vector2) {
|
||||
.x = a.x - b.x,
|
||||
.y = a.y - b.y,
|
||||
};
|
||||
}
|
||||
|
||||
static Vector2
|
||||
vector2_multiply_constant (float c, Vector2 a)
|
||||
{
|
||||
return (Vector2) {
|
||||
.x = c * a.x,
|
||||
.y = c * a.y,
|
||||
};
|
||||
}
|
||||
|
||||
typedef struct _Line2
|
||||
{
|
||||
Vector2 a;
|
||||
Vector2 b;
|
||||
} Line2;
|
||||
|
||||
static gboolean
|
||||
lines_intersect (Line2 *line1, Line2 *line2, Vector2 *intersection)
|
||||
{
|
||||
Vector2 p = line1->a;
|
||||
Vector2 r = vector2_subtract (line1->b, line1->a);
|
||||
Vector2 q = line2->a;
|
||||
Vector2 s = vector2_subtract (line2->b, line2->a);
|
||||
float rxs;
|
||||
float sxr;
|
||||
float t;
|
||||
float u;
|
||||
|
||||
/*
|
||||
* The line (p, r) and (q, s) intersects where
|
||||
*
|
||||
* p + t r = q + u s
|
||||
*
|
||||
* Calculate t:
|
||||
*
|
||||
* (p + t r) × s = (q + u s) × s
|
||||
* p × s + t (r × s) = q × s + u (s × s)
|
||||
* p × s + t (r × s) = q × s
|
||||
* t (r × s) = q × s - p × s
|
||||
* t (r × s) = (q - p) × s
|
||||
* t = ((q - p) × s) / (r × s)
|
||||
*
|
||||
* Using the same method, for u we get:
|
||||
*
|
||||
* u = ((p - q) × r) / (s × r)
|
||||
*/
|
||||
|
||||
rxs = vector2_cross_product (r, s);
|
||||
sxr = vector2_cross_product (s, r);
|
||||
|
||||
/* If r × s = 0 then the lines are either parallel or collinear. */
|
||||
if (fabs ( rxs) < DBL_MIN)
|
||||
return FALSE;
|
||||
|
||||
t = vector2_cross_product (vector2_subtract (q, p), s) / rxs;
|
||||
u = vector2_cross_product (vector2_subtract (p, q), r) / sxr;
|
||||
|
||||
|
||||
/* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */
|
||||
if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0)
|
||||
return FALSE;
|
||||
|
||||
*intersection = vector2_add (p, vector2_multiply_constant (t, r));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_barrier_horizontal (MetaBarrier *barrier)
|
||||
{
|
||||
return barrier->priv->y1 == barrier->priv->y2;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_barrier_blocking_directions (MetaBarrier *barrier,
|
||||
MetaBarrierDirection directions)
|
||||
{
|
||||
/* Barriers doesn't block parallel motions. */
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if ((directions & (META_BARRIER_DIRECTION_POSITIVE_Y |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y)) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((directions & (META_BARRIER_DIRECTION_POSITIVE_X |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X)) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (barrier->priv->directions & directions) != directions;
|
||||
}
|
||||
|
||||
static void
|
||||
dismiss_pointer (MetaBarrierImplNative *self)
|
||||
{
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
priv->state = META_BARRIER_STATE_LEFT;
|
||||
}
|
||||
|
||||
static Line2
|
||||
barrier_to_line (MetaBarrier *barrier)
|
||||
{
|
||||
return (Line2) {
|
||||
.a = (Vector2) {
|
||||
.x = MIN (barrier->priv->x1, barrier->priv->x2),
|
||||
.y = MIN (barrier->priv->y1, barrier->priv->y2),
|
||||
},
|
||||
.b = (Vector2) {
|
||||
.x = MAX (barrier->priv->x1, barrier->priv->x2),
|
||||
.y = MAX (barrier->priv->y1, barrier->priv->y2),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the hit box for a held motion. The hit box is a 2 px wide region
|
||||
* in the opposite direction of every direction the barrier blocks. The purpose
|
||||
* of this is to allow small movements without receiving a "left" signal. This
|
||||
* heuristic comes from the X.org pointer barrier implementation.
|
||||
*/
|
||||
static Line2
|
||||
calculate_barrier_hit_box (MetaBarrier *barrier)
|
||||
{
|
||||
Line2 hit_box = barrier_to_line (barrier);
|
||||
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_POSITIVE_Y))
|
||||
hit_box.a.y -= 2.0f;
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y))
|
||||
hit_box.b.y += 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_POSITIVE_X))
|
||||
hit_box.a.x -= 2.0f;
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X))
|
||||
hit_box.b.x += 2.0f;
|
||||
}
|
||||
|
||||
return hit_box;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_within_box (Line2 box, Vector2 point)
|
||||
{
|
||||
return (point.x >= box.a.x && point.x < box.b.x &&
|
||||
point.y >= box.a.y && point.y < box.b.y);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_release_barrier (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBarrierImplNative *self = key;
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
Line2 *motion = user_data;
|
||||
Line2 hit_box;
|
||||
|
||||
if (priv->state != META_BARRIER_STATE_HELD)
|
||||
return;
|
||||
|
||||
/* Release if we end up outside barrier end points. */
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if (motion->b.x > MAX (barrier->priv->x1, barrier->priv->x2) ||
|
||||
motion->b.x < MIN (barrier->priv->x1, barrier->priv->x2))
|
||||
{
|
||||
dismiss_pointer (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (motion->b.y > MAX (barrier->priv->y1, barrier->priv->y2) ||
|
||||
motion->b.y < MIN (barrier->priv->y1, barrier->priv->y2))
|
||||
{
|
||||
dismiss_pointer (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release if we don't intersect and end up outside of hit box. */
|
||||
hit_box = calculate_barrier_hit_box (barrier);
|
||||
if (!is_within_box (hit_box, motion->b))
|
||||
{
|
||||
dismiss_pointer (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_release_barriers (MetaBarrierManagerNative *manager,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
Line2 motion = {
|
||||
.a = {
|
||||
.x = prev_x,
|
||||
.y = prev_y,
|
||||
},
|
||||
.b = {
|
||||
.x = x,
|
||||
.y = y,
|
||||
},
|
||||
};
|
||||
|
||||
g_hash_table_foreach (manager->barriers,
|
||||
maybe_release_barrier,
|
||||
&motion);
|
||||
}
|
||||
|
||||
typedef struct _MetaClosestBarrierData
|
||||
{
|
||||
struct
|
||||
{
|
||||
Line2 motion;
|
||||
MetaBarrierDirection directions;
|
||||
} in;
|
||||
|
||||
struct
|
||||
{
|
||||
float closest_distance_2;
|
||||
MetaBarrierImplNative *barrier_impl;
|
||||
} out;
|
||||
} MetaClosestBarrierData;
|
||||
|
||||
static void
|
||||
update_closest_barrier (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBarrierImplNative *self = key;
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
MetaClosestBarrierData *data = user_data;
|
||||
Line2 barrier_line;
|
||||
Vector2 intersection;
|
||||
float dx, dy;
|
||||
float distance_2;
|
||||
|
||||
/* Ignore if the barrier is not blocking in any of the motions directions. */
|
||||
if (!is_barrier_blocking_directions (barrier, data->in.directions))
|
||||
return;
|
||||
|
||||
/* Ignore if the barrier released the pointer. */
|
||||
if (priv->state == META_BARRIER_STATE_RELEASE)
|
||||
return;
|
||||
|
||||
/* Ignore if we are moving away from barrier. */
|
||||
if (priv->state == META_BARRIER_STATE_HELD &&
|
||||
(data->in.directions & priv->blocked_dir) == 0)
|
||||
return;
|
||||
|
||||
/* Check if the motion intersects with the barrier, and retrieve the
|
||||
* intersection point if any. */
|
||||
barrier_line = (Line2) {
|
||||
.a = {
|
||||
.x = barrier->priv->x1,
|
||||
.y = barrier->priv->y1
|
||||
},
|
||||
.b = {
|
||||
.x = barrier->priv->x2,
|
||||
.y = barrier->priv->y2
|
||||
},
|
||||
};
|
||||
if (!lines_intersect (&barrier_line, &data->in.motion, &intersection))
|
||||
return;
|
||||
|
||||
/* Calculate the distance to the barrier and keep track of the closest
|
||||
* barrier. */
|
||||
dx = intersection.x - data->in.motion.a.x;
|
||||
dy = intersection.y - data->in.motion.a.y;
|
||||
distance_2 = dx*dx + dy*dy;
|
||||
if (data->out.barrier_impl == NULL ||
|
||||
distance_2 < data->out.closest_distance_2)
|
||||
{
|
||||
data->out.barrier_impl = self;
|
||||
data->out.closest_distance_2 = distance_2;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_closest_barrier (MetaBarrierManagerNative *manager,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float x,
|
||||
float y,
|
||||
MetaBarrierDirection motion_dir,
|
||||
MetaBarrierImplNative **barrier_impl)
|
||||
{
|
||||
MetaClosestBarrierData closest_barrier_data;
|
||||
|
||||
closest_barrier_data = (MetaClosestBarrierData) {
|
||||
.in = {
|
||||
.motion = {
|
||||
.a = {
|
||||
.x = prev_x,
|
||||
.y = prev_y,
|
||||
},
|
||||
.b = {
|
||||
.x = x,
|
||||
.y = y,
|
||||
},
|
||||
},
|
||||
.directions = motion_dir,
|
||||
},
|
||||
};
|
||||
|
||||
g_hash_table_foreach (manager->barriers,
|
||||
update_closest_barrier,
|
||||
&closest_barrier_data);
|
||||
|
||||
if (closest_barrier_data.out.barrier_impl != NULL)
|
||||
{
|
||||
*barrier_impl = closest_barrier_data.out.barrier_impl;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _MetaBarrierEventData
|
||||
{
|
||||
guint32 time;
|
||||
float prev_x;
|
||||
float prev_y;
|
||||
float x;
|
||||
float y;
|
||||
float dx;
|
||||
float dy;
|
||||
} MetaBarrierEventData;
|
||||
|
||||
static void
|
||||
emit_barrier_event (MetaBarrierImplNative *self,
|
||||
guint32 time,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float x,
|
||||
float y,
|
||||
float dx,
|
||||
float dy)
|
||||
{
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||
MetaBarrierState old_state = priv->state;
|
||||
|
||||
switch (priv->state)
|
||||
{
|
||||
case META_BARRIER_STATE_HIT:
|
||||
priv->state = META_BARRIER_STATE_HELD;
|
||||
priv->trigger_serial = next_serial ();
|
||||
event->dt = 0;
|
||||
|
||||
break;
|
||||
case META_BARRIER_STATE_RELEASE:
|
||||
case META_BARRIER_STATE_LEFT:
|
||||
priv->state = META_BARRIER_STATE_ACTIVE;
|
||||
|
||||
/* Intentional fall-through. */
|
||||
case META_BARRIER_STATE_HELD:
|
||||
event->dt = time - priv->last_event_time;
|
||||
|
||||
break;
|
||||
case META_BARRIER_STATE_ACTIVE:
|
||||
g_assert_not_reached (); /* Invalid state. */
|
||||
}
|
||||
|
||||
event->ref_count = 1;
|
||||
event->event_id = priv->trigger_serial;
|
||||
event->time = time;
|
||||
|
||||
event->x = x;
|
||||
event->y = y;
|
||||
event->dx = dx;
|
||||
event->dy = dy;
|
||||
|
||||
event->grabbed = priv->state == META_BARRIER_STATE_HELD;
|
||||
event->released = old_state == META_BARRIER_STATE_RELEASE;
|
||||
|
||||
priv->last_event_time = time;
|
||||
|
||||
if (priv->state == META_BARRIER_STATE_HELD)
|
||||
_meta_barrier_emit_hit_signal (barrier, event);
|
||||
else
|
||||
_meta_barrier_emit_left_signal (barrier, event);
|
||||
|
||||
meta_barrier_event_unref (event);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_emit_barrier_event (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
MetaBarrierImplNative *self = key;
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrierEventData *data = user_data;
|
||||
|
||||
switch (priv->state) {
|
||||
case META_BARRIER_STATE_ACTIVE:
|
||||
break;
|
||||
case META_BARRIER_STATE_HIT:
|
||||
case META_BARRIER_STATE_HELD:
|
||||
case META_BARRIER_STATE_RELEASE:
|
||||
case META_BARRIER_STATE_LEFT:
|
||||
emit_barrier_event (self,
|
||||
data->time,
|
||||
data->prev_x,
|
||||
data->prev_y,
|
||||
data->x,
|
||||
data->y,
|
||||
data->dx,
|
||||
data->dy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clamp (x, y) to the barrier and remove clamped direction from motion_dir. */
|
||||
static void
|
||||
clamp_to_barrier (MetaBarrierImplNative *self,
|
||||
MetaBarrierDirection *motion_dir,
|
||||
float *x,
|
||||
float *y)
|
||||
{
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_Y)
|
||||
*y = barrier->priv->y1;
|
||||
else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_Y)
|
||||
*y = barrier->priv->y1;
|
||||
|
||||
priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_Y |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y);
|
||||
*motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_Y |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_X)
|
||||
*x = barrier->priv->x1;
|
||||
else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_X)
|
||||
*x = barrier->priv->x1;
|
||||
|
||||
priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_X |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X);
|
||||
*motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_X |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X);
|
||||
}
|
||||
|
||||
priv->state = META_BARRIER_STATE_HIT;
|
||||
}
|
||||
|
||||
void
|
||||
meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
||||
ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *x,
|
||||
float *y)
|
||||
{
|
||||
ClutterPoint prev_pos;
|
||||
float prev_x;
|
||||
float prev_y;
|
||||
float orig_x = *x;
|
||||
float orig_y = *y;
|
||||
MetaBarrierDirection motion_dir = 0;
|
||||
MetaBarrierEventData barrier_event_data;
|
||||
MetaBarrierImplNative *barrier_impl;
|
||||
|
||||
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
|
||||
return;
|
||||
|
||||
prev_x = prev_pos.x;
|
||||
prev_y = prev_pos.y;
|
||||
|
||||
/* Get the direction of the motion vector. */
|
||||
if (prev_x < *x)
|
||||
motion_dir |= META_BARRIER_DIRECTION_POSITIVE_X;
|
||||
else if (prev_x > *x)
|
||||
motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_X;
|
||||
if (prev_y < *y)
|
||||
motion_dir |= META_BARRIER_DIRECTION_POSITIVE_Y;
|
||||
else if (prev_y > *y)
|
||||
motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_Y;
|
||||
|
||||
/* Clamp to the closest barrier in any direction until either there are no
|
||||
* more barriers to clamp to or all directions have been clamped. */
|
||||
while (motion_dir != 0)
|
||||
{
|
||||
if (get_closest_barrier (manager,
|
||||
prev_x, prev_y,
|
||||
*x, *y,
|
||||
motion_dir,
|
||||
&barrier_impl))
|
||||
clamp_to_barrier (barrier_impl, &motion_dir, x, y);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* Potentially release active barrier movements. */
|
||||
maybe_release_barriers (manager, prev_x, prev_y, *x, *y);
|
||||
|
||||
/* Initiate or continue barrier interaction. */
|
||||
barrier_event_data = (MetaBarrierEventData) {
|
||||
.time = time,
|
||||
.prev_x = prev_x,
|
||||
.prev_y = prev_y,
|
||||
.x = *x,
|
||||
.y = *y,
|
||||
.dx = orig_x - prev_x,
|
||||
.dy = orig_y - prev_y,
|
||||
};
|
||||
|
||||
g_hash_table_foreach (manager->barriers,
|
||||
maybe_emit_barrier_event,
|
||||
&barrier_event_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_meta_barrier_impl_native_is_active (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
return priv->is_active;
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_native_release (MetaBarrierImpl *impl,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
if (priv->state == META_BARRIER_STATE_HELD &&
|
||||
event->event_id == priv->trigger_serial)
|
||||
priv->state = META_BARRIER_STATE_RELEASE;
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
g_hash_table_remove (priv->manager->barriers, self);
|
||||
priv->is_active = FALSE;
|
||||
}
|
||||
|
||||
MetaBarrierImpl *
|
||||
meta_barrier_impl_native_new (MetaBarrier *barrier)
|
||||
{
|
||||
MetaBarrierImplNative *self;
|
||||
MetaBarrierImplNativePrivate *priv;
|
||||
MetaBackendNative *native;
|
||||
MetaBarrierManagerNative *manager;
|
||||
|
||||
self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
|
||||
priv = meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
priv->barrier = barrier;
|
||||
priv->is_active = TRUE;
|
||||
|
||||
native = META_BACKEND_NATIVE (meta_get_backend ());
|
||||
manager = meta_backend_native_get_barrier_manager (native);
|
||||
priv->manager = manager;
|
||||
g_hash_table_add (manager->barriers, self);
|
||||
|
||||
return META_BARRIER_IMPL (self);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_native_class_init (MetaBarrierImplNativeClass *klass)
|
||||
{
|
||||
MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass);
|
||||
|
||||
impl_class->is_active = _meta_barrier_impl_native_is_active;
|
||||
impl_class->release = _meta_barrier_impl_native_release;
|
||||
impl_class->destroy = _meta_barrier_impl_native_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_native_init (MetaBarrierImplNative *self)
|
||||
{
|
||||
}
|
||||
|
||||
MetaBarrierManagerNative *
|
||||
meta_barrier_manager_native_new (void)
|
||||
{
|
||||
MetaBarrierManagerNative *manager;
|
||||
|
||||
manager = g_new0 (MetaBarrierManagerNative, 1);
|
||||
|
||||
manager->barriers = g_hash_table_new (NULL, NULL);
|
||||
|
||||
return manager;
|
||||
}
|
68
src/backends/native/meta-barrier-native.h
Normal file
68
src/backends/native/meta-barrier-native.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BARRIER_NATIVE_H
|
||||
#define META_BARRIER_NATIVE_H
|
||||
|
||||
#include "backends/meta-barrier-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_BARRIER_IMPL_NATIVE (meta_barrier_impl_native_get_type ())
|
||||
#define META_BARRIER_IMPL_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNative))
|
||||
#define META_BARRIER_IMPL_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNativeClass))
|
||||
#define META_IS_BARRIER_IMPL_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL_NATIVE))
|
||||
#define META_IS_BARRIER_IMPL_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL_NATIVE))
|
||||
#define META_BARRIER_IMPL_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNativeClass))
|
||||
|
||||
typedef struct _MetaBarrierImplNative MetaBarrierImplNative;
|
||||
typedef struct _MetaBarrierImplNativeClass MetaBarrierImplNativeClass;
|
||||
typedef struct _MetaBarrierImplNativePrivate MetaBarrierImplNativePrivate;
|
||||
|
||||
typedef struct _MetaBarrierManagerNative MetaBarrierManagerNative;
|
||||
|
||||
struct _MetaBarrierImplNative
|
||||
{
|
||||
MetaBarrierImpl parent;
|
||||
};
|
||||
|
||||
struct _MetaBarrierImplNativeClass
|
||||
{
|
||||
MetaBarrierImplClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_barrier_impl_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaBarrierImpl *meta_barrier_impl_native_new (MetaBarrier *barrier);
|
||||
|
||||
MetaBarrierManagerNative *meta_barrier_manager_native_new (void);
|
||||
void meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
||||
ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *x,
|
||||
float *y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_BARRIER_NATIVE_H */
|
@@ -30,7 +30,7 @@
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#ifndef DRM_CAP_CURSOR_WIDTH
|
||||
#define DRM_CAP_CURSOR_WIDTH 0x8
|
||||
|
217
src/backends/native/meta-input-settings-native.c
Normal file
217
src/backends/native/meta-input-settings-native.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
#include <libinput.h>
|
||||
|
||||
#include "meta-input-settings-native.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_send_events (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopDeviceSendEvents mode)
|
||||
{
|
||||
enum libinput_config_send_events_mode libinput_mode;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
|
||||
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
break;
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
||||
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
break;
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED:
|
||||
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device_config_send_events_set_mode (libinput_device, libinput_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_matrix (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gfloat matrix[6])
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_calibration_has_matrix (libinput_device) > 0)
|
||||
libinput_device_config_calibration_set_matrix (libinput_device, matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_speed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble speed)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device_config_accel_set_speed (libinput_device,
|
||||
CLAMP (speed, -1, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_left_handed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_left_handed_is_available (libinput_device))
|
||||
libinput_device_config_left_handed_set (libinput_device, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_tap_enabled (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count (libinput_device) > 0)
|
||||
libinput_device_config_tap_set_enabled (libinput_device,
|
||||
enabled ?
|
||||
LIBINPUT_CONFIG_TAP_ENABLED :
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_invert_scroll (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll (libinput_device))
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled (libinput_device,
|
||||
inverted);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_set_scroll_method (struct libinput_device *libinput_device,
|
||||
enum libinput_config_scroll_method method)
|
||||
{
|
||||
enum libinput_config_scroll_method supported;
|
||||
|
||||
supported = libinput_device_config_scroll_get_methods (libinput_device);
|
||||
|
||||
if (method & supported)
|
||||
libinput_device_config_scroll_set_method (libinput_device, method);
|
||||
|
||||
return (method & supported) != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_scroll_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode)
|
||||
{
|
||||
enum libinput_config_scroll_method scroll_method = 0;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
device_set_scroll_method (libinput_device, scroll_method);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_scroll_button (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (!device_set_scroll_method (libinput_device,
|
||||
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN))
|
||||
return;
|
||||
|
||||
libinput_device_config_scroll_set_button (libinput_device, button);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
gboolean enabled,
|
||||
guint delay,
|
||||
guint interval)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
clutter_evdev_set_keyboard_repeat (manager, enabled, delay, interval);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
||||
|
||||
input_settings_class->set_send_events = meta_input_settings_native_set_send_events;
|
||||
input_settings_class->set_matrix = meta_input_settings_native_set_matrix;
|
||||
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_invert_scroll = meta_input_settings_native_set_invert_scroll;
|
||||
input_settings_class->set_scroll_method = meta_input_settings_native_set_scroll_method;
|
||||
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
|
||||
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_init (MetaInputSettingsNative *settings)
|
||||
{
|
||||
}
|
49
src/backends/native/meta-input-settings-native.h
Normal file
49
src/backends/native/meta-input-settings-native.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_SETTINGS_NATIVE_H
|
||||
#define META_INPUT_SETTINGS_NATIVE_H
|
||||
|
||||
#include "meta-input-settings-private.h"
|
||||
|
||||
#define META_TYPE_INPUT_SETTINGS_NATIVE (meta_input_settings_native_get_type ())
|
||||
#define META_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNative))
|
||||
#define META_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass))
|
||||
#define META_IS_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_NATIVE))
|
||||
#define META_IS_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_NATIVE))
|
||||
#define META_INPUT_SETTINGS_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass))
|
||||
|
||||
typedef struct _MetaInputSettingsNative MetaInputSettingsNative;
|
||||
typedef struct _MetaInputSettingsNativeClass MetaInputSettingsNativeClass;
|
||||
|
||||
struct _MetaInputSettingsNative
|
||||
{
|
||||
MetaInputSettings parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsNativeClass
|
||||
{
|
||||
MetaInputSettingsClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_input_settings_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_NATIVE_H */
|
@@ -130,8 +130,8 @@ take_device (Login1Session *session_proxy,
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GVariant *fd_variant = NULL;
|
||||
GUnixFDList *fd_list = NULL;
|
||||
int fd = -1;
|
||||
GUnixFDList *fd_list;
|
||||
|
||||
if (!login1_session_call_take_device_sync (session_proxy,
|
||||
dev_major,
|
||||
|
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <meta/main.h>
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
|
||||
#include <gudev/gudev.h>
|
||||
|
||||
@@ -207,7 +206,7 @@ find_properties (MetaMonitorManagerKms *manager_kms,
|
||||
strcmp (prop->name, "EDID") == 0)
|
||||
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,8 +228,10 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
|
||||
}
|
||||
|
||||
if (edid_blob->length > 0)
|
||||
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
|
||||
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
|
||||
{
|
||||
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
|
||||
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeFreePropertyBlob (edid_blob);
|
||||
@@ -415,6 +416,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->name = make_output_name (connector);
|
||||
meta_output->width_mm = connector->mmWidth;
|
||||
meta_output->height_mm = connector->mmHeight;
|
||||
meta_output->suggested_x = -1;
|
||||
meta_output->suggested_y = -1;
|
||||
|
||||
switch (connector->subpixel)
|
||||
{
|
||||
@@ -509,29 +512,11 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
find_properties (manager_kms, output_kms);
|
||||
|
||||
edid = read_output_edid (manager_kms, meta_output);
|
||||
if (edid)
|
||||
{
|
||||
MonitorInfo *parsed_edid;
|
||||
gsize len;
|
||||
meta_output_parse_edid (meta_output, edid);
|
||||
g_bytes_unref (edid);
|
||||
|
||||
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
|
||||
if (parsed_edid)
|
||||
{
|
||||
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
|
||||
g_free (parsed_edid);
|
||||
}
|
||||
|
||||
g_bytes_unref (edid);
|
||||
}
|
||||
if (!meta_output->vendor)
|
||||
{
|
||||
meta_output->vendor = g_strdup ("unknown");
|
||||
meta_output->product = g_strdup ("unknown");
|
||||
meta_output->serial = g_strdup ("unknown");
|
||||
}
|
||||
/* MetaConnectorType matches DRM's connector types */
|
||||
meta_output->connector_type = (MetaConnectorType) connector->connector_type;
|
||||
|
||||
/* FIXME: backlight is a very driver specific thing unfortunately,
|
||||
every DDX does its own thing, and the dumb KMS API does not include it.
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_MANAGER_KMS_H
|
||||
#define META_MONITOR_MANAGER_KMS_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ())
|
||||
#define META_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms))
|
||||
|
@@ -79,11 +79,15 @@ static void
|
||||
handle_alarm_notify (MetaBackend *backend,
|
||||
XEvent *event)
|
||||
{
|
||||
int i;
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
|
||||
for (i = 0; i <= backend->device_id_max; i++)
|
||||
if (backend->device_monitors[i])
|
||||
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event);
|
||||
g_hash_table_iter_init (&iter, backend->device_monitors);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
MetaIdleMonitor *device_monitor = META_IDLE_MONITOR (value);
|
||||
meta_idle_monitor_xsync_handle_xevent (device_monitor, (XSyncAlarmNotifyEvent*) event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -125,6 +129,21 @@ translate_device_event (MetaBackendX11 *x11,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
translate_crossing_event (MetaBackendX11 *x11,
|
||||
XIEnterEvent *enter_event)
|
||||
{
|
||||
/* Throw out weird events generated by grabs. */
|
||||
if (enter_event->mode == XINotifyGrab ||
|
||||
enter_event->mode == XINotifyUngrab)
|
||||
{
|
||||
enter_event->event = None;
|
||||
return;
|
||||
}
|
||||
|
||||
enter_event->event = meta_backend_x11_get_xwindow (x11);
|
||||
}
|
||||
|
||||
/* Clutter makes the assumption that there is only one X window
|
||||
* per stage, which is a valid assumption to make for a generic
|
||||
* application toolkit. As such, it will ignore any events sent
|
||||
@@ -157,6 +176,10 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
case XI_TouchEnd:
|
||||
translate_device_event (x11, (XIDeviceEvent *) input_event);
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
translate_crossing_event (x11, (XIEnterEvent *) input_event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
216
src/backends/x11/meta-barrier-x11.c
Normal file
216
src/backends/x11/meta-barrier-x11.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:barrier-x11
|
||||
* @Title: MetaBarrierImplX11
|
||||
* @Short_Description: Pointer barriers implementation for X11
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <meta/barrier.h>
|
||||
#include "backends/x11/meta-barrier-x11.h"
|
||||
#include "display-private.h"
|
||||
|
||||
struct _MetaBarrierImplX11Private
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
PointerBarrier xbarrier;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrierImplX11, meta_barrier_impl_x11,
|
||||
META_TYPE_BARRIER_IMPL)
|
||||
|
||||
static gboolean
|
||||
_meta_barrier_impl_x11_is_active (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
|
||||
MetaBarrierImplX11Private *priv =
|
||||
meta_barrier_impl_x11_get_instance_private (self);
|
||||
|
||||
return priv->xbarrier != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_x11_release (MetaBarrierImpl *impl,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
|
||||
MetaBarrierImplX11Private *priv =
|
||||
meta_barrier_impl_x11_get_instance_private (self);
|
||||
MetaDisplay *display = priv->barrier->priv->display;
|
||||
|
||||
if (META_DISPLAY_HAS_XINPUT_23 (display))
|
||||
{
|
||||
XIBarrierReleasePointer (display->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
priv->xbarrier, event->event_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
|
||||
MetaBarrierImplX11Private *priv =
|
||||
meta_barrier_impl_x11_get_instance_private (self);
|
||||
MetaDisplay *display = priv->barrier->priv->display;
|
||||
Display *dpy;
|
||||
|
||||
if (display == NULL)
|
||||
return;
|
||||
|
||||
dpy = display->xdisplay;
|
||||
|
||||
if (!meta_barrier_is_active (priv->barrier))
|
||||
return;
|
||||
|
||||
XFixesDestroyPointerBarrier (dpy, priv->xbarrier);
|
||||
g_hash_table_remove (display->xids, &priv->xbarrier);
|
||||
priv->xbarrier = 0;
|
||||
}
|
||||
|
||||
MetaBarrierImpl *
|
||||
meta_barrier_impl_x11_new (MetaBarrier *barrier)
|
||||
{
|
||||
MetaBarrierImplX11 *self;
|
||||
MetaBarrierImplX11Private *priv;
|
||||
MetaDisplay *display = barrier->priv->display;
|
||||
Display *dpy;
|
||||
Window root;
|
||||
|
||||
if (display == NULL)
|
||||
{
|
||||
g_warning ("A display must be provided when constructing a barrier.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL);
|
||||
priv = meta_barrier_impl_x11_get_instance_private (self);
|
||||
priv->barrier = barrier;
|
||||
|
||||
dpy = display->xdisplay;
|
||||
root = DefaultRootWindow (dpy);
|
||||
|
||||
priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
|
||||
barrier->priv->x1,
|
||||
barrier->priv->y1,
|
||||
barrier->priv->x2,
|
||||
barrier->priv->y2,
|
||||
barrier->priv->directions,
|
||||
0, NULL);
|
||||
|
||||
g_hash_table_insert (display->xids, &priv->xbarrier, barrier);
|
||||
|
||||
return META_BARRIER_IMPL (self);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_fire_xevent (MetaBarrier *barrier,
|
||||
XIBarrierEvent *xevent)
|
||||
{
|
||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||
|
||||
event->ref_count = 1;
|
||||
event->event_id = xevent->eventid;
|
||||
event->time = xevent->time;
|
||||
event->dt = xevent->dtime;
|
||||
|
||||
event->x = xevent->root_x;
|
||||
event->y = xevent->root_y;
|
||||
event->dx = xevent->dx;
|
||||
event->dy = xevent->dy;
|
||||
|
||||
event->released = (xevent->flags & XIBarrierPointerReleased) != 0;
|
||||
event->grabbed = (xevent->flags & XIBarrierDeviceIsGrabbed) != 0;
|
||||
|
||||
switch (xevent->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
_meta_barrier_emit_hit_signal (barrier, event);
|
||||
break;
|
||||
case XI_BarrierLeave:
|
||||
_meta_barrier_emit_left_signal (barrier, event);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
meta_barrier_event_unref (event);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_process_barrier_xevent (MetaDisplay *display,
|
||||
XIEvent *event)
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
XIBarrierEvent *xev;
|
||||
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (event->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
case XI_BarrierLeave:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xev = (XIBarrierEvent *) event;
|
||||
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
||||
if (barrier != NULL)
|
||||
{
|
||||
meta_barrier_fire_xevent (barrier, xev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_x11_class_init (MetaBarrierImplX11Class *klass)
|
||||
{
|
||||
MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass);
|
||||
|
||||
impl_class->is_active = _meta_barrier_impl_x11_is_active;
|
||||
impl_class->release = _meta_barrier_impl_x11_release;
|
||||
impl_class->destroy = _meta_barrier_impl_x11_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_x11_init (MetaBarrierImplX11 *self)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* HAVE_XI23 */
|
59
src/backends/x11/meta-barrier-x11.h
Normal file
59
src/backends/x11/meta-barrier-x11.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BARRIER_X11_H
|
||||
#define META_BARRIER_X11_H
|
||||
|
||||
#include "backends/meta-barrier-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_BARRIER_IMPL_X11 (meta_barrier_impl_x11_get_type ())
|
||||
#define META_BARRIER_IMPL_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11))
|
||||
#define META_BARRIER_IMPL_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11Class))
|
||||
#define META_IS_BARRIER_IMPL_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL_X11))
|
||||
#define META_IS_BARRIER_IMPL_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL_X11))
|
||||
#define META_BARRIER_IMPL_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11Class))
|
||||
|
||||
typedef struct _MetaBarrierImplX11 MetaBarrierImplX11;
|
||||
typedef struct _MetaBarrierImplX11Class MetaBarrierImplX11Class;
|
||||
typedef struct _MetaBarrierImplX11Private MetaBarrierImplX11Private;
|
||||
|
||||
struct _MetaBarrierImplX11
|
||||
{
|
||||
MetaBarrierImpl parent;
|
||||
};
|
||||
|
||||
struct _MetaBarrierImplX11Class
|
||||
{
|
||||
MetaBarrierImplClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_barrier_impl_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaBarrierImpl *meta_barrier_impl_x11_new (MetaBarrier *barrier);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_BARRIER_X11_H1 */
|
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
|
226
src/backends/x11/meta-input-settings-x11.c
Normal file
226
src/backends/x11/meta-input-settings-x11.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-input-settings-x11.h"
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include <meta/errors.h>
|
||||
|
||||
G_DEFINE_TYPE (MetaInputSettingsX11, meta_input_settings_x11, META_TYPE_INPUT_SETTINGS)
|
||||
|
||||
static void
|
||||
change_property (ClutterInputDevice *device,
|
||||
const gchar *property,
|
||||
Atom type,
|
||||
int format,
|
||||
void *data,
|
||||
gulong nitems)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
gulong nitems_ret, bytes_after_ret;
|
||||
int rc, device_id, format_ret;
|
||||
Atom property_atom, type_ret;
|
||||
guchar *data_ret;
|
||||
|
||||
property_atom = XInternAtom (xdisplay, property, False);
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
rc = XIGetProperty (xdisplay, device_id, property_atom,
|
||||
0, 0, False, type, &type_ret, &format_ret,
|
||||
&nitems_ret, &bytes_after_ret, &data_ret);
|
||||
|
||||
meta_XFree (data_ret);
|
||||
|
||||
if (rc == Success && type_ret == type && format_ret == format)
|
||||
XIChangeProperty (xdisplay, device_id, property_atom, type,
|
||||
format, XIPropModeReplace, data, nitems);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopDeviceSendEvents mode)
|
||||
{
|
||||
guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
|
||||
values[0] = 1;
|
||||
break;
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
||||
values[1] = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
change_property (device, "libinput Send Events Mode Enabled",
|
||||
XA_INTEGER, 8, &values, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_matrix (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gfloat matrix[6])
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
gfloat full_matrix[9] = { matrix[0], matrix[1], matrix[2],
|
||||
matrix[3], matrix[4], matrix[5],
|
||||
0, 0, 1 };
|
||||
|
||||
change_property (device, "Coordinate Transformation Matrix",
|
||||
XInternAtom (xdisplay, "FLOAT", False),
|
||||
32, &full_matrix, 9);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_speed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble speed)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
gfloat value = speed;
|
||||
|
||||
change_property (device, "libinput Accel Speed",
|
||||
XInternAtom (xdisplay, "FLOAT", False),
|
||||
32, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
guchar value = (enabled) ? 1 : 0;
|
||||
|
||||
change_property (device, "libinput Left Handed Enabled",
|
||||
XA_INTEGER, 8, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
guchar value = (enabled) ? 1 : 0;
|
||||
|
||||
change_property (device, "libinput Tapping Enabled",
|
||||
XA_INTEGER, 8, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted)
|
||||
{
|
||||
guchar value = (inverted) ? 1 : 0;
|
||||
|
||||
change_property (device, "libinput Natural Scrolling Enabled",
|
||||
XA_INTEGER, 8, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_scroll_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode)
|
||||
{
|
||||
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
|
||||
values[1] = 1;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
||||
values[0] = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
XA_INTEGER, 8, &values, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
XA_INTEGER, 32, &button, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
gboolean enabled,
|
||||
guint delay,
|
||||
guint interval)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
XAutoRepeatOn (xdisplay);
|
||||
XkbSetAutoRepeatRate (xdisplay, XkbUseCoreKbd, delay, interval);
|
||||
}
|
||||
else
|
||||
{
|
||||
XAutoRepeatOff (xdisplay);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
||||
|
||||
input_settings_class->set_send_events = meta_input_settings_x11_set_send_events;
|
||||
input_settings_class->set_matrix = meta_input_settings_x11_set_matrix;
|
||||
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_invert_scroll = meta_input_settings_x11_set_invert_scroll;
|
||||
input_settings_class->set_scroll_method = meta_input_settings_x11_set_scroll_method;
|
||||
input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button;
|
||||
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_init (MetaInputSettingsX11 *settings)
|
||||
{
|
||||
}
|
49
src/backends/x11/meta-input-settings-x11.h
Normal file
49
src/backends/x11/meta-input-settings-x11.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_SETTINGS_X11_H
|
||||
#define META_INPUT_SETTINGS_X11_H
|
||||
|
||||
#include "meta-input-settings-private.h"
|
||||
|
||||
#define META_TYPE_INPUT_SETTINGS_X11 (meta_input_settings_x11_get_type ())
|
||||
#define META_INPUT_SETTINGS_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11))
|
||||
#define META_INPUT_SETTINGS_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11Class))
|
||||
#define META_IS_INPUT_SETTINGS_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_X11))
|
||||
#define META_IS_INPUT_SETTINGS_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_X11))
|
||||
#define META_INPUT_SETTINGS_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11Class))
|
||||
|
||||
typedef struct _MetaInputSettingsX11 MetaInputSettingsX11;
|
||||
typedef struct _MetaInputSettingsX11Class MetaInputSettingsX11Class;
|
||||
|
||||
struct _MetaInputSettingsX11
|
||||
{
|
||||
MetaInputSettings parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsX11Class
|
||||
{
|
||||
MetaInputSettingsClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_input_settings_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_X11_H */
|
@@ -41,7 +41,6 @@
|
||||
#include "meta-backend-x11.h"
|
||||
#include <meta/main.h>
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
@@ -139,6 +138,58 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_integer_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname,
|
||||
gint *value)
|
||||
{
|
||||
gboolean exists = FALSE;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_INTEGER,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
exists = (actual_type == XA_INTEGER && actual_format == 32 && nitems == 1);
|
||||
|
||||
if (exists && value != NULL)
|
||||
*value = ((int*)buffer)[0];
|
||||
|
||||
XFree (buffer);
|
||||
return exists;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_property_exists (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname)
|
||||
{
|
||||
gboolean exists = FALSE;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, AnyPropertyType,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
exists = (actual_type != None);
|
||||
|
||||
XFree (buffer);
|
||||
return exists;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname)
|
||||
@@ -329,7 +380,170 @@ static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
return output_get_boolean_property (manager_xrandr, output, "hotplug_mode_update");
|
||||
return output_get_property_exists (manager_xrandr, output, "hotplug_mode_update");
|
||||
}
|
||||
|
||||
static gint
|
||||
output_get_suggested_x (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
gint val;
|
||||
if (output_get_integer_property (manager_xrandr, output, "suggested X", &val))
|
||||
return val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gint
|
||||
output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
gint val;
|
||||
if (output_get_integer_property (manager_xrandr, output, "suggested Y", &val))
|
||||
return val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
connector_type_from_atom (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
Atom atom)
|
||||
{
|
||||
Display *xdpy = manager_xrandr->xdisplay;
|
||||
|
||||
if (atom == XInternAtom (xdpy, "HDMI", True))
|
||||
return META_CONNECTOR_TYPE_HDMIA;
|
||||
if (atom == XInternAtom (xdpy, "VGA", True))
|
||||
return META_CONNECTOR_TYPE_VGA;
|
||||
/* Doesn't have a DRM equivalent, but means an internal panel.
|
||||
* We could pick either LVDS or eDP here. */
|
||||
if (atom == XInternAtom (xdpy, "Panel", True))
|
||||
return META_CONNECTOR_TYPE_LVDS;
|
||||
if (atom == XInternAtom (xdpy, "DVI", True) || atom == XInternAtom (xdpy, "DVI-I", True))
|
||||
return META_CONNECTOR_TYPE_DVII;
|
||||
if (atom == XInternAtom (xdpy, "DVI-A", True))
|
||||
return META_CONNECTOR_TYPE_DVIA;
|
||||
if (atom == XInternAtom (xdpy, "DVI-D", True))
|
||||
return META_CONNECTOR_TYPE_DVID;
|
||||
if (atom == XInternAtom (xdpy, "DisplayPort", True))
|
||||
return META_CONNECTOR_TYPE_DisplayPort;
|
||||
|
||||
if (atom == XInternAtom (xdpy, "TV", True))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
if (atom == XInternAtom (xdpy, "TV-Composite", True))
|
||||
return META_CONNECTOR_TYPE_Composite;
|
||||
if (atom == XInternAtom (xdpy, "TV-SVideo", True))
|
||||
return META_CONNECTOR_TYPE_SVIDEO;
|
||||
/* Another set of mismatches. */
|
||||
if (atom == XInternAtom (xdpy, "TV-SCART", True))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
if (atom == XInternAtom (xdpy, "TV-C4", True))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaConnectorType ret = META_CONNECTOR_TYPE_Unknown;
|
||||
Atom atom, actual_type, connector_type_atom;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "ConnectorType", False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_ATOM,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
|
||||
goto out;
|
||||
|
||||
connector_type_atom = ((Atom *) buffer)[0];
|
||||
ret = connector_type_from_atom (manager_xrandr, connector_type_atom);
|
||||
|
||||
out:
|
||||
meta_XFree (buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
output_get_connector_type_from_name (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
const char *name = output->name;
|
||||
|
||||
/* drmmode_display.c, which was copy/pasted across all the FOSS
|
||||
* xf86-video-* drivers, seems to name its outputs based on the
|
||||
* connector type, so look for that....
|
||||
*
|
||||
* SNA has its own naming scheme, because what else did you expect
|
||||
* from SNA, but it's not too different, so we can thankfully use
|
||||
* that with minor changes.
|
||||
*
|
||||
* http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/drivers/modesetting/drmmode_display.c#n953
|
||||
* http://cgit.freedesktop.org/xorg/driver/xf86-video-intel/tree/src/sna/sna_display.c#n3486
|
||||
*/
|
||||
|
||||
if (g_str_has_prefix (name, "DVI"))
|
||||
return META_CONNECTOR_TYPE_DVII;
|
||||
if (g_str_has_prefix (name, "LVDS"))
|
||||
return META_CONNECTOR_TYPE_LVDS;
|
||||
if (g_str_has_prefix (name, "HDMI"))
|
||||
return META_CONNECTOR_TYPE_HDMIA;
|
||||
if (g_str_has_prefix (name, "VGA"))
|
||||
return META_CONNECTOR_TYPE_VGA;
|
||||
/* SNA uses DP, not DisplayPort. Test for both. */
|
||||
if (g_str_has_prefix (name, "DP") || g_str_has_prefix (name, "DisplayPort"))
|
||||
return META_CONNECTOR_TYPE_DisplayPort;
|
||||
if (g_str_has_prefix (name, "eDP"))
|
||||
return META_CONNECTOR_TYPE_eDP;
|
||||
if (g_str_has_prefix (name, "Virtual"))
|
||||
return META_CONNECTOR_TYPE_VIRTUAL;
|
||||
if (g_str_has_prefix (name, "Composite"))
|
||||
return META_CONNECTOR_TYPE_VGA;
|
||||
if (g_str_has_prefix (name, "S-video"))
|
||||
return META_CONNECTOR_TYPE_SVIDEO;
|
||||
if (g_str_has_prefix (name, "TV"))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
if (g_str_has_prefix (name, "CTV"))
|
||||
return META_CONNECTOR_TYPE_Composite;
|
||||
if (g_str_has_prefix (name, "DSI"))
|
||||
return META_CONNECTOR_TYPE_DSI;
|
||||
if (g_str_has_prefix (name, "DIN"))
|
||||
return META_CONNECTOR_TYPE_9PinDIN;
|
||||
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
output_get_connector_type (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaConnectorType ret;
|
||||
|
||||
/* The "ConnectorType" property is considered mandatory since RandR 1.3,
|
||||
* but none of the FOSS drivers support it, because we're a bunch of
|
||||
* professional software developers.
|
||||
*
|
||||
* Try poking it first, without any expectations that it will work.
|
||||
* If it's not there, we thankfully have other bonghits to try next.
|
||||
*/
|
||||
ret = output_get_connector_type_from_prop (manager_xrandr, output);
|
||||
if (ret != META_CONNECTOR_TYPE_Unknown)
|
||||
return ret;
|
||||
|
||||
/* Fall back to heuristics based on the output name. */
|
||||
ret = output_get_connector_type_from_name (manager_xrandr, output);
|
||||
if (ret != META_CONNECTOR_TYPE_Unknown)
|
||||
return ret;
|
||||
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -338,12 +552,6 @@ get_xmode_name (XRRModeInfo *xmode)
|
||||
int width = xmode->width;
|
||||
int height = xmode->height;
|
||||
|
||||
if (xmode->hSkew != 0)
|
||||
{
|
||||
width += 2 * (xmode->hSkew >> 8);
|
||||
height += 2 * (xmode->hSkew & 0xff);
|
||||
}
|
||||
|
||||
return g_strdup_printf ("%dx%d", width, height);
|
||||
}
|
||||
|
||||
@@ -480,45 +688,21 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
if (output->connection != RR_Disconnected)
|
||||
{
|
||||
GBytes *edid;
|
||||
MonitorInfo *parsed_edid;
|
||||
|
||||
meta_output->winsys_id = resources->outputs[i];
|
||||
meta_output->name = g_strdup (output->name);
|
||||
|
||||
edid = read_output_edid (manager_xrandr, meta_output->winsys_id);
|
||||
if (edid)
|
||||
{
|
||||
gsize len;
|
||||
meta_output_parse_edid (meta_output, edid);
|
||||
g_bytes_unref (edid);
|
||||
|
||||
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
|
||||
if (parsed_edid)
|
||||
{
|
||||
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
if (parsed_edid->dsc_product_name[0])
|
||||
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
else
|
||||
meta_output->product = g_strdup_printf ("0x%04x", (unsigned)parsed_edid->product_code);
|
||||
if (parsed_edid->dsc_serial_number[0])
|
||||
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
else
|
||||
meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
|
||||
|
||||
g_free (parsed_edid);
|
||||
}
|
||||
|
||||
g_bytes_unref (edid);
|
||||
}
|
||||
|
||||
if (!meta_output->vendor)
|
||||
{
|
||||
meta_output->vendor = g_strdup ("unknown");
|
||||
meta_output->product = g_strdup ("unknown");
|
||||
meta_output->serial = g_strdup ("unknown");
|
||||
}
|
||||
meta_output->width_mm = output->mm_width;
|
||||
meta_output->height_mm = output->mm_height;
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
|
||||
meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output);
|
||||
meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
|
||||
meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
@@ -812,26 +996,12 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
unsigned int j, n_outputs;
|
||||
int width, height;
|
||||
Status ok;
|
||||
unsigned long old_controlled_mask;
|
||||
unsigned long new_controlled_mask;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
|
||||
n_outputs = crtc_info->outputs->len;
|
||||
outputs = g_new (XID, n_outputs);
|
||||
|
||||
old_controlled_mask = 0;
|
||||
for (j = 0; j < manager->n_outputs; j++)
|
||||
{
|
||||
MetaOutput *output;
|
||||
|
||||
output = &manager->outputs[j];
|
||||
|
||||
if (output->crtc == crtc)
|
||||
old_controlled_mask |= 1UL << j;
|
||||
}
|
||||
|
||||
new_controlled_mask = 0;
|
||||
for (j = 0; j < n_outputs; j++)
|
||||
{
|
||||
MetaOutput *output;
|
||||
@@ -840,21 +1010,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
new_controlled_mask |= 1UL << j;
|
||||
|
||||
outputs[j] = output->winsys_id;
|
||||
}
|
||||
|
||||
if (crtc->current_mode == mode &&
|
||||
crtc->rect.x == crtc_info->x &&
|
||||
crtc->rect.y == crtc_info->y &&
|
||||
crtc->transform == crtc_info->transform &&
|
||||
old_controlled_mask == new_controlled_mask)
|
||||
{
|
||||
/* No change */
|
||||
goto next;
|
||||
}
|
||||
|
||||
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
manager_xrandr->resources,
|
||||
(XID)crtc->crtc_id,
|
||||
@@ -866,7 +1025,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
if (ok != Success)
|
||||
{
|
||||
meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transfrom %u failed\n",
|
||||
meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n",
|
||||
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
|
||||
mode->width, mode->height, (float)mode->refresh_rate,
|
||||
crtc_info->x, crtc_info->y, crtc_info->transform);
|
||||
@@ -1059,15 +1218,12 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
||||
gboolean hotplug;
|
||||
Time old_timestamp;
|
||||
|
||||
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
||||
return FALSE;
|
||||
|
||||
XRRUpdateConfiguration (event);
|
||||
|
||||
old_timestamp = manager_xrandr->resources->timestamp;
|
||||
|
||||
meta_monitor_manager_read_current_config (manager);
|
||||
|
||||
hotplug = manager_xrandr->resources->timestamp < manager_xrandr->resources->configTimestamp;
|
||||
@@ -1078,9 +1234,8 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If something else changed -- tell the world about it. */
|
||||
if (old_timestamp < manager_xrandr->resources->timestamp)
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
/* Something else changed -- tell the world about it. */
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_MANAGER_XRANDR_H
|
||||
#define META_MONITOR_MANAGER_XRANDR_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_XRANDR (meta_monitor_manager_xrandr_get_type ())
|
||||
#define META_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandr))
|
||||
|
@@ -614,6 +614,7 @@ set_unredirected_window (MetaCompositor *compositor,
|
||||
meta_window_actor_set_unredirected (window_actor, FALSE);
|
||||
}
|
||||
|
||||
meta_shape_cow_for_window (compositor, window);
|
||||
compositor->unredirected_window = window;
|
||||
|
||||
if (compositor->unredirected_window != NULL)
|
||||
@@ -621,8 +622,6 @@ set_unredirected_window (MetaCompositor *compositor,
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (compositor->unredirected_window));
|
||||
meta_window_actor_set_unredirected (window_actor, TRUE);
|
||||
}
|
||||
|
||||
meta_shape_cow_for_window (compositor, compositor->unredirected_window);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "compositor-private.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
|
||||
|
||||
|
@@ -49,6 +49,8 @@ meta_surface_actor_pick (ClutterActor *actor,
|
||||
{
|
||||
MetaSurfaceActor *self = META_SURFACE_ACTOR (actor);
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
|
||||
if (!clutter_actor_should_pick_paint (actor))
|
||||
return;
|
||||
@@ -65,8 +67,6 @@ meta_surface_actor_pick (ClutterActor *actor,
|
||||
CoglContext *ctx;
|
||||
CoglFramebuffer *fb;
|
||||
CoglColor cogl_color;
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (priv->input_region);
|
||||
rectangles = g_alloca (sizeof (float) * 4 * n_rects);
|
||||
@@ -93,12 +93,12 @@ meta_surface_actor_pick (ClutterActor *actor,
|
||||
cogl_pipeline_set_color (pipeline, &cogl_color);
|
||||
cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects);
|
||||
cogl_object_unref (pipeline);
|
||||
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-texture-rectangle.h"
|
||||
#include "region-utils.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
#include "meta-cullable.h"
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
@@ -100,7 +100,7 @@ struct _MetaWindowActorPrivate
|
||||
guint disposed : 1;
|
||||
|
||||
/* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN
|
||||
* client message using the most recent frame in ->frames */
|
||||
* client message for one or more messages in ->frames */
|
||||
guint needs_frame_drawn : 1;
|
||||
guint repaint_scheduled : 1;
|
||||
|
||||
@@ -118,10 +118,21 @@ struct _MetaWindowActorPrivate
|
||||
|
||||
typedef struct _FrameData FrameData;
|
||||
|
||||
/* Each time the application updates the sync request counter to a new even value
|
||||
* value, we queue a frame into the windows list of frames. Once we're painting
|
||||
* an update "in response" to the window, we fill in frame_counter with the
|
||||
* Cogl counter for that frame, and send _NET_WM_FRAME_DRAWN at the end of the
|
||||
* frame. _NET_WM_FRAME_TIMINGS is sent when we get a frame_complete callback.
|
||||
*
|
||||
* As an exception, if a window is completely obscured, we try to throttle drawning
|
||||
* to a slower frame rate. In this case, frame_counter stays -1 until
|
||||
* send_frame_message_timeout() runs, at which point we send both the
|
||||
* _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages.
|
||||
*/
|
||||
struct _FrameData
|
||||
{
|
||||
int64_t frame_counter;
|
||||
guint64 sync_request_serial;
|
||||
int64_t frame_counter;
|
||||
gint64 frame_drawn_time;
|
||||
};
|
||||
|
||||
@@ -655,6 +666,30 @@ clip_shadow_under_window (MetaWindowActor *self)
|
||||
return is_non_opaque (self) && priv->window->frame;
|
||||
}
|
||||
|
||||
static void
|
||||
assign_frame_counter_to_frames (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
GList *l;
|
||||
|
||||
/* If the window is obscured, then we're expecting to deal with sending
|
||||
* frame messages in a timeout, rather than in this paint cycle.
|
||||
*/
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
return;
|
||||
|
||||
for (l = priv->frames; l; l = l->next)
|
||||
{
|
||||
FrameData *frame = l->data;
|
||||
|
||||
if (frame->frame_counter == -1)
|
||||
{
|
||||
CoglOnscreen *onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer());
|
||||
frame->frame_counter = cogl_onscreen_get_frame_counter (onscreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_paint (ClutterActor *actor)
|
||||
{
|
||||
@@ -671,6 +706,8 @@ meta_window_actor_paint (ClutterActor *actor)
|
||||
{
|
||||
g_source_remove (priv->send_frame_messages_timer);
|
||||
priv->send_frame_messages_timer = 0;
|
||||
|
||||
assign_frame_counter_to_frames (self);
|
||||
}
|
||||
|
||||
if (shadow != NULL)
|
||||
@@ -873,16 +910,27 @@ send_frame_messages_timeout (gpointer data)
|
||||
{
|
||||
MetaWindowActor *self = (MetaWindowActor *) data;
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
FrameData *frame = g_slice_new0 (FrameData);
|
||||
GList *l;
|
||||
|
||||
frame->sync_request_serial = priv->window->sync_request_serial;
|
||||
for (l = priv->frames; l;)
|
||||
{
|
||||
GList *l_next = l->next;
|
||||
FrameData *frame = l->data;
|
||||
|
||||
do_send_frame_drawn (self, frame);
|
||||
do_send_frame_timings (self, frame, 0, 0);
|
||||
if (frame->frame_counter == -1)
|
||||
{
|
||||
do_send_frame_drawn (self, frame);
|
||||
do_send_frame_timings (self, frame, 0, 0);
|
||||
|
||||
priv->frames = g_list_delete_link (priv->frames, l);
|
||||
frame_data_free (frame);
|
||||
}
|
||||
|
||||
l = l_next;
|
||||
}
|
||||
|
||||
priv->needs_frame_drawn = FALSE;
|
||||
priv->send_frame_messages_timer = 0;
|
||||
frame_data_free (frame);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -891,6 +939,10 @@ static void
|
||||
queue_send_frame_messages_timeout (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
return;
|
||||
|
||||
MetaDisplay *display = meta_window_get_display (priv->window);
|
||||
gint64 current_time = meta_compositor_monotonic_time_to_server_time (display, g_get_monotonic_time ());
|
||||
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
|
||||
@@ -933,6 +985,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
return;
|
||||
|
||||
frame = g_slice_new0 (FrameData);
|
||||
frame->frame_counter = -1;
|
||||
|
||||
priv->needs_frame_drawn = TRUE;
|
||||
|
||||
@@ -1155,7 +1208,7 @@ gboolean
|
||||
meta_window_actor_should_unredirect (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
if (priv->surface)
|
||||
if (!meta_window_actor_is_destroyed (self) && priv->surface)
|
||||
return meta_surface_actor_should_unredirect (priv->surface);
|
||||
else
|
||||
return FALSE;
|
||||
@@ -1905,24 +1958,12 @@ meta_window_actor_handle_updates (MetaWindowActor *self)
|
||||
void
|
||||
meta_window_actor_pre_paint (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
GList *l;
|
||||
|
||||
if (meta_window_actor_is_destroyed (self))
|
||||
return;
|
||||
|
||||
meta_window_actor_handle_updates (self);
|
||||
|
||||
for (l = priv->frames; l != NULL; l = l->next)
|
||||
{
|
||||
FrameData *frame = l->data;
|
||||
|
||||
if (frame->frame_counter == 0)
|
||||
{
|
||||
CoglOnscreen *onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer());
|
||||
frame->frame_counter = cogl_onscreen_get_frame_counter (onscreen);
|
||||
}
|
||||
}
|
||||
assign_frame_counter_to_frames (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1963,16 +2004,23 @@ meta_window_actor_post_paint (MetaWindowActor *self)
|
||||
if (meta_window_actor_is_destroyed (self))
|
||||
return;
|
||||
|
||||
/* This window had damage, but wasn't actually redrawn because
|
||||
* it is obscured. So we should wait until timer expiration
|
||||
* before sending _NET_WM_FRAME_* messages.
|
||||
*/
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
return;
|
||||
|
||||
if (priv->needs_frame_drawn)
|
||||
/* If the window had damage, but wasn't actually redrawn because
|
||||
* it is obscured, we should wait until timer expiration before
|
||||
* sending _NET_WM_FRAME_* messages.
|
||||
*/
|
||||
if (priv->send_frame_messages_timer == 0 &&
|
||||
priv->needs_frame_drawn)
|
||||
{
|
||||
do_send_frame_drawn (self, priv->frames->data);
|
||||
GList *l;
|
||||
|
||||
for (l = priv->frames; l; l = l->next)
|
||||
{
|
||||
FrameData *frame = l->data;
|
||||
|
||||
if (frame->frame_drawn_time == 0)
|
||||
do_send_frame_drawn (self, frame);
|
||||
}
|
||||
|
||||
priv->needs_frame_drawn = FALSE;
|
||||
}
|
||||
|
||||
@@ -2057,15 +2105,20 @@ meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
{
|
||||
GList *l_next = l->next;
|
||||
FrameData *frame = l->data;
|
||||
gint64 frame_counter = cogl_frame_info_get_frame_counter (frame_info);
|
||||
|
||||
if (frame->frame_counter == cogl_frame_info_get_frame_counter (frame_info))
|
||||
if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter)
|
||||
{
|
||||
if (frame->frame_drawn_time != 0)
|
||||
{
|
||||
priv->frames = g_list_delete_link (priv->frames, l);
|
||||
send_frame_timings (self, frame, frame_info, presentation_time);
|
||||
frame_data_free (frame);
|
||||
}
|
||||
if (G_UNLIKELY (frame->frame_drawn_time == 0))
|
||||
g_warning ("%s: Frame has assigned frame counter but no frame drawn time",
|
||||
priv->window->desc);
|
||||
if (G_UNLIKELY (frame->frame_counter < frame_counter))
|
||||
g_warning ("%s: frame_complete callback never occurred for frame %" G_GINT64_FORMAT,
|
||||
priv->window->desc, frame->frame_counter);
|
||||
|
||||
priv->frames = g_list_delete_link (priv->frames, l);
|
||||
send_frame_timings (self, frame, frame_info, presentation_time);
|
||||
frame_data_free (frame);
|
||||
}
|
||||
|
||||
l = l_next;
|
||||
|
@@ -24,8 +24,8 @@ pkglib_LTLIBRARIES = default.la
|
||||
# (There is no way to stop libtool generating static libs locally, and we
|
||||
# cannot do this globally because of libmutter-private.so).
|
||||
install-exec-hook:
|
||||
-rm $(DESTDIR)$(pkglibdir)/*.a
|
||||
-rm $(DESTDIR)$(pkglibdir)/*.la
|
||||
-rm -f $(DESTDIR)$(pkglibdir)/*.a
|
||||
-rm -f $(DESTDIR)$(pkglibdir)/*.la
|
||||
|
||||
# Since we removed the .la file, 'make uninstall' doesn't work properly,
|
||||
# since it counts on libtool to remove the .la files, so just kill the
|
||||
|
@@ -328,17 +328,17 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
info->orig = *orig;
|
||||
info->current = *new;
|
||||
|
||||
if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
|
||||
if (flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_RESIZE_ACTION)
|
||||
info->action_type = ACTION_MOVE_AND_RESIZE;
|
||||
else if (flags & META_IS_RESIZE_ACTION)
|
||||
else if (flags & META_MOVE_RESIZE_RESIZE_ACTION)
|
||||
info->action_type = ACTION_RESIZE;
|
||||
else if (flags & META_IS_MOVE_ACTION)
|
||||
else if (flags & META_MOVE_RESIZE_MOVE_ACTION)
|
||||
info->action_type = ACTION_MOVE;
|
||||
else
|
||||
g_error ("BAD, BAD developer! No treat for you! (Fix your calls to "
|
||||
"meta_window_move_resize_internal()).\n");
|
||||
|
||||
info->is_user_action = (flags & META_IS_USER_ACTION);
|
||||
info->is_user_action = (flags & META_MOVE_RESIZE_USER_ACTION);
|
||||
|
||||
info->resize_gravity = resize_gravity;
|
||||
|
||||
@@ -1017,6 +1017,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
double best_width, best_height;
|
||||
double alt_width, alt_height;
|
||||
MetaRectangle *start_rect;
|
||||
MetaRectangle client_rect;
|
||||
|
||||
if (priority > PRIORITY_ASPECT_RATIO)
|
||||
return TRUE;
|
||||
@@ -1068,15 +1069,18 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
fudge = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &info->current, &client_rect);
|
||||
|
||||
constraint_already_satisfied =
|
||||
info->current.width - (info->current.height * minr ) > -minr*fudge &&
|
||||
info->current.width - (info->current.height * maxr ) < maxr*fudge;
|
||||
client_rect.width - (client_rect.height * minr ) > -minr*fudge &&
|
||||
client_rect.width - (client_rect.height * maxr ) < maxr*fudge;
|
||||
if (check_only || constraint_already_satisfied)
|
||||
return constraint_already_satisfied;
|
||||
|
||||
/*** Enforce constraint ***/
|
||||
new_width = info->current.width;
|
||||
new_height = info->current.height;
|
||||
new_width = client_rect.width;
|
||||
new_height = client_rect.height;
|
||||
|
||||
switch (info->resize_gravity)
|
||||
{
|
||||
@@ -1123,6 +1127,14 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
client_rect.width = new_width;
|
||||
client_rect.height = new_height;
|
||||
meta_window_client_rect_to_frame_rect (window, &client_rect, &client_rect);
|
||||
new_width = client_rect.width;
|
||||
new_height = client_rect.height;
|
||||
}
|
||||
|
||||
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
|
||||
* See bug 448183
|
||||
*/
|
||||
|
200
src/core/core.c
200
src/core/core.c
@@ -62,87 +62,6 @@ get_window (Display *xdisplay,
|
||||
return window;
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_get (Display *xdisplay,
|
||||
Window xwindow,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
MetaCoreGetType request;
|
||||
|
||||
MetaDisplay *display = meta_display_for_x_display (xdisplay);
|
||||
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
va_start (args, xwindow);
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
|
||||
/* Now, we special-case the first request slightly. Mostly, requests
|
||||
* for information on windows which have no frame are errors.
|
||||
* But sometimes we may want to know *whether* a window has a frame.
|
||||
* In this case, pass the key META_CORE_WINDOW_HAS_FRAME
|
||||
* as the *first* request, with a pointer to a boolean; if the window
|
||||
* has no frame, this will be set to False and meta_core_get will
|
||||
* exit immediately (so the values of any other requests will be
|
||||
* undefined). Otherwise it will be set to True and meta_core_get will
|
||||
* continue happily on its way.
|
||||
*/
|
||||
|
||||
if (request != META_CORE_WINDOW_HAS_FRAME &&
|
||||
(window == NULL || window->frame == NULL))
|
||||
{
|
||||
meta_bug ("No such frame window 0x%lx!\n", xwindow);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (request != META_CORE_GET_END)
|
||||
{
|
||||
gpointer answer = va_arg (args, gpointer);
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case META_CORE_WINDOW_HAS_FRAME:
|
||||
*((gboolean*)answer) = window != NULL && window->frame != NULL;
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = priv->client_rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = priv->client_rect.height;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_TYPE:
|
||||
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
|
||||
break;
|
||||
case META_CORE_GET_MINI_ICON:
|
||||
*((GdkPixbuf**)answer) = window->mini_icon;
|
||||
break;
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_RECT:
|
||||
meta_window_get_frame_rect (window, ((MetaRectangle*)answer));
|
||||
break;
|
||||
case META_CORE_GET_THEME_VARIANT:
|
||||
*((char**)answer) = window->gtk_theme_variant;
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning("Unknown window information request: %d\n", request);
|
||||
}
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
}
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_queue_frame_resize (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
@@ -161,8 +80,7 @@ lower_window_and_transients (MetaWindow *window,
|
||||
|
||||
meta_window_foreach_transient (window, lower_window_and_transients, NULL);
|
||||
|
||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
|
||||
meta_prefs_get_raise_on_click ())
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
{
|
||||
/* Move window to the back of the focusing workspace's MRU list.
|
||||
* Do extra sanity checks to avoid possible race conditions.
|
||||
@@ -209,37 +127,6 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_focus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_focus (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_minimize (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_minimize (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_maximize (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_toggle_maximize_vertically (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
@@ -285,84 +172,6 @@ meta_core_toggle_maximize (Display *xdisplay,
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unmaximize (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_delete (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_delete (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unshade (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_unshade (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_shade (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_shade (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unstick (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_unstick (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_make_above (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_make_above (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unmake_above (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_unmake_above (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_stick (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_stick (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_change_workspace (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -497,3 +306,10 @@ meta_invalidate_default_icons (void)
|
||||
{
|
||||
/* XXX: Actually invalidate the icons when they're used. */
|
||||
}
|
||||
|
||||
void
|
||||
meta_retheme_all (void)
|
||||
{
|
||||
if (meta_get_display ())
|
||||
meta_display_retheme_all ();
|
||||
}
|
||||
|
@@ -28,60 +28,6 @@
|
||||
#include <meta/common.h>
|
||||
#include <meta/boxes.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_CORE_GET_END = 0,
|
||||
META_CORE_WINDOW_HAS_FRAME,
|
||||
META_CORE_GET_CLIENT_WIDTH,
|
||||
META_CORE_GET_CLIENT_HEIGHT,
|
||||
META_CORE_GET_FRAME_FLAGS,
|
||||
META_CORE_GET_FRAME_TYPE,
|
||||
META_CORE_GET_MINI_ICON,
|
||||
META_CORE_GET_ICON,
|
||||
META_CORE_GET_FRAME_RECT,
|
||||
META_CORE_GET_THEME_VARIANT,
|
||||
} MetaCoreGetType;
|
||||
|
||||
/* General information function about the given window. Pass in a sequence of
|
||||
* pairs of MetaCoreGetTypes and pointers to variables; the variables will be
|
||||
* filled with the requested values. End the list with META_CORE_GET_END.
|
||||
* For example:
|
||||
*
|
||||
* meta_core_get (my_display, my_window,
|
||||
* META_CORE_GET_FRAME_WIDTH, &width,
|
||||
* META_CORE_GET_FRAME_HEIGHT, &height,
|
||||
* META_CORE_GET_END);
|
||||
*
|
||||
* If the window doesn't have a frame, this will raise a meta_bug. To suppress
|
||||
* this behaviour, ask META_CORE_WINDOW_HAS_FRAME as the *first* question in
|
||||
* the list. If the window has no frame, the answer to this question will be
|
||||
* False, and anything else you asked will be undefined. Otherwise, the answer
|
||||
* will be True. The answer will necessarily be True if you ask the question
|
||||
* in any other position. The positions of all other questions don't matter.
|
||||
*
|
||||
* The reason for this function is that some parts of the program don't know
|
||||
* about MetaWindows. But they *can* see core.h. So we used to have a whole
|
||||
* load of functions which took a display and an X window, looked up the
|
||||
* relevant MetaWindow, and returned information about it. The trouble with
|
||||
* that is that looking up the MetaWindow is a nontrivial operation, and
|
||||
* consolidating the calls in this way makes (for example) frame exposes
|
||||
* 33% faster, according to valgrind.
|
||||
*
|
||||
* This function would perhaps be slightly better if the questions were
|
||||
* represented by pointers, perhaps gchar*s, because then we could take
|
||||
* advantage of gcc's automatic sentinel checking. On the other hand, this
|
||||
* immediately suggests string comparison, and that's slow.
|
||||
*
|
||||
* Another possible improvement is that core.h still has a bunch of
|
||||
* functions which can't be described by the formula "give a display and
|
||||
* an X window, get a single value" (meta_core_user_move, for example), but
|
||||
* which could theoretically be handled by this function if we relaxed the
|
||||
* requirement that all questions should have exactly one argument.
|
||||
*/
|
||||
void meta_core_get (Display *xdisplay,
|
||||
Window window,
|
||||
...);
|
||||
|
||||
void meta_core_queue_frame_resize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
@@ -89,39 +35,12 @@ void meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_user_focus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_minimize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_toggle_maximize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_toggle_maximize_horizontally (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_toggle_maximize_vertically (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_unmaximize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_maximize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_delete (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
void meta_core_unshade (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
void meta_core_shade (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
void meta_core_unstick (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_stick (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_unmake_above (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_make_above (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_change_workspace (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int new_workspace);
|
||||
@@ -168,5 +87,6 @@ void meta_core_set_screen_cursor (Display *xdisplay,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_invalidate_default_icons (void);
|
||||
void meta_retheme_all (void);
|
||||
|
||||
#endif
|
||||
|
@@ -85,6 +85,10 @@ typedef enum {
|
||||
* Events go to windows normally. */
|
||||
META_EVENT_ROUTE_NORMAL,
|
||||
|
||||
/* In a window operation like moving or resizing. All events
|
||||
* goes to MetaWindow, but not to the actual client window. */
|
||||
META_EVENT_ROUTE_WINDOW_OP,
|
||||
|
||||
/* In a compositor grab operation. All events go to the
|
||||
* compositor plugin. */
|
||||
META_EVENT_ROUTE_COMPOSITOR_GRAB,
|
||||
@@ -93,9 +97,8 @@ typedef enum {
|
||||
* the Wayland application. */
|
||||
META_EVENT_ROUTE_WAYLAND_POPUP,
|
||||
|
||||
/* In a window operation like moving or resizing. All events
|
||||
* goes to MetaWindow, but not to the actual client window. */
|
||||
META_EVENT_ROUTE_WINDOW_OP,
|
||||
/* The user is clicking on a window button. */
|
||||
META_EVENT_ROUTE_FRAME_BUTTON,
|
||||
} MetaEventRoute;
|
||||
|
||||
typedef gboolean (*MetaAlarmFilter) (MetaDisplay *display,
|
||||
@@ -175,7 +178,6 @@ struct _MetaDisplay
|
||||
* ignore
|
||||
*/
|
||||
unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS];
|
||||
Window ungrab_should_not_cause_focus_window;
|
||||
|
||||
guint32 current_time;
|
||||
|
||||
@@ -448,8 +450,8 @@ void meta_display_accelerator_activate (MetaDisplay *display,
|
||||
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
gboolean meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIEvent *event);
|
||||
gboolean meta_display_process_barrier_xevent (MetaDisplay *display,
|
||||
XIEvent *event);
|
||||
#endif /* HAVE_XI23 */
|
||||
|
||||
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
||||
@@ -478,6 +480,12 @@ gboolean meta_display_show_restart_message (MetaDisplay *display,
|
||||
const char *message);
|
||||
gboolean meta_display_request_restart (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_show_resize_popup (MetaDisplay *display,
|
||||
gboolean show,
|
||||
MetaRectangle *rect,
|
||||
int display_w,
|
||||
int display_h);
|
||||
|
||||
void meta_restart_init (void);
|
||||
void meta_restart_finish (void);
|
||||
|
||||
|
@@ -50,6 +50,7 @@
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
@@ -122,6 +123,7 @@ enum
|
||||
GRAB_OP_END,
|
||||
SHOW_RESTART_MESSAGE,
|
||||
RESTART,
|
||||
SHOW_RESIZE_POPUP,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -329,6 +331,16 @@ meta_display_class_init (MetaDisplayClass *klass)
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 0);
|
||||
|
||||
display_signals[SHOW_RESIZE_POPUP] =
|
||||
g_signal_new ("show-resize-popup",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 4,
|
||||
G_TYPE_BOOLEAN, META_TYPE_RECTANGLE, G_TYPE_INT, G_TYPE_INT);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FOCUS_WINDOW,
|
||||
g_param_spec_object ("focus-window",
|
||||
@@ -640,7 +652,6 @@ meta_display_open (void)
|
||||
display->ignored_crossing_serials[i] = 0;
|
||||
++i;
|
||||
}
|
||||
display->ungrab_should_not_cause_focus_window = None;
|
||||
|
||||
display->current_time = CurrentTime;
|
||||
display->sentinel_counter = 0;
|
||||
@@ -1205,7 +1216,7 @@ meta_grab_op_is_resizing (MetaGrabOp op)
|
||||
if (!grab_op_is_window (op))
|
||||
return FALSE;
|
||||
|
||||
return (op & META_GRAB_OP_WINDOW_DIR_MASK) != 0;
|
||||
return (op & META_GRAB_OP_WINDOW_DIR_MASK) != 0 || op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1214,7 +1225,7 @@ meta_grab_op_is_moving (MetaGrabOp op)
|
||||
if (!grab_op_is_window (op))
|
||||
return FALSE;
|
||||
|
||||
return (op & META_GRAB_OP_WINDOW_DIR_MASK) == 0;
|
||||
return !meta_grab_op_is_resizing (op);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1791,6 +1802,9 @@ get_event_route_from_grab_op (MetaGrabOp op)
|
||||
case META_GRAB_OP_WAYLAND_POPUP:
|
||||
return META_EVENT_ROUTE_WAYLAND_POPUP;
|
||||
|
||||
case META_GRAB_OP_FRAME_BUTTON:
|
||||
return META_EVENT_ROUTE_FRAME_BUTTON;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -1953,6 +1967,11 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
|
||||
display->screen, grab_window, grab_op);
|
||||
|
||||
/* We need to reset this early, since the
|
||||
* meta_window_grab_op_ended callback relies on this being
|
||||
* up to date. */
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
/* Clear out the edge cache */
|
||||
@@ -1985,7 +2004,6 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
}
|
||||
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
display->grab_tile_mode = META_TILE_NONE;
|
||||
display->grab_tile_monitor_number = -1;
|
||||
@@ -2892,9 +2910,11 @@ meta_display_get_xinput_opcode (MetaDisplay *display)
|
||||
* meta_display_supports_extended_barriers:
|
||||
* @display: a #MetaDisplay
|
||||
*
|
||||
* Returns: whether the X server supports extended barrier
|
||||
* features as defined in version 2.3 of the XInput 2
|
||||
* specification.
|
||||
* Returns: whether pointer barriers can be supported.
|
||||
*
|
||||
* When running as an X compositor the X server needs XInput 2
|
||||
* version 2.3. When running as a display server it is supported
|
||||
* when running on the native backend.
|
||||
*
|
||||
* Clients should use this method to determine whether their
|
||||
* interfaces should depend on new barrier features.
|
||||
@@ -2902,7 +2922,18 @@ meta_display_get_xinput_opcode (MetaDisplay *display)
|
||||
gboolean
|
||||
meta_display_supports_extended_barriers (MetaDisplay *display)
|
||||
{
|
||||
return META_DISPLAY_HAS_XINPUT_23 (display) && !meta_is_wayland_compositor ();
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (META_IS_BACKEND_NATIVE (meta_get_backend ()))
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
if (META_IS_BACKEND_X11 (meta_get_backend ()))
|
||||
{
|
||||
return (META_DISPLAY_HAS_XINPUT_23 (display) &&
|
||||
!meta_is_wayland_compositor());
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3014,6 +3045,22 @@ meta_display_request_restart (MetaDisplay *display)
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_show_resize_popup (MetaDisplay *display,
|
||||
gboolean show,
|
||||
MetaRectangle *rect,
|
||||
int display_w,
|
||||
int display_h)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
g_signal_emit (display,
|
||||
display_signals[SHOW_RESIZE_POPUP], 0,
|
||||
show, rect, display_w, display_h, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_is_pointer_emulating_sequence:
|
||||
* @display: the display
|
||||
|
@@ -66,9 +66,10 @@ get_window_for_event (MetaDisplay *display,
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
case META_EVENT_ROUTE_WINDOW_OP:
|
||||
case META_EVENT_ROUTE_COMPOSITOR_GRAB:
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
case META_EVENT_ROUTE_FRAME_BUTTON:
|
||||
return display->grab_window;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -261,7 +262,8 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
* event, and if it doesn't, replay the event to release our
|
||||
* own sync grab. */
|
||||
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP ||
|
||||
display->event_route == META_EVENT_ROUTE_FRAME_BUTTON)
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
|
107
src/core/frame.c
107
src/core/frame.c
@@ -85,15 +85,18 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
else
|
||||
visual = NULL;
|
||||
|
||||
frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
|
||||
window->display->xdisplay,
|
||||
visual,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
frame->rect.height,
|
||||
frame->window->screen->number,
|
||||
&create_serial);
|
||||
frame->ui_frame = meta_ui_create_frame (window->screen->ui,
|
||||
window->display->xdisplay,
|
||||
frame->window,
|
||||
visual,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
frame->rect.height,
|
||||
frame->window->screen->number,
|
||||
&create_serial);
|
||||
frame->xwindow = frame->ui_frame->xwindow;
|
||||
|
||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||
frame->xwindow,
|
||||
create_serial);
|
||||
@@ -103,19 +106,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
XChangeWindowAttributes (window->display->xdisplay,
|
||||
frame->xwindow, CWEventMask, &attrs);
|
||||
|
||||
{
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
|
||||
XISelectEvents (window->display->xdisplay, frame->xwindow, &mask, 1);
|
||||
}
|
||||
|
||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
@@ -146,12 +136,8 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
/* Now that frame->xwindow is registered with window, we can set its
|
||||
* style and background.
|
||||
*/
|
||||
meta_ui_update_frame_style (window->screen->ui, frame->xwindow);
|
||||
|
||||
if (window->title)
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
meta_frame_update_style (frame);
|
||||
meta_frame_update_title (frame);
|
||||
|
||||
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
|
||||
|
||||
@@ -159,10 +145,23 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
{
|
||||
/* Since the backend takes keygrabs on another connection, make sure
|
||||
* to sync the GTK+ connection to ensure that the frame window has
|
||||
* been created on the server at this point. */
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
|
||||
/* Since the backend selects for events on another connection,
|
||||
* make sure to sync the GTK+ connection to ensure that the
|
||||
* frame window has been created on the server at this point. */
|
||||
XSync (window->display->xdisplay, False);
|
||||
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
|
||||
XISelectEvents (xdisplay, frame->xwindow, &mask, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +214,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
window->frame->rect.y + borders.invisible.top);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
|
||||
meta_ui_frame_unmanage (frame->ui_frame);
|
||||
|
||||
meta_display_unregister_x_window (window->display,
|
||||
frame->xwindow);
|
||||
@@ -335,9 +334,7 @@ meta_frame_calc_borders (MetaFrame *frame,
|
||||
{
|
||||
if (!frame->borders_cached)
|
||||
{
|
||||
meta_ui_get_frame_borders (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
&frame->cached_borders);
|
||||
meta_ui_frame_get_borders (frame->ui_frame, &frame->cached_borders);
|
||||
frame->borders_cached = TRUE;
|
||||
}
|
||||
|
||||
@@ -353,8 +350,6 @@ meta_frame_clear_cached_borders (MetaFrame *frame)
|
||||
|
||||
gboolean
|
||||
meta_frame_sync_to_window (MetaFrame *frame,
|
||||
int resize_gravity,
|
||||
gboolean need_move,
|
||||
gboolean need_resize)
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
@@ -364,49 +359,32 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
frame->rect.x + frame->rect.width,
|
||||
frame->rect.y + frame->rect.height);
|
||||
|
||||
meta_ui_move_resize_frame (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
meta_ui_frame_move_resize (frame->ui_frame,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
|
||||
if (need_resize)
|
||||
{
|
||||
/* If we're interactively resizing the frame, repaint
|
||||
* it immediately so we don't start to lag.
|
||||
*/
|
||||
if (frame->window->display->grab_window ==
|
||||
frame->window)
|
||||
meta_ui_repaint_frame (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
}
|
||||
|
||||
return need_resize;
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_frame_get_frame_bounds (MetaFrame *frame)
|
||||
{
|
||||
return meta_ui_get_frame_bounds (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
return meta_ui_frame_get_bounds (frame->ui_frame);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_get_mask (MetaFrame *frame,
|
||||
cairo_t *cr)
|
||||
{
|
||||
meta_ui_get_frame_mask (frame->window->screen->ui, frame->xwindow,
|
||||
frame->rect.width, frame->rect.height, cr);
|
||||
meta_ui_frame_get_mask (frame->ui_frame, cr);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_queue_draw (MetaFrame *frame)
|
||||
{
|
||||
meta_ui_queue_frame_draw (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
meta_ui_frame_queue_draw (frame->ui_frame);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -433,3 +411,16 @@ meta_frame_get_xwindow (MetaFrame *frame)
|
||||
{
|
||||
return frame->xwindow;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_update_style (MetaFrame *frame)
|
||||
{
|
||||
meta_ui_frame_update_style (frame->ui_frame);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_update_title (MetaFrame *frame)
|
||||
{
|
||||
if (frame->window->title)
|
||||
meta_ui_frame_set_title (frame->ui_frame, frame->window->title);
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "window-private.h"
|
||||
|
||||
#include "ui/frames.h"
|
||||
|
||||
struct _MetaFrame
|
||||
{
|
||||
/* window we frame */
|
||||
@@ -50,6 +52,8 @@ struct _MetaFrame
|
||||
guint need_reapply_frame_shape : 1;
|
||||
guint is_flashing : 1; /* used by the visual bell flash */
|
||||
guint borders_cached : 1;
|
||||
|
||||
MetaUIFrame *ui_frame;
|
||||
};
|
||||
|
||||
void meta_window_ensure_frame (MetaWindow *window);
|
||||
@@ -64,8 +68,6 @@ void meta_frame_calc_borders (MetaFrame *frame,
|
||||
MetaFrameBorders *borders);
|
||||
|
||||
gboolean meta_frame_sync_to_window (MetaFrame *frame,
|
||||
int gravity,
|
||||
gboolean need_move,
|
||||
gboolean need_resize);
|
||||
|
||||
void meta_frame_clear_cached_borders (MetaFrame *frame);
|
||||
@@ -78,8 +80,7 @@ void meta_frame_get_mask (MetaFrame *frame,
|
||||
void meta_frame_set_screen_cursor (MetaFrame *frame,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_frame_update_style (MetaFrame *frame);
|
||||
void meta_frame_update_title (MetaFrame *frame);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -42,16 +42,10 @@ struct _MetaKeyHandler
|
||||
GDestroyNotify user_data_free_func;
|
||||
};
|
||||
|
||||
struct _MetaKeyBinding
|
||||
{
|
||||
const char *name;
|
||||
KeySym keysym;
|
||||
KeyCode keycode;
|
||||
unsigned int mask;
|
||||
MetaVirtualModifier modifiers;
|
||||
gint flags;
|
||||
MetaKeyHandler *handler;
|
||||
};
|
||||
typedef struct _MetaResolvedKeyCombo {
|
||||
xkb_keycode_t keycode;
|
||||
xkb_mod_mask_t mask;
|
||||
} MetaResolvedKeyCombo;
|
||||
|
||||
/**
|
||||
* MetaKeyCombo:
|
||||
@@ -67,6 +61,15 @@ struct _MetaKeyCombo
|
||||
MetaVirtualModifier modifiers;
|
||||
};
|
||||
|
||||
struct _MetaKeyBinding
|
||||
{
|
||||
const char *name;
|
||||
MetaKeyCombo combo;
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
gint flags;
|
||||
MetaKeyHandler *handler;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
@@ -81,9 +84,6 @@ typedef struct
|
||||
*/
|
||||
GSList *combos;
|
||||
|
||||
/* for keybindings that apply only to a window */
|
||||
gboolean per_window:1;
|
||||
|
||||
/* for keybindings not added with meta_display_add_keybinding() */
|
||||
gboolean builtin:1;
|
||||
} MetaKeyPref;
|
||||
@@ -97,8 +97,9 @@ typedef struct
|
||||
xkb_mod_mask_t super_mask;
|
||||
xkb_mod_mask_t meta_mask;
|
||||
MetaKeyCombo overlay_key_combo;
|
||||
MetaResolvedKeyCombo overlay_resolved_key_combo;
|
||||
gboolean overlay_key_only_pressed;
|
||||
MetaKeyCombo *iso_next_group_combos;
|
||||
MetaResolvedKeyCombo *iso_next_group_combos;
|
||||
int n_iso_next_group_combos;
|
||||
|
||||
xkb_level_index_t keymap_num_levels;
|
||||
|
@@ -91,7 +91,7 @@ meta_key_binding_get_name (MetaKeyBinding *binding)
|
||||
MetaVirtualModifier
|
||||
meta_key_binding_get_modifiers (MetaKeyBinding *binding)
|
||||
{
|
||||
return binding->modifiers;
|
||||
return binding->combo.modifiers;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -103,7 +103,7 @@ meta_key_binding_is_reversed (MetaKeyBinding *binding)
|
||||
guint
|
||||
meta_key_binding_get_mask (MetaKeyBinding *binding)
|
||||
{
|
||||
return binding->mask;
|
||||
return binding->resolved_combo.mask;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -153,20 +153,18 @@ typedef struct _MetaKeyGrab MetaKeyGrab;
|
||||
struct _MetaKeyGrab {
|
||||
char *name;
|
||||
guint action;
|
||||
MetaKeyCombo *combo;
|
||||
MetaKeyCombo combo;
|
||||
};
|
||||
|
||||
static void
|
||||
meta_key_grab_free (MetaKeyGrab *grab)
|
||||
{
|
||||
g_free (grab->name);
|
||||
g_free (grab->combo);
|
||||
g_free (grab);
|
||||
}
|
||||
|
||||
static guint32
|
||||
key_binding_key (guint32 keycode,
|
||||
guint32 mask)
|
||||
key_combo_key (MetaResolvedKeyCombo *resolved_combo)
|
||||
{
|
||||
/* On X, keycodes are only 8 bits while libxkbcommon supports 32 bit
|
||||
keycodes, but since we're using the same XKB keymaps that X uses,
|
||||
@@ -176,16 +174,8 @@ key_binding_key (guint32 keycode,
|
||||
can use a 32 bit integer to safely concatenate both keycode and
|
||||
mask and thus making it easy to use them as an index in a
|
||||
GHashTable. */
|
||||
guint32 key = keycode & 0xffff;
|
||||
return (key << 16) | (mask & 0xffff);
|
||||
}
|
||||
|
||||
static const char *
|
||||
keysym_name (xkb_keysym_t keysym)
|
||||
{
|
||||
static char name[32] = "";
|
||||
xkb_keysym_get_name (keysym, name, sizeof (name));
|
||||
return name;
|
||||
guint32 key = resolved_combo->keycode & 0xffff;
|
||||
return (key << 16) | (resolved_combo->mask & 0xffff);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -371,7 +361,7 @@ static void
|
||||
reload_iso_next_group_combos (MetaKeyBindingManager *keys)
|
||||
{
|
||||
const char *iso_next_group_option;
|
||||
MetaKeyCombo *combos;
|
||||
MetaResolvedKeyCombo *combos;
|
||||
int *keycodes;
|
||||
int n_keycodes;
|
||||
int n_combos;
|
||||
@@ -399,39 +389,36 @@ reload_iso_next_group_combos (MetaKeyBindingManager *keys)
|
||||
g_str_equal (iso_next_group_option, "caps_toggle"))
|
||||
{
|
||||
n_combos = n_keycodes;
|
||||
combos = g_new (MetaKeyCombo, n_combos);
|
||||
combos = g_new (MetaResolvedKeyCombo, n_combos);
|
||||
|
||||
for (i = 0; i < n_keycodes; ++i)
|
||||
{
|
||||
combos[i].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i].keycode = keycodes[i];
|
||||
combos[i].modifiers = 0;
|
||||
combos[i].mask = 0;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (iso_next_group_option, "shift_caps_toggle") ||
|
||||
g_str_equal (iso_next_group_option, "shifts_toggle"))
|
||||
{
|
||||
n_combos = n_keycodes;
|
||||
combos = g_new (MetaKeyCombo, n_combos);
|
||||
combos = g_new (MetaResolvedKeyCombo, n_combos);
|
||||
|
||||
for (i = 0; i < n_keycodes; ++i)
|
||||
{
|
||||
combos[i].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i].keycode = keycodes[i];
|
||||
combos[i].modifiers = ShiftMask;
|
||||
combos[i].mask = ShiftMask;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (iso_next_group_option, "alt_caps_toggle") ||
|
||||
g_str_equal (iso_next_group_option, "alt_space_toggle"))
|
||||
{
|
||||
n_combos = n_keycodes;
|
||||
combos = g_new (MetaKeyCombo, n_combos);
|
||||
combos = g_new (MetaResolvedKeyCombo, n_combos);
|
||||
|
||||
for (i = 0; i < n_keycodes; ++i)
|
||||
{
|
||||
combos[i].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i].keycode = keycodes[i];
|
||||
combos[i].modifiers = Mod1Mask;
|
||||
combos[i].mask = Mod1Mask;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (iso_next_group_option, "ctrl_shift_toggle") ||
|
||||
@@ -439,50 +426,44 @@ reload_iso_next_group_combos (MetaKeyBindingManager *keys)
|
||||
g_str_equal (iso_next_group_option, "rctrl_rshift_toggle"))
|
||||
{
|
||||
n_combos = n_keycodes * 2;
|
||||
combos = g_new (MetaKeyCombo, n_combos);
|
||||
combos = g_new (MetaResolvedKeyCombo, n_combos);
|
||||
|
||||
for (i = 0; i < n_keycodes; ++i)
|
||||
{
|
||||
combos[i].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i].keycode = keycodes[i];
|
||||
combos[i].modifiers = ShiftMask;
|
||||
combos[i].mask = ShiftMask;
|
||||
|
||||
combos[i + n_keycodes].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i + n_keycodes].keycode = keycodes[i];
|
||||
combos[i + n_keycodes].modifiers = ControlMask;
|
||||
combos[i + n_keycodes].mask = ControlMask;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (iso_next_group_option, "ctrl_alt_toggle"))
|
||||
{
|
||||
n_combos = n_keycodes * 2;
|
||||
combos = g_new (MetaKeyCombo, n_combos);
|
||||
combos = g_new (MetaResolvedKeyCombo, n_combos);
|
||||
|
||||
for (i = 0; i < n_keycodes; ++i)
|
||||
{
|
||||
combos[i].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i].keycode = keycodes[i];
|
||||
combos[i].modifiers = Mod1Mask;
|
||||
combos[i].mask = Mod1Mask;
|
||||
|
||||
combos[i + n_keycodes].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i + n_keycodes].keycode = keycodes[i];
|
||||
combos[i + n_keycodes].modifiers = ControlMask;
|
||||
combos[i + n_keycodes].mask = ControlMask;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (iso_next_group_option, "alt_shift_toggle") ||
|
||||
g_str_equal (iso_next_group_option, "lalt_lshift_toggle"))
|
||||
{
|
||||
n_combos = n_keycodes * 2;
|
||||
combos = g_new (MetaKeyCombo, n_combos);
|
||||
combos = g_new (MetaResolvedKeyCombo, n_combos);
|
||||
|
||||
for (i = 0; i < n_keycodes; ++i)
|
||||
{
|
||||
combos[i].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i].keycode = keycodes[i];
|
||||
combos[i].modifiers = Mod1Mask;
|
||||
combos[i].mask = Mod1Mask;
|
||||
|
||||
combos[i + n_keycodes].keysym = XKB_KEY_ISO_Next_Group;
|
||||
combos[i + n_keycodes].keycode = keycodes[i];
|
||||
combos[i + n_keycodes].modifiers = ShiftMask;
|
||||
combos[i + n_keycodes].mask = ShiftMask;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -497,41 +478,6 @@ reload_iso_next_group_combos (MetaKeyBindingManager *keys)
|
||||
keys->iso_next_group_combos = combos;
|
||||
}
|
||||
|
||||
static void
|
||||
binding_reload_keycode_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
MetaKeyBindingManager *keys = data;
|
||||
MetaKeyBinding *binding = value;
|
||||
|
||||
if (binding->keysym)
|
||||
binding->keycode = get_first_keycode_for_keysym (keys, binding->keysym);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_keycodes (MetaKeyBindingManager *keys)
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Reloading keycodes for binding tables\n");
|
||||
|
||||
determine_keymap_num_levels (keys);
|
||||
|
||||
if (keys->overlay_key_combo.keysym != 0)
|
||||
{
|
||||
keys->overlay_key_combo.keycode =
|
||||
get_first_keycode_for_keysym (keys, keys->overlay_key_combo.keysym);
|
||||
}
|
||||
else
|
||||
{
|
||||
keys->overlay_key_combo.keycode = 0;
|
||||
}
|
||||
|
||||
reload_iso_next_group_combos (keys);
|
||||
|
||||
g_hash_table_foreach (keys->key_bindings, binding_reload_keycode_foreach, keys);
|
||||
}
|
||||
|
||||
static void
|
||||
devirtualize_modifiers (MetaKeyBindingManager *keys,
|
||||
MetaVirtualModifier modifiers,
|
||||
@@ -561,58 +507,56 @@ devirtualize_modifiers (MetaKeyBindingManager *keys,
|
||||
*mask |= Mod5Mask;
|
||||
}
|
||||
|
||||
static void
|
||||
binding_reload_modifiers_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
MetaKeyBindingManager *keys = data;
|
||||
MetaKeyBinding *binding = value;
|
||||
|
||||
devirtualize_modifiers (keys, binding->modifiers, &binding->mask);
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
" Devirtualized mods 0x%x -> 0x%x (%s)\n",
|
||||
binding->modifiers,
|
||||
binding->mask,
|
||||
binding->name);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_modifiers (MetaKeyBindingManager *keys)
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Reloading keycodes for binding tables\n");
|
||||
|
||||
g_hash_table_foreach (keys->key_bindings, binding_reload_modifiers_foreach, keys);
|
||||
}
|
||||
|
||||
static void
|
||||
index_binding (MetaKeyBindingManager *keys,
|
||||
MetaKeyBinding *binding)
|
||||
{
|
||||
guint32 index_key;
|
||||
|
||||
index_key = key_binding_key (binding->keycode, binding->mask);
|
||||
index_key = key_combo_key (&binding->resolved_combo);
|
||||
g_hash_table_replace (keys->key_bindings_index,
|
||||
GINT_TO_POINTER (index_key), binding);
|
||||
}
|
||||
|
||||
static void
|
||||
binding_index_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
resolve_key_combo (MetaKeyBindingManager *keys,
|
||||
MetaKeyCombo *combo,
|
||||
MetaResolvedKeyCombo *resolved_combo)
|
||||
{
|
||||
if (combo->keysym != 0)
|
||||
resolved_combo->keycode = get_first_keycode_for_keysym (keys, combo->keysym);
|
||||
else
|
||||
resolved_combo->keycode = combo->keycode;
|
||||
|
||||
devirtualize_modifiers (keys, combo->modifiers, &resolved_combo->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
binding_reload_combos_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
MetaKeyBindingManager *keys = data;
|
||||
MetaKeyBinding *binding = value;
|
||||
|
||||
resolve_key_combo (keys, &binding->combo, &binding->resolved_combo);
|
||||
index_binding (keys, binding);
|
||||
}
|
||||
|
||||
static void
|
||||
rebuild_binding_index (MetaKeyBindingManager *keys)
|
||||
reload_combos (MetaKeyBindingManager *keys)
|
||||
{
|
||||
g_hash_table_remove_all (keys->key_bindings_index);
|
||||
g_hash_table_foreach (keys->key_bindings, binding_index_foreach, keys);
|
||||
|
||||
determine_keymap_num_levels (keys);
|
||||
|
||||
resolve_key_combo (keys,
|
||||
&keys->overlay_key_combo,
|
||||
&keys->overlay_resolved_key_combo);
|
||||
|
||||
reload_iso_next_group_combos (keys);
|
||||
|
||||
g_hash_table_foreach (keys->key_bindings, binding_reload_combos_foreach, keys);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -639,15 +583,11 @@ rebuild_binding_table (MetaKeyBindingManager *keys,
|
||||
{
|
||||
MetaKeyHandler *handler = HANDLER (pref->name);
|
||||
|
||||
b = g_malloc0 (sizeof (MetaKeyBinding));
|
||||
|
||||
b = g_slice_new0 (MetaKeyBinding);
|
||||
b->name = pref->name;
|
||||
b->handler = handler;
|
||||
b->flags = handler->flags;
|
||||
b->keysym = combo->keysym;
|
||||
b->keycode = combo->keycode;
|
||||
b->modifiers = combo->modifiers;
|
||||
b->mask = 0;
|
||||
b->combo = *combo;
|
||||
|
||||
g_hash_table_add (keys->key_bindings, b);
|
||||
}
|
||||
@@ -662,19 +602,15 @@ rebuild_binding_table (MetaKeyBindingManager *keys,
|
||||
while (g)
|
||||
{
|
||||
MetaKeyGrab *grab = (MetaKeyGrab*)g->data;
|
||||
if (grab->combo && (grab->combo->keysym != None || grab->combo->keycode != 0))
|
||||
if (grab->combo.keysym != None || grab->combo.keycode != 0)
|
||||
{
|
||||
MetaKeyHandler *handler = HANDLER ("external-grab");
|
||||
|
||||
b = g_malloc0 (sizeof (MetaKeyBinding));
|
||||
|
||||
b = g_slice_new0 (MetaKeyBinding);
|
||||
b->name = grab->name;
|
||||
b->handler = handler;
|
||||
b->flags = handler->flags;
|
||||
b->keysym = grab->combo->keysym;
|
||||
b->keycode = grab->combo->keycode;
|
||||
b->modifiers = grab->combo->modifiers;
|
||||
b->mask = 0;
|
||||
b->combo = grab->combo;
|
||||
|
||||
g_hash_table_add (keys->key_bindings, b);
|
||||
}
|
||||
@@ -747,14 +683,10 @@ grab_key_bindings (MetaDisplay *display)
|
||||
|
||||
static MetaKeyBinding *
|
||||
get_keybinding (MetaKeyBindingManager *keys,
|
||||
guint32 keycode,
|
||||
guint32 mask)
|
||||
MetaResolvedKeyCombo *resolved_combo)
|
||||
{
|
||||
guint32 key;
|
||||
|
||||
mask = mask & 0xff & ~keys->ignored_modifier_mask;
|
||||
key = key_binding_key (keycode, mask);
|
||||
|
||||
key = key_combo_key (resolved_combo);
|
||||
return g_hash_table_lookup (keys->key_bindings_index, GINT_TO_POINTER (key));
|
||||
}
|
||||
|
||||
@@ -873,6 +805,46 @@ meta_display_remove_keybinding (MetaDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
get_keybinding_action (MetaKeyBindingManager *keys,
|
||||
MetaResolvedKeyCombo *resolved_combo)
|
||||
{
|
||||
MetaKeyBinding *binding;
|
||||
|
||||
/* This is much more vague than the MetaDisplay::overlay-key signal,
|
||||
* which is only emitted if the overlay-key is the only key pressed;
|
||||
* as this method is primarily intended for plugins to allow processing
|
||||
* of mutter keybindings while holding a grab, the overlay-key-only-pressed
|
||||
* tracking is left to the plugin here.
|
||||
*/
|
||||
if (resolved_combo->keycode == (unsigned int)keys->overlay_resolved_key_combo.keycode)
|
||||
return META_KEYBINDING_ACTION_OVERLAY_KEY;
|
||||
|
||||
binding = get_keybinding (keys, resolved_combo);
|
||||
if (binding)
|
||||
{
|
||||
MetaKeyGrab *grab = g_hash_table_lookup (external_grabs, binding->name);
|
||||
if (grab)
|
||||
return grab->action;
|
||||
else
|
||||
return (guint) meta_prefs_get_keybinding_action (binding->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
resolved_combo_from_event_params (MetaResolvedKeyCombo *resolved_combo,
|
||||
MetaKeyBindingManager *keys,
|
||||
unsigned int keycode,
|
||||
unsigned long mask)
|
||||
{
|
||||
resolved_combo->keycode = keycode;
|
||||
resolved_combo->mask = mask & 0xff & ~keys->ignored_modifier_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_keybinding_action:
|
||||
* @display: A #MetaDisplay
|
||||
@@ -893,31 +865,9 @@ meta_display_get_keybinding_action (MetaDisplay *display,
|
||||
unsigned long mask)
|
||||
{
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
MetaKeyBinding *binding;
|
||||
|
||||
/* This is much more vague than the MetaDisplay::overlay-key signal,
|
||||
* which is only emitted if the overlay-key is the only key pressed;
|
||||
* as this method is primarily intended for plugins to allow processing
|
||||
* of mutter keybindings while holding a grab, the overlay-key-only-pressed
|
||||
* tracking is left to the plugin here.
|
||||
*/
|
||||
if (keycode == (unsigned int)keys->overlay_key_combo.keycode)
|
||||
return META_KEYBINDING_ACTION_OVERLAY_KEY;
|
||||
|
||||
binding = get_keybinding (keys, keycode, mask);
|
||||
|
||||
if (binding)
|
||||
{
|
||||
MetaKeyGrab *grab = g_hash_table_lookup (external_grabs, binding->name);
|
||||
if (grab)
|
||||
return grab->action;
|
||||
else
|
||||
return (guint) meta_prefs_get_keybinding_action (binding->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
}
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
resolved_combo_from_event_params (&resolved_combo, keys, keycode, mask);
|
||||
return get_keybinding_action (keys, &resolved_combo);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -934,11 +884,7 @@ on_keymap_changed (MetaBackend *backend,
|
||||
* even when only the keymap changes */
|
||||
reload_modmap (keys);
|
||||
|
||||
reload_keycodes (keys);
|
||||
|
||||
reload_modifiers (keys);
|
||||
|
||||
rebuild_binding_index (keys);
|
||||
reload_combos (keys);
|
||||
|
||||
grab_key_bindings (display);
|
||||
}
|
||||
@@ -1158,9 +1104,7 @@ prefs_changed_callback (MetaPreference pref,
|
||||
ungrab_key_bindings (display);
|
||||
rebuild_key_binding_table (keys);
|
||||
rebuild_special_bindings (keys);
|
||||
reload_keycodes (keys);
|
||||
reload_modifiers (keys);
|
||||
rebuild_binding_index (keys);
|
||||
reload_combos (keys);
|
||||
grab_key_bindings (display);
|
||||
break;
|
||||
case META_PREF_MOUSE_BUTTON_MODS:
|
||||
@@ -1205,11 +1149,9 @@ meta_display_shutdown_keys (MetaDisplay *display)
|
||||
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
|
||||
static void
|
||||
meta_change_keygrab (MetaKeyBindingManager *keys,
|
||||
Window xwindow,
|
||||
gboolean grab,
|
||||
int keysym,
|
||||
unsigned int keycode,
|
||||
int modmask)
|
||||
Window xwindow,
|
||||
gboolean grab,
|
||||
MetaResolvedKeyCombo *resolved_combo)
|
||||
{
|
||||
unsigned int ignored_mask;
|
||||
|
||||
@@ -1228,10 +1170,9 @@ meta_change_keygrab (MetaKeyBindingManager *keys,
|
||||
*/
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"%s keybinding %s keycode %d mask 0x%x on 0x%lx\n",
|
||||
"%s keybinding keycode %d mask 0x%x on 0x%lx\n",
|
||||
grab ? "Grabbing" : "Ungrabbing",
|
||||
keysym_name (keysym), keycode,
|
||||
modmask, xwindow);
|
||||
resolved_combo->keycode, resolved_combo->mask, xwindow);
|
||||
|
||||
ignored_mask = 0;
|
||||
while (ignored_mask <= keys->ignored_modifier_mask)
|
||||
@@ -1247,18 +1188,18 @@ meta_change_keygrab (MetaKeyBindingManager *keys,
|
||||
continue;
|
||||
}
|
||||
|
||||
mods = (XIGrabModifiers) { modmask | ignored_mask, 0 };
|
||||
mods = (XIGrabModifiers) { resolved_combo->mask | ignored_mask, 0 };
|
||||
|
||||
if (grab)
|
||||
XIGrabKeycode (xdisplay,
|
||||
META_VIRTUAL_CORE_KEYBOARD_ID,
|
||||
keycode, xwindow,
|
||||
resolved_combo->keycode, xwindow,
|
||||
XIGrabModeSync, XIGrabModeAsync,
|
||||
False, &mask, 1, &mods);
|
||||
else
|
||||
XIUngrabKeycode (xdisplay,
|
||||
META_VIRTUAL_CORE_KEYBOARD_ID,
|
||||
keycode, xwindow, 1, &mods);
|
||||
resolved_combo->keycode, xwindow, 1, &mods);
|
||||
|
||||
++ignored_mask;
|
||||
}
|
||||
@@ -1284,13 +1225,10 @@ change_keygrab_foreach (gpointer key,
|
||||
if (data->only_per_window != binding_is_per_window)
|
||||
return;
|
||||
|
||||
if (binding->keycode == 0)
|
||||
if (binding->resolved_combo.keycode == 0)
|
||||
return;
|
||||
|
||||
meta_change_keygrab (data->keys, data->xwindow, data->grab,
|
||||
binding->keysym,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
meta_change_keygrab (data->keys, data->xwindow, data->grab, &binding->resolved_combo);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1316,11 +1254,8 @@ meta_screen_change_keygrabs (MetaScreen *screen,
|
||||
MetaDisplay *display = screen->display;
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
|
||||
if (keys->overlay_key_combo.keycode != 0)
|
||||
meta_change_keygrab (keys, screen->xroot, grab,
|
||||
keys->overlay_key_combo.keysym,
|
||||
keys->overlay_key_combo.keycode,
|
||||
keys->overlay_key_combo.modifiers);
|
||||
if (keys->overlay_resolved_key_combo.keycode != 0)
|
||||
meta_change_keygrab (keys, screen->xroot, grab, &keys->overlay_resolved_key_combo);
|
||||
|
||||
if (keys->iso_next_group_combos)
|
||||
{
|
||||
@@ -1328,12 +1263,8 @@ meta_screen_change_keygrabs (MetaScreen *screen,
|
||||
while (i < keys->n_iso_next_group_combos)
|
||||
{
|
||||
if (keys->iso_next_group_combos[i].keycode != 0)
|
||||
{
|
||||
meta_change_keygrab (keys, screen->xroot, grab,
|
||||
keys->iso_next_group_combos[i].keysym,
|
||||
keys->iso_next_group_combos[i].keycode,
|
||||
keys->iso_next_group_combos[i].modifiers);
|
||||
}
|
||||
meta_change_keygrab (keys, screen->xroot, grab, &keys->iso_next_group_combos[i]);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@@ -1443,9 +1374,8 @@ handle_external_grab (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint action = meta_display_get_keybinding_action (display,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
guint action = get_keybinding_action (keys, &binding->resolved_combo);
|
||||
meta_display_accelerator_activate (display, action, event);
|
||||
}
|
||||
|
||||
@@ -1458,12 +1388,10 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
MetaKeyBinding *binding;
|
||||
MetaKeyGrab *grab;
|
||||
guint keysym = 0;
|
||||
guint keycode = 0;
|
||||
guint mask = 0;
|
||||
MetaVirtualModifier modifiers = 0;
|
||||
MetaKeyCombo combo;
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
|
||||
if (!meta_parse_accelerator (accelerator, &keysym, &keycode, &modifiers))
|
||||
if (!meta_parse_accelerator (accelerator, &combo))
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to parse accelerator\n");
|
||||
@@ -1472,35 +1400,29 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
}
|
||||
|
||||
devirtualize_modifiers (keys, modifiers, &mask);
|
||||
keycode = get_first_keycode_for_keysym (keys, keysym);
|
||||
resolve_key_combo (keys, &combo, &resolved_combo);
|
||||
|
||||
if (keycode == 0)
|
||||
if (resolved_combo.keycode == 0)
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
|
||||
if (get_keybinding (keys, keycode, mask))
|
||||
if (get_keybinding (keys, &resolved_combo))
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
meta_change_keygrab (keys, display->screen->xroot, TRUE, keysym, keycode, mask);
|
||||
meta_change_keygrab (keys, display->screen->xroot, TRUE, &resolved_combo);
|
||||
|
||||
grab = g_new0 (MetaKeyGrab, 1);
|
||||
grab->action = next_dynamic_keybinding_action ();
|
||||
grab->name = meta_external_binding_name_for_action (grab->action);
|
||||
grab->combo = g_malloc0 (sizeof (MetaKeyCombo));
|
||||
grab->combo->keysym = keysym;
|
||||
grab->combo->keycode = keycode;
|
||||
grab->combo->modifiers = modifiers;
|
||||
grab->combo = combo;
|
||||
|
||||
g_hash_table_insert (external_grabs, grab->name, grab);
|
||||
|
||||
binding = g_malloc0 (sizeof (MetaKeyBinding));
|
||||
binding = g_slice_new0 (MetaKeyBinding);
|
||||
binding->name = grab->name;
|
||||
binding->handler = HANDLER ("external-grab");
|
||||
binding->keysym = grab->combo->keysym;
|
||||
binding->keycode = grab->combo->keycode;
|
||||
binding->modifiers = grab->combo->modifiers;
|
||||
binding->mask = mask;
|
||||
binding->combo = combo;
|
||||
binding->resolved_combo = resolved_combo;
|
||||
|
||||
g_hash_table_add (keys->key_bindings, binding);
|
||||
index_binding (keys, binding);
|
||||
@@ -1517,8 +1439,7 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
|
||||
MetaKeyBinding *binding;
|
||||
MetaKeyGrab *grab;
|
||||
char *key;
|
||||
guint mask = 0;
|
||||
guint keycode = 0;
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
|
||||
g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE);
|
||||
|
||||
@@ -1527,21 +1448,16 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
|
||||
if (!grab)
|
||||
return FALSE;
|
||||
|
||||
devirtualize_modifiers (keys, grab->combo->modifiers, &mask);
|
||||
keycode = get_first_keycode_for_keysym (keys, grab->combo->keysym);
|
||||
|
||||
binding = get_keybinding (keys, keycode, mask);
|
||||
resolve_key_combo (keys, &grab->combo, &resolved_combo);
|
||||
binding = get_keybinding (keys, &resolved_combo);
|
||||
if (binding)
|
||||
{
|
||||
guint32 index_key;
|
||||
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
meta_change_keygrab (keys, display->screen->xroot, FALSE,
|
||||
binding->keysym,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
meta_change_keygrab (keys, display->screen->xroot, FALSE, &binding->resolved_combo);
|
||||
|
||||
index_key = key_binding_key (binding->keycode, binding->mask);
|
||||
index_key = key_combo_key (&binding->resolved_combo);
|
||||
g_hash_table_remove (keys->key_bindings_index, GINT_TO_POINTER (index_key));
|
||||
|
||||
g_hash_table_remove (keys->key_bindings, binding);
|
||||
@@ -1757,15 +1673,19 @@ process_event (MetaDisplay *display,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
MetaKeyBinding *binding;
|
||||
|
||||
/* we used to have release-based bindings but no longer. */
|
||||
if (event->type == CLUTTER_KEY_RELEASE)
|
||||
return FALSE;
|
||||
|
||||
binding = get_keybinding (keys,
|
||||
event->hardware_keycode,
|
||||
event->modifier_state);
|
||||
resolved_combo_from_event_params (&resolved_combo, keys,
|
||||
event->hardware_keycode,
|
||||
event->modifier_state);
|
||||
|
||||
binding = get_keybinding (keys, &resolved_combo);
|
||||
|
||||
if (!binding ||
|
||||
(!window && binding->flags & META_KEY_BINDING_PER_WINDOW))
|
||||
goto not_found;
|
||||
@@ -1816,7 +1736,7 @@ process_overlay_key (MetaDisplay *display,
|
||||
|
||||
if (keys->overlay_key_only_pressed)
|
||||
{
|
||||
if (event->hardware_keycode != (int)keys->overlay_key_combo.keycode)
|
||||
if (event->hardware_keycode != (int)keys->overlay_resolved_key_combo.keycode)
|
||||
{
|
||||
keys->overlay_key_only_pressed = FALSE;
|
||||
|
||||
@@ -1869,7 +1789,7 @@ process_overlay_key (MetaDisplay *display,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
|
||||
binding = get_keybinding (keys, keys->overlay_key_combo.keycode, 0);
|
||||
binding = get_keybinding (keys, &keys->overlay_resolved_key_combo);
|
||||
if (binding &&
|
||||
meta_compositor_filter_keybinding (display->compositor, binding))
|
||||
return TRUE;
|
||||
@@ -1898,7 +1818,7 @@ process_overlay_key (MetaDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_PRESS &&
|
||||
event->hardware_keycode == (int)keys->overlay_key_combo.keycode)
|
||||
event->hardware_keycode == (int)keys->overlay_resolved_key_combo.keycode)
|
||||
{
|
||||
keys->overlay_key_only_pressed = TRUE;
|
||||
/* We keep the keyboard frozen - this allows us to use ReplayKeyboard
|
||||
@@ -1921,8 +1841,7 @@ process_iso_next_group (MetaDisplay *display,
|
||||
{
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
gboolean activate;
|
||||
guint32 keycode;
|
||||
guint32 modifiers;
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
int i;
|
||||
|
||||
if (event->type == CLUTTER_KEY_RELEASE)
|
||||
@@ -1930,13 +1849,14 @@ process_iso_next_group (MetaDisplay *display,
|
||||
|
||||
activate = FALSE;
|
||||
|
||||
keycode = event->hardware_keycode;
|
||||
modifiers = event->modifier_state & 0xff & ~keys->ignored_modifier_mask;
|
||||
resolved_combo_from_event_params (&resolved_combo, keys,
|
||||
event->hardware_keycode,
|
||||
event->modifier_state);
|
||||
|
||||
for (i = 0; i < keys->n_iso_next_group_combos; ++i)
|
||||
{
|
||||
if (keycode == keys->iso_next_group_combos[i].keycode &&
|
||||
modifiers == keys->iso_next_group_combos[i].modifiers)
|
||||
if (resolved_combo.keycode == keys->iso_next_group_combos[i].keycode &&
|
||||
resolved_combo.mask == keys->iso_next_group_combos[i].mask)
|
||||
{
|
||||
/* If the signal handler returns TRUE the keyboard will
|
||||
remain frozen. It's the signal handler's responsibility
|
||||
@@ -3716,6 +3636,41 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 7);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-8",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 8);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-9",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 9);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-10",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 10);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-11",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 11);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-12",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 12);
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
@@ -4092,7 +4047,7 @@ meta_display_init_keys (MetaDisplay *display)
|
||||
keys->super_mask = 0;
|
||||
keys->meta_mask = 0;
|
||||
|
||||
keys->key_bindings = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
keys->key_bindings = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) meta_key_binding_free);
|
||||
keys->key_bindings_index = g_hash_table_new (NULL, NULL);
|
||||
|
||||
reload_modmap (keys);
|
||||
@@ -4128,9 +4083,7 @@ meta_display_init_keys (MetaDisplay *display)
|
||||
rebuild_key_binding_table (keys);
|
||||
rebuild_special_bindings (keys);
|
||||
|
||||
reload_keycodes (keys);
|
||||
reload_modifiers (keys);
|
||||
rebuild_binding_index (keys);
|
||||
reload_combos (keys);
|
||||
|
||||
update_window_grab_modifiers (keys);
|
||||
|
||||
|
@@ -431,42 +431,6 @@ meta_run (void)
|
||||
meta_prefs_init ();
|
||||
meta_prefs_add_listener (prefs_changed_callback, NULL);
|
||||
|
||||
meta_ui_set_current_theme (meta_prefs_get_theme ());
|
||||
|
||||
/* Try to find some theme that'll work if the theme preference
|
||||
* doesn't exist. First try Simple (the default theme) then just
|
||||
* try anything in the themes directory.
|
||||
*/
|
||||
if (!meta_ui_have_a_theme ())
|
||||
meta_ui_set_current_theme ("Simple");
|
||||
|
||||
if (!meta_ui_have_a_theme ())
|
||||
{
|
||||
const char *dir_entry = NULL;
|
||||
GError *err = NULL;
|
||||
GDir *themes_dir = NULL;
|
||||
|
||||
if (!(themes_dir = g_dir_open (MUTTER_DATADIR"/themes", 0, &err)))
|
||||
{
|
||||
meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
|
||||
(!meta_ui_have_a_theme ()))
|
||||
{
|
||||
meta_ui_set_current_theme (dir_entry);
|
||||
}
|
||||
|
||||
g_dir_close (themes_dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (!meta_ui_have_a_theme ())
|
||||
meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes.\n"),
|
||||
MUTTER_DATADIR"/themes");
|
||||
|
||||
if (!meta_display_open ())
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
|
||||
@@ -513,9 +477,7 @@ prefs_changed_callback (MetaPreference pref,
|
||||
{
|
||||
switch (pref)
|
||||
{
|
||||
case META_PREF_THEME:
|
||||
case META_PREF_DRAGGABLE_BORDER_WIDTH:
|
||||
meta_ui_set_current_theme (meta_prefs_get_theme ());
|
||||
meta_display_retheme_all ();
|
||||
break;
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-accel-parse.h"
|
||||
#include "keybindings-private.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <string.h>
|
||||
@@ -173,21 +174,16 @@ is_keycode (const gchar *string)
|
||||
|
||||
static gboolean
|
||||
accelerator_parse (const gchar *accelerator,
|
||||
guint *accelerator_key,
|
||||
guint *accelerator_keycode,
|
||||
MetaVirtualModifier *accelerator_mods)
|
||||
MetaKeyCombo *combo)
|
||||
{
|
||||
gboolean error = FALSE;
|
||||
guint keyval, keycode;
|
||||
MetaVirtualModifier mods;
|
||||
gint len;
|
||||
|
||||
if (accelerator_key)
|
||||
*accelerator_key = 0;
|
||||
if (accelerator_keycode)
|
||||
*accelerator_keycode = 0;
|
||||
if (accelerator_mods)
|
||||
*accelerator_mods = 0;
|
||||
combo->keysym = 0;
|
||||
combo->keycode = 0;
|
||||
combo->modifiers = 0;
|
||||
|
||||
if (accelerator == NULL)
|
||||
{
|
||||
@@ -330,34 +326,35 @@ out:
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
if (accelerator_key)
|
||||
*accelerator_key = keyval;
|
||||
if (accelerator_keycode)
|
||||
*accelerator_keycode = keycode;
|
||||
if (accelerator_mods)
|
||||
*accelerator_mods = mods;
|
||||
combo->keysym = keyval;
|
||||
combo->keycode = keycode;
|
||||
combo->modifiers = mods;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_parse_accelerator (const char *accel,
|
||||
unsigned int *keysym,
|
||||
unsigned int *keycode,
|
||||
MetaVirtualModifier *mask)
|
||||
meta_parse_accelerator (const char *accel,
|
||||
MetaKeyCombo *combo)
|
||||
{
|
||||
if (!accel[0] || strcmp (accel, "disabled") == 0)
|
||||
return TRUE;
|
||||
|
||||
return accelerator_parse (accel, keysym, keycode, mask);
|
||||
return accelerator_parse (accel, combo);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_parse_modifier (const char *accel,
|
||||
MetaVirtualModifier *mask)
|
||||
{
|
||||
MetaKeyCombo combo;
|
||||
|
||||
if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0)
|
||||
return TRUE;
|
||||
|
||||
return accelerator_parse (accel, NULL, NULL, mask);
|
||||
if (!accelerator_parse (accel, &combo))
|
||||
return FALSE;
|
||||
|
||||
*mask = combo.modifiers;
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -27,16 +27,16 @@
|
||||
#include <glib.h>
|
||||
#include <meta/common.h>
|
||||
|
||||
typedef struct _MetaKeyCombo MetaKeyCombo;
|
||||
|
||||
/* Not a real key symbol but means "key above the tab key"; this is
|
||||
* used as the default keybinding for cycle_group.
|
||||
* 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are
|
||||
* randomly chosen */
|
||||
#define META_KEY_ABOVE_TAB 0x2f7259c9
|
||||
|
||||
gboolean meta_parse_accelerator (const char *accel,
|
||||
unsigned int *keysym,
|
||||
unsigned int *keycode,
|
||||
MetaVirtualModifier *mask);
|
||||
gboolean meta_parse_accelerator (const char *accel,
|
||||
MetaKeyCombo *combo);
|
||||
gboolean meta_parse_modifier (const char *accel,
|
||||
MetaVirtualModifier *mask);
|
||||
|
||||
|
@@ -779,7 +779,8 @@ meta_window_place (MetaWindow *window,
|
||||
|
||||
if (w != window &&
|
||||
meta_window_showing_on_its_workspace (w) &&
|
||||
meta_window_located_on_workspace (w, window->workspace))
|
||||
(window->on_all_workspaces ||
|
||||
meta_window_located_on_workspace (w, window->workspace)))
|
||||
windows = g_list_prepend (windows, w);
|
||||
|
||||
tmp = tmp->next;
|
||||
|
@@ -82,7 +82,6 @@ static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_S
|
||||
static gboolean raise_on_click = TRUE;
|
||||
static gboolean center_new_windows = FALSE;
|
||||
static gboolean attach_modal_dialogs = FALSE;
|
||||
static char* current_theme = NULL;
|
||||
static int num_workspaces = 4;
|
||||
static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
|
||||
static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
|
||||
@@ -144,7 +143,6 @@ static void queue_changed (MetaPreference pref);
|
||||
static void maybe_give_disable_workarounds_warning (void);
|
||||
|
||||
static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
|
||||
static gboolean theme_name_handler (GVariant*, gpointer*, gpointer);
|
||||
static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
|
||||
static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
|
||||
static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
|
||||
@@ -401,14 +399,6 @@ static MetaStringPreference preferences_string[] =
|
||||
mouse_button_mods_handler,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
{ "theme",
|
||||
SCHEMA_GENERAL,
|
||||
META_PREF_THEME,
|
||||
},
|
||||
theme_name_handler,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
{ KEY_TITLEBAR_FONT,
|
||||
SCHEMA_GENERAL,
|
||||
@@ -449,7 +439,7 @@ static MetaStringArrayPreference preferences_string_array[] =
|
||||
{
|
||||
{ KEY_WORKSPACE_NAMES,
|
||||
SCHEMA_GENERAL,
|
||||
META_PREF_KEYBINDINGS,
|
||||
META_PREF_WORKSPACE_NAMES,
|
||||
},
|
||||
NULL,
|
||||
&workspace_names,
|
||||
@@ -571,8 +561,7 @@ handle_preference_init_string (void)
|
||||
if (!cursor->target)
|
||||
meta_bug ("%s must have handler or target\n", cursor->base.key);
|
||||
|
||||
if (*(cursor->target))
|
||||
g_free (*(cursor->target));
|
||||
g_free (*(cursor->target));
|
||||
|
||||
value = g_settings_get_string (SETTINGS (cursor->base.schema),
|
||||
cursor->base.key);
|
||||
@@ -728,8 +717,7 @@ handle_preference_update_string (GSettings *settings,
|
||||
|
||||
inform_listeners = (g_strcmp0 (value, *(cursor->target)) != 0);
|
||||
|
||||
if (*(cursor->target))
|
||||
g_free(*(cursor->target));
|
||||
g_free(*(cursor->target));
|
||||
|
||||
*(cursor->target) = value;
|
||||
}
|
||||
@@ -1302,10 +1290,7 @@ meta_prefs_get_attach_modal_dialogs (void)
|
||||
gboolean
|
||||
meta_prefs_get_raise_on_click (void)
|
||||
{
|
||||
/* Force raise_on_click on for click-to-focus, as requested by Havoc
|
||||
* in #326156.
|
||||
*/
|
||||
return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
|
||||
return raise_on_click;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1314,12 +1299,6 @@ meta_prefs_get_show_fallback_app_menu (void)
|
||||
return show_fallback_app_menu;
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_prefs_get_theme (void)
|
||||
{
|
||||
return current_theme;
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_prefs_get_cursor_theme (void)
|
||||
{
|
||||
@@ -1376,31 +1355,6 @@ titlebar_handler (GVariant *value,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
theme_name_handler (GVariant *value,
|
||||
gpointer *result,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *string_value;
|
||||
|
||||
*result = NULL; /* ignored */
|
||||
string_value = g_variant_get_string (value, NULL);
|
||||
|
||||
if (!string_value || !*string_value)
|
||||
return FALSE;
|
||||
|
||||
if (g_strcmp0 (current_theme, string_value) != 0)
|
||||
{
|
||||
if (current_theme)
|
||||
g_free (current_theme);
|
||||
|
||||
current_theme = g_strdup (string_value);
|
||||
queue_changed (META_PREF_THEME);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mouse_button_mods_handler (GVariant *value,
|
||||
gpointer *result,
|
||||
@@ -1718,9 +1672,7 @@ overlay_key_handler (GVariant *value,
|
||||
*result = NULL; /* ignored */
|
||||
string_value = g_variant_get_string (value, NULL);
|
||||
|
||||
if (string_value && meta_parse_accelerator (string_value, &combo.keysym,
|
||||
&combo.keycode,
|
||||
&combo.modifiers))
|
||||
if (string_value && meta_parse_accelerator (string_value, &combo))
|
||||
;
|
||||
else
|
||||
{
|
||||
@@ -1729,9 +1681,10 @@ overlay_key_handler (GVariant *value,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
combo.modifiers = 0;
|
||||
|
||||
if (overlay_key_combo.keysym != combo.keysym ||
|
||||
overlay_key_combo.keycode != combo.keycode ||
|
||||
overlay_key_combo.modifiers != combo.modifiers)
|
||||
overlay_key_combo.keycode != combo.keycode)
|
||||
{
|
||||
overlay_key_combo = combo;
|
||||
queue_changed (META_PREF_KEYBINDINGS);
|
||||
@@ -1825,9 +1778,6 @@ meta_preference_to_string (MetaPreference pref)
|
||||
case META_PREF_RAISE_ON_CLICK:
|
||||
return "RAISE_ON_CLICK";
|
||||
|
||||
case META_PREF_THEME:
|
||||
return "THEME";
|
||||
|
||||
case META_PREF_TITLEBAR_FONT:
|
||||
return "TITLEBAR_FONT";
|
||||
|
||||
@@ -1965,10 +1915,6 @@ update_binding (MetaKeyPref *binding,
|
||||
{
|
||||
GSList *old_combos, *a, *b;
|
||||
gboolean changed;
|
||||
unsigned int keysym;
|
||||
unsigned int keycode;
|
||||
MetaVirtualModifier mods;
|
||||
MetaKeyCombo *combo;
|
||||
int i;
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
@@ -1980,31 +1926,25 @@ update_binding (MetaKeyPref *binding,
|
||||
|
||||
for (i = 0; strokes && strokes[i]; i++)
|
||||
{
|
||||
keysym = 0;
|
||||
keycode = 0;
|
||||
mods = 0;
|
||||
MetaKeyCombo *combo;
|
||||
|
||||
if (!meta_parse_accelerator (strokes[i], &keysym, &keycode, &mods))
|
||||
combo = g_malloc0 (sizeof (MetaKeyCombo));
|
||||
|
||||
if (!meta_parse_accelerator (strokes[i], combo))
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to parse new GSettings value\n");
|
||||
meta_warning ("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n",
|
||||
strokes[i], binding->name);
|
||||
|
||||
g_free (combo);
|
||||
|
||||
/* Value is kept and will thus be removed next time we save the key.
|
||||
* Changing the key in response to a modification could lead to cyclic calls. */
|
||||
continue;
|
||||
}
|
||||
|
||||
combo = g_malloc0 (sizeof (MetaKeyCombo));
|
||||
combo->keysym = keysym;
|
||||
combo->keycode = keycode;
|
||||
combo->modifiers = mods;
|
||||
binding->combos = g_slist_prepend (binding->combos, combo);
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n",
|
||||
binding->name, keysym, keycode, mods);
|
||||
}
|
||||
|
||||
binding->combos = g_slist_reverse (binding->combos);
|
||||
@@ -2171,7 +2111,6 @@ meta_prefs_add_keybinding (const char *name,
|
||||
pref->settings = g_object_ref (settings);
|
||||
pref->action = action;
|
||||
pref->combos = NULL;
|
||||
pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0;
|
||||
pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0;
|
||||
|
||||
strokes = g_settings_get_strv (settings, name);
|
||||
@@ -2234,7 +2173,7 @@ meta_prefs_remove_keybinding (const char *name)
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_prefs_get_keybindings ()
|
||||
meta_prefs_get_keybindings (void)
|
||||
{
|
||||
return g_hash_table_get_values (key_bindings);
|
||||
}
|
||||
@@ -2282,25 +2221,25 @@ meta_prefs_get_auto_raise_delay (void)
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_focus_change_on_pointer_rest ()
|
||||
meta_prefs_get_focus_change_on_pointer_rest (void)
|
||||
{
|
||||
return focus_change_on_pointer_rest;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_gnome_accessibility ()
|
||||
meta_prefs_get_gnome_accessibility (void)
|
||||
{
|
||||
return gnome_accessibility;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_gnome_animations ()
|
||||
meta_prefs_get_gnome_animations (void)
|
||||
{
|
||||
return gnome_animations;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_edge_tiling ()
|
||||
meta_prefs_get_edge_tiling (void)
|
||||
{
|
||||
return edge_tiling;
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include "stack-tracker.h"
|
||||
#include "ui.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
typedef void (* MetaScreenWindowFunc) (MetaWindow *window,
|
||||
gpointer user_data);
|
||||
@@ -100,8 +100,6 @@ struct _MetaScreen
|
||||
#endif
|
||||
|
||||
Window wm_cm_selection_window;
|
||||
guint32 wm_cm_timestamp;
|
||||
|
||||
guint work_area_later;
|
||||
guint check_fullscreen_later;
|
||||
|
||||
|
@@ -496,13 +496,79 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
return guard_window;
|
||||
}
|
||||
|
||||
/* Set a black background on the root window so that we don't
|
||||
* see confusing old copies of old windows when debugging
|
||||
* and testing. */
|
||||
static void
|
||||
meta_screen_set_background (MetaScreen *screen)
|
||||
static Window
|
||||
take_manager_selection (MetaDisplay *display,
|
||||
Window xroot,
|
||||
Atom manager_atom,
|
||||
int timestamp,
|
||||
gboolean should_replace)
|
||||
{
|
||||
XSetWindowBackground (screen->display->xdisplay, screen->xroot, 0x00000000);
|
||||
Display *xdisplay = display->xdisplay;
|
||||
Window current_owner, new_owner;
|
||||
|
||||
current_owner = XGetSelectionOwner (xdisplay, manager_atom);
|
||||
if (current_owner != None)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
if (should_replace)
|
||||
{
|
||||
/* We want to find out when the current selection owner dies */
|
||||
meta_error_trap_push (display);
|
||||
attrs.event_mask = StructureNotifyMask;
|
||||
XChangeWindowAttributes (xdisplay, current_owner, CWEventMask, &attrs);
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
current_owner = None; /* don't wait for it to die later on */
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning (_("Display \"%s\" already has a window manager; try using the --replace option to replace the current window manager."),
|
||||
display->name);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need SelectionClear and SelectionRequest events on the new owner,
|
||||
* but those cannot be masked, so we only need NoEventMask.
|
||||
*/
|
||||
new_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
|
||||
|
||||
XSetSelectionOwner (xdisplay, manager_atom, new_owner, timestamp);
|
||||
|
||||
if (XGetSelectionOwner (xdisplay, manager_atom) != new_owner)
|
||||
{
|
||||
meta_warning ("Could not acquire selection: %s", XGetAtomName (xdisplay, manager_atom));
|
||||
return None;
|
||||
}
|
||||
|
||||
{
|
||||
/* Send client message indicating that we are now the selection owner */
|
||||
XClientMessageEvent ev;
|
||||
|
||||
ev.type = ClientMessage;
|
||||
ev.window = xroot;
|
||||
ev.message_type = display->atom_MANAGER;
|
||||
ev.format = 32;
|
||||
ev.data.l[0] = timestamp;
|
||||
ev.data.l[1] = manager_atom;
|
||||
|
||||
XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent *) &ev);
|
||||
}
|
||||
|
||||
/* Wait for old window manager to go away */
|
||||
if (current_owner != None)
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
/* We sort of block infinitely here which is probably lame. */
|
||||
|
||||
meta_verbose ("Waiting for old window manager to exit\n");
|
||||
do
|
||||
XWindowEvent (xdisplay, current_owner, StructureNotifyMask, &event);
|
||||
while (event.type != DestroyNotify);
|
||||
}
|
||||
|
||||
return new_owner;
|
||||
}
|
||||
|
||||
MetaScreen*
|
||||
@@ -514,11 +580,9 @@ meta_screen_new (MetaDisplay *display,
|
||||
Window xroot;
|
||||
Display *xdisplay;
|
||||
Window new_wm_sn_owner;
|
||||
Window current_wm_sn_owner;
|
||||
gboolean replace_current_wm;
|
||||
Atom wm_sn_atom;
|
||||
char buf[128];
|
||||
guint32 manager_timestamp;
|
||||
MetaMonitorManager *manager;
|
||||
|
||||
replace_current_wm = meta_get_replace_current_wm ();
|
||||
@@ -546,83 +610,11 @@ meta_screen_new (MetaDisplay *display,
|
||||
}
|
||||
|
||||
sprintf (buf, "WM_S%d", number);
|
||||
|
||||
wm_sn_atom = XInternAtom (xdisplay, buf, False);
|
||||
|
||||
current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
|
||||
|
||||
if (current_wm_sn_owner != None)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
if (!replace_current_wm)
|
||||
{
|
||||
meta_warning (_("Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n"),
|
||||
number, display->name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We want to find out when the current selection owner dies */
|
||||
meta_error_trap_push (display);
|
||||
attrs.event_mask = StructureNotifyMask;
|
||||
XChangeWindowAttributes (xdisplay,
|
||||
current_wm_sn_owner, CWEventMask, &attrs);
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
current_wm_sn_owner = None; /* don't wait for it to die later on */
|
||||
}
|
||||
|
||||
/* We need SelectionClear and SelectionRequest events on the new_wm_sn_owner,
|
||||
* but those cannot be masked, so we only need NoEventMask.
|
||||
*/
|
||||
new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
|
||||
|
||||
manager_timestamp = timestamp;
|
||||
|
||||
XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner,
|
||||
manager_timestamp);
|
||||
|
||||
if (XGetSelectionOwner (xdisplay, wm_sn_atom) != new_wm_sn_owner)
|
||||
{
|
||||
meta_warning ("Could not acquire window manager selection on screen %d display \"%s\"\n",
|
||||
number, display->name);
|
||||
|
||||
XDestroyWindow (xdisplay, new_wm_sn_owner);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
/* Send client message indicating that we are now the WM */
|
||||
XClientMessageEvent ev;
|
||||
|
||||
ev.type = ClientMessage;
|
||||
ev.window = xroot;
|
||||
ev.message_type = display->atom_MANAGER;
|
||||
ev.format = 32;
|
||||
ev.data.l[0] = manager_timestamp;
|
||||
ev.data.l[1] = wm_sn_atom;
|
||||
|
||||
XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent*)&ev);
|
||||
}
|
||||
|
||||
/* Wait for old window manager to go away */
|
||||
if (current_wm_sn_owner != None)
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
/* We sort of block infinitely here which is probably lame. */
|
||||
|
||||
meta_verbose ("Waiting for old window manager to exit\n");
|
||||
do
|
||||
{
|
||||
XWindowEvent (xdisplay, current_wm_sn_owner,
|
||||
StructureNotifyMask, &event);
|
||||
}
|
||||
while (event.type != DestroyNotify);
|
||||
}
|
||||
|
||||
/* select our root window events */
|
||||
meta_error_trap_push (display);
|
||||
new_wm_sn_owner = take_manager_selection (display, xroot, wm_sn_atom, timestamp, replace_current_wm);
|
||||
if (new_wm_sn_owner == None)
|
||||
return NULL;
|
||||
|
||||
{
|
||||
long event_mask;
|
||||
@@ -647,16 +639,6 @@ meta_screen_new (MetaDisplay *display,
|
||||
XSelectInput (xdisplay, xroot, event_mask);
|
||||
}
|
||||
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
|
||||
number, display->name);
|
||||
|
||||
XDestroyWindow (xdisplay, new_wm_sn_owner);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Select for cursor changes so the cursor tracker is up to date. */
|
||||
XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask);
|
||||
|
||||
@@ -684,11 +666,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
|
||||
screen->wm_sn_selection_window = new_wm_sn_owner;
|
||||
screen->wm_sn_atom = wm_sn_atom;
|
||||
screen->wm_sn_timestamp = manager_timestamp;
|
||||
|
||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
||||
xroot,
|
||||
NoEventMask);
|
||||
screen->wm_sn_timestamp = timestamp;
|
||||
screen->work_area_later = 0;
|
||||
screen->check_fullscreen_later = 0;
|
||||
|
||||
@@ -700,7 +678,10 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->starting_corner = META_SCREEN_TOPLEFT;
|
||||
screen->guard_window = None;
|
||||
|
||||
screen->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot);
|
||||
/* If we're a Wayland compositor, then we don't grab the COW, since it
|
||||
* will map it. */
|
||||
if (!meta_is_wayland_compositor ())
|
||||
screen->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot);
|
||||
|
||||
/* Now that we've gotten taken a reference count on the COW, we
|
||||
* can close the helper that is holding on to it */
|
||||
@@ -709,7 +690,6 @@ meta_screen_new (MetaDisplay *display,
|
||||
reload_monitor_infos (screen);
|
||||
|
||||
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
|
||||
meta_screen_set_background (screen);
|
||||
|
||||
/* Handle creating a no_focus_window for this screen */
|
||||
screen->no_focus_window =
|
||||
@@ -858,8 +838,7 @@ meta_screen_free (MetaScreen *screen,
|
||||
if (screen->check_fullscreen_later != 0)
|
||||
meta_later_remove (screen->check_fullscreen_later);
|
||||
|
||||
if (screen->monitor_infos)
|
||||
g_free (screen->monitor_infos);
|
||||
g_free (screen->monitor_infos);
|
||||
|
||||
if (screen->tile_preview_timeout_id)
|
||||
g_source_remove (screen->tile_preview_timeout_id);
|
||||
@@ -1286,9 +1265,11 @@ meta_screen_update_cursor (MetaScreen *screen)
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (screen);
|
||||
|
||||
cursor_ref = meta_cursor_reference_from_theme (cursor);
|
||||
if (cursor_ref == NULL)
|
||||
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
|
||||
|
||||
meta_cursor_tracker_set_root_cursor (tracker, cursor_ref);
|
||||
if (cursor_ref)
|
||||
meta_cursor_reference_unref (cursor_ref);
|
||||
meta_cursor_reference_unref (cursor_ref);
|
||||
|
||||
/* Set a cursor for X11 applications that don't specify their own */
|
||||
xcursor = meta_display_create_x_cursor (display, cursor);
|
||||
@@ -2908,27 +2889,12 @@ meta_screen_set_cm_selection (MetaScreen *screen)
|
||||
{
|
||||
char selection[32];
|
||||
Atom a;
|
||||
guint32 timestamp;
|
||||
|
||||
screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip (
|
||||
screen->display);
|
||||
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
meta_verbose ("Setting selection: %s\n", selection);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
screen->wm_cm_selection_window, screen->wm_cm_timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_unset_cm_selection (MetaScreen *screen)
|
||||
{
|
||||
char selection[32];
|
||||
Atom a;
|
||||
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
None, screen->wm_cm_timestamp);
|
||||
timestamp = meta_display_get_current_time_roundtrip (screen->display);
|
||||
g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", screen->number);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, False);
|
||||
screen->wm_cm_selection_window = take_manager_selection (screen->display, screen->xroot, a, timestamp, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1137,6 +1137,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
x11_stacked->len);
|
||||
|
||||
g_array_free (x11_stacked, TRUE);
|
||||
g_array_free (x11_hidden_stack_ids, TRUE);
|
||||
g_array_free (all_root_children_stacked, TRUE);
|
||||
}
|
||||
|
||||
|
@@ -72,11 +72,12 @@ typedef enum {
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||
META_IS_USER_ACTION = 1 << 1,
|
||||
META_IS_MOVE_ACTION = 1 << 2,
|
||||
META_IS_RESIZE_ACTION = 1 << 3,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 4,
|
||||
META_MOVE_RESIZE_CONFIGURE_REQUEST = 1 << 0,
|
||||
META_MOVE_RESIZE_USER_ACTION = 1 << 1,
|
||||
META_MOVE_RESIZE_MOVE_ACTION = 1 << 2,
|
||||
META_MOVE_RESIZE_RESIZE_ACTION = 1 << 3,
|
||||
META_MOVE_RESIZE_WAYLAND_RESIZE = 1 << 4,
|
||||
META_MOVE_RESIZE_STATE_CHANGED = 1 << 5,
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
typedef enum
|
||||
@@ -105,8 +106,8 @@ struct _MetaWindow
|
||||
char *desc; /* used in debug spew */
|
||||
char *title;
|
||||
|
||||
GdkPixbuf *icon;
|
||||
GdkPixbuf *mini_icon;
|
||||
cairo_surface_t *icon;
|
||||
cairo_surface_t *mini_icon;
|
||||
|
||||
MetaWindowType type;
|
||||
|
||||
@@ -478,9 +479,9 @@ struct _MetaWindowClass
|
||||
void (*get_default_skip_hints) (MetaWindow *window,
|
||||
gboolean *skip_taskbar_out,
|
||||
gboolean *skip_pager_out);
|
||||
gboolean (*update_icon) (MetaWindow *window,
|
||||
GdkPixbuf **icon,
|
||||
GdkPixbuf **mini_icon);
|
||||
gboolean (*update_icon) (MetaWindow *window,
|
||||
cairo_surface_t **icon,
|
||||
cairo_surface_t **mini_icon);
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
@@ -539,9 +540,6 @@ void meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
int h,
|
||||
int gravity);
|
||||
|
||||
void meta_window_change_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
/* Return whether the window should be currently mapped */
|
||||
gboolean meta_window_should_be_showing (MetaWindow *window);
|
||||
|
||||
|
@@ -244,9 +244,9 @@ meta_window_real_get_default_skip_hints (MetaWindow *window,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_real_update_icon (MetaWindow *window,
|
||||
GdkPixbuf **icon,
|
||||
GdkPixbuf **mini_icon)
|
||||
meta_window_real_update_icon (MetaWindow *window,
|
||||
cairo_surface_t **icon,
|
||||
cairo_surface_t **mini_icon)
|
||||
{
|
||||
*icon = NULL;
|
||||
*mini_icon = NULL;
|
||||
@@ -259,10 +259,10 @@ meta_window_finalize (GObject *object)
|
||||
MetaWindow *window = META_WINDOW (object);
|
||||
|
||||
if (window->icon)
|
||||
g_object_unref (G_OBJECT (window->icon));
|
||||
cairo_surface_destroy (window->icon);
|
||||
|
||||
if (window->mini_icon)
|
||||
g_object_unref (G_OBJECT (window->mini_icon));
|
||||
cairo_surface_destroy (window->mini_icon);
|
||||
|
||||
if (window->frame_bounds)
|
||||
cairo_region_destroy (window->frame_bounds);
|
||||
@@ -312,10 +312,10 @@ meta_window_get_property(GObject *object,
|
||||
g_value_set_string (value, win->title);
|
||||
break;
|
||||
case PROP_ICON:
|
||||
g_value_set_object (value, win->icon);
|
||||
g_value_set_pointer (value, win->icon);
|
||||
break;
|
||||
case PROP_MINI_ICON:
|
||||
g_value_set_object (value, win->mini_icon);
|
||||
g_value_set_pointer (value, win->mini_icon);
|
||||
break;
|
||||
case PROP_DECORATED:
|
||||
g_value_set_boolean (value, win->decorated);
|
||||
@@ -427,17 +427,15 @@ meta_window_class_init (MetaWindowClass *klass)
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_ICON] =
|
||||
g_param_spec_object ("icon",
|
||||
"Icon",
|
||||
"96 pixel sized icon",
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_param_spec_pointer ("icon",
|
||||
"Icon",
|
||||
"96 pixel sized icon",
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_MINI_ICON] =
|
||||
g_param_spec_object ("mini-icon",
|
||||
"Mini Icon",
|
||||
"16 pixel sized icon",
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_param_spec_pointer ("mini-icon",
|
||||
"Mini Icon",
|
||||
"16 pixel sized icon",
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_DECORATED] =
|
||||
g_param_spec_boolean ("decorated",
|
||||
"Decorated",
|
||||
@@ -2690,7 +2688,10 @@ meta_window_maximize (MetaWindow *window,
|
||||
|
||||
meta_window_get_frame_rect (window, &old_rect);
|
||||
|
||||
meta_window_move_resize_now (window);
|
||||
meta_window_move_resize_internal (window,
|
||||
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
|
||||
NorthWestGravity,
|
||||
window->unconstrained_rect);
|
||||
|
||||
meta_window_get_frame_rect (window, &new_rect);
|
||||
meta_compositor_maximize_window (window->display->compositor,
|
||||
@@ -2882,8 +2883,7 @@ meta_window_tile (MetaWindow *window)
|
||||
&new_rect);
|
||||
|
||||
if (window->frame)
|
||||
meta_ui_queue_frame_draw (window->screen->ui,
|
||||
window->frame->xwindow);
|
||||
meta_frame_queue_draw (window->frame);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3044,7 +3044,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
||||
meta_window_client_rect_to_frame_rect (window, &target_rect, &target_rect);
|
||||
|
||||
meta_window_move_resize_internal (window,
|
||||
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION,
|
||||
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
|
||||
gravity,
|
||||
target_rect);
|
||||
|
||||
@@ -3189,9 +3189,11 @@ meta_window_make_fullscreen (MetaWindow *window)
|
||||
if (!window->fullscreen)
|
||||
{
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
/* move_resize with new constraints
|
||||
*/
|
||||
meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
meta_window_move_resize_internal (window,
|
||||
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
|
||||
NorthWestGravity,
|
||||
window->unconstrained_rect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3213,19 +3215,19 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
/* Window's size hints may have changed while maximized, making
|
||||
* saved_rect invalid. #329152
|
||||
*/
|
||||
meta_window_frame_rect_to_client_rect (window, &target_rect, &target_rect);
|
||||
ensure_size_hints_satisfied (&target_rect, &window->size_hints);
|
||||
meta_window_client_rect_to_frame_rect (window, &target_rect, &target_rect);
|
||||
|
||||
/* Need to update window->has_resize_func before we move_resize()
|
||||
*/
|
||||
meta_window_recalc_features (window);
|
||||
set_net_wm_state (window);
|
||||
|
||||
meta_window_move_resize_frame (window,
|
||||
FALSE,
|
||||
target_rect.x,
|
||||
target_rect.y,
|
||||
target_rect.width,
|
||||
target_rect.height);
|
||||
meta_window_move_resize_internal (window,
|
||||
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
|
||||
NorthWestGravity,
|
||||
target_rect);
|
||||
|
||||
meta_window_update_layer (window);
|
||||
|
||||
@@ -3612,19 +3614,19 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
/* The action has to be a move, a resize or the wayland client
|
||||
* acking our choice of size.
|
||||
*/
|
||||
g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_WAYLAND_RESIZE));
|
||||
g_assert (flags & (META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_WAYLAND_RESIZE));
|
||||
|
||||
did_placement = !window->placed && window->calc_placement;
|
||||
|
||||
/* We don't need it in the idle queue anymore. */
|
||||
meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
if ((flags & META_IS_RESIZE_ACTION) && (flags & META_IS_MOVE_ACTION))
|
||||
if ((flags & META_MOVE_RESIZE_RESIZE_ACTION) && (flags & META_MOVE_RESIZE_MOVE_ACTION))
|
||||
{
|
||||
/* We're both moving and resizing. Just use the passed in rect. */
|
||||
unconstrained_rect = frame_rect;
|
||||
}
|
||||
else if ((flags & META_IS_RESIZE_ACTION))
|
||||
else if ((flags & META_MOVE_RESIZE_RESIZE_ACTION))
|
||||
{
|
||||
/* If this is only a resize, then ignore the position given in
|
||||
* the parameters and instead calculate the new position from
|
||||
@@ -3635,7 +3637,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
frame_rect.width,
|
||||
frame_rect.height);
|
||||
}
|
||||
else if ((flags & META_IS_MOVE_ACTION))
|
||||
else if ((flags & META_MOVE_RESIZE_MOVE_ACTION))
|
||||
{
|
||||
/* If this is only a move, then ignore the passed in size and
|
||||
* just use the existing size of the window. */
|
||||
@@ -3644,7 +3646,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
unconstrained_rect.width = window->rect.width;
|
||||
unconstrained_rect.height = window->rect.height;
|
||||
}
|
||||
else if ((flags & META_IS_WAYLAND_RESIZE))
|
||||
else if ((flags & META_MOVE_RESIZE_WAYLAND_RESIZE))
|
||||
{
|
||||
/* This is a Wayland buffer acking our size. The new rect is
|
||||
* just the existing one we have. Ignore the passed-in rect
|
||||
@@ -3655,7 +3657,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
g_assert_not_reached ();
|
||||
|
||||
constrained_rect = unconstrained_rect;
|
||||
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
||||
if (flags & (META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION))
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
meta_window_get_frame_rect (window, &old_rect);
|
||||
@@ -3698,10 +3700,10 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
|
||||
old_output_winsys_id = window->monitor->winsys_id;
|
||||
|
||||
meta_window_update_monitor (window, flags & META_IS_USER_ACTION);
|
||||
meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
|
||||
|
||||
if (old_output_winsys_id != window->monitor->winsys_id &&
|
||||
flags & META_IS_MOVE_ACTION && flags & META_IS_USER_ACTION)
|
||||
flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION)
|
||||
window->preferred_output_winsys_id = window->monitor->winsys_id;
|
||||
|
||||
if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
|
||||
@@ -3739,7 +3741,7 @@ meta_window_move_frame (MetaWindow *window,
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION;
|
||||
flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_MOVE_ACTION;
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
@@ -3789,7 +3791,7 @@ meta_window_move_resize_frame (MetaWindow *window,
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION;
|
||||
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
@@ -3841,7 +3843,7 @@ meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_RESIZE_ACTION;
|
||||
flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_RESIZE_ACTION;
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
|
||||
@@ -4882,73 +4884,51 @@ redraw_icon (MetaWindow *window)
|
||||
* instead of the whole frame.
|
||||
*/
|
||||
if (window->frame)
|
||||
meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
|
||||
meta_frame_queue_draw (window->frame);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
static cairo_surface_t *
|
||||
load_default_window_icon (int size)
|
||||
{
|
||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||
GdkPixbuf *pixbuf;
|
||||
const char *icon_name;
|
||||
|
||||
if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME))
|
||||
icon_name = META_DEFAULT_ICON_NAME;
|
||||
else
|
||||
icon_name = "image-missing";
|
||||
|
||||
pixbuf = gtk_icon_theme_load_icon (theme, icon_name, size, 0, NULL);
|
||||
return gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
get_default_window_icon (void)
|
||||
{
|
||||
static GdkPixbuf *default_icon = NULL;
|
||||
static cairo_surface_t *default_icon = NULL;
|
||||
|
||||
if (default_icon == NULL)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
gboolean icon_exists;
|
||||
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
|
||||
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
|
||||
|
||||
if (icon_exists)
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
META_DEFAULT_ICON_NAME,
|
||||
META_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
else
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
"image-missing",
|
||||
META_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
default_icon = load_default_window_icon (META_ICON_WIDTH);
|
||||
g_assert (default_icon);
|
||||
}
|
||||
|
||||
return g_object_ref (default_icon);
|
||||
return cairo_surface_reference (default_icon);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
static cairo_surface_t *
|
||||
get_default_mini_icon (void)
|
||||
{
|
||||
static GdkPixbuf *default_icon = NULL;
|
||||
static cairo_surface_t *default_icon = NULL;
|
||||
|
||||
if (default_icon == NULL)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
gboolean icon_exists;
|
||||
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
|
||||
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
|
||||
|
||||
if (icon_exists)
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
META_DEFAULT_ICON_NAME,
|
||||
META_MINI_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
else
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
"image-missing",
|
||||
META_MINI_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
default_icon = load_default_window_icon (META_MINI_ICON_WIDTH);
|
||||
g_assert (default_icon);
|
||||
}
|
||||
|
||||
return g_object_ref (default_icon);
|
||||
return cairo_surface_reference (default_icon);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4956,8 +4936,8 @@ meta_window_update_icon_now (MetaWindow *window,
|
||||
gboolean force)
|
||||
{
|
||||
gboolean changed;
|
||||
GdkPixbuf *icon = NULL;
|
||||
GdkPixbuf *mini_icon;
|
||||
cairo_surface_t *icon = NULL;
|
||||
cairo_surface_t *mini_icon;
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
@@ -4966,14 +4946,14 @@ meta_window_update_icon_now (MetaWindow *window,
|
||||
if (changed || force)
|
||||
{
|
||||
if (window->icon)
|
||||
g_object_unref (window->icon);
|
||||
cairo_surface_destroy (window->icon);
|
||||
if (icon)
|
||||
window->icon = icon;
|
||||
else
|
||||
window->icon = get_default_window_icon ();
|
||||
|
||||
if (window->mini_icon)
|
||||
g_object_unref (window->mini_icon);
|
||||
cairo_surface_destroy (window->mini_icon);
|
||||
if (mini_icon)
|
||||
window->mini_icon = mini_icon;
|
||||
else
|
||||
@@ -7447,9 +7427,7 @@ meta_window_set_title (MetaWindow *window,
|
||||
window->title = g_strdup (title);
|
||||
|
||||
if (window->frame)
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
meta_frame_update_title (window->frame);
|
||||
|
||||
meta_window_update_desc (window);
|
||||
|
||||
@@ -7581,8 +7559,6 @@ reset_ignored_crossing_serials (MetaDisplay *display)
|
||||
display->ignored_crossing_serials[i] = 0;
|
||||
++i;
|
||||
}
|
||||
|
||||
display->ungrab_should_not_cause_focus_window = None;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@@ -7797,6 +7773,9 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
gboolean unmodified;
|
||||
gboolean is_window_grab;
|
||||
|
||||
if (window->frame && meta_ui_frame_handle_event (window->frame->ui_frame, event))
|
||||
return;
|
||||
|
||||
if (event->type != CLUTTER_BUTTON_PRESS)
|
||||
return;
|
||||
|
||||
|
@@ -152,14 +152,17 @@ typedef enum
|
||||
{
|
||||
META_GRAB_OP_NONE,
|
||||
|
||||
/* Window grab ops. */
|
||||
META_GRAB_OP_WINDOW_BASE,
|
||||
|
||||
/* Special grab op when the compositor asked for a grab */
|
||||
META_GRAB_OP_COMPOSITOR,
|
||||
|
||||
/* For when a Wayland client takes a popup grab */
|
||||
/* For when a Wayland client takes a popup grab. */
|
||||
META_GRAB_OP_WAYLAND_POPUP,
|
||||
|
||||
/* Window grab ops. */
|
||||
META_GRAB_OP_WINDOW_BASE,
|
||||
/* For when the user clicks on a frame button. */
|
||||
META_GRAB_OP_FRAME_BUTTON,
|
||||
|
||||
META_GRAB_OP_MOVING = META_GRAB_OP_WINDOW_BASE,
|
||||
META_GRAB_OP_RESIZING_NW = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_W,
|
||||
|
37
src/meta/meta-monitor-manager.h
Normal file
37
src/meta/meta-monitor-manager.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_MONITOR_MANAGER_H
|
||||
#define META_MONITOR_MANAGER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass;
|
||||
typedef struct _MetaMonitorManager MetaMonitorManager;
|
||||
|
||||
GType meta_monitor_manager_get_type (void);
|
||||
|
||||
MetaMonitorManager *meta_monitor_manager_get (void);
|
||||
|
||||
gint meta_monitor_manager_get_monitor_for_output (MetaMonitorManager *manager,
|
||||
guint id);
|
||||
|
||||
#endif /* META_MONITOR_MANAGER_H */
|
@@ -43,7 +43,6 @@
|
||||
* @META_PREF_AUTO_RAISE: auto-raise
|
||||
* @META_PREF_AUTO_RAISE_DELAY: auto-raise delay
|
||||
* @META_PREF_FOCUS_CHANGE_ON_POINTER_REST: focus change on pointer rest
|
||||
* @META_PREF_THEME: theme
|
||||
* @META_PREF_TITLEBAR_FONT: title-bar font
|
||||
* @META_PREF_NUM_WORKSPACES: number of workspaces
|
||||
* @META_PREF_DYNAMIC_WORKSPACES: dynamic workspaces
|
||||
@@ -81,7 +80,6 @@ typedef enum
|
||||
META_PREF_AUTO_RAISE,
|
||||
META_PREF_AUTO_RAISE_DELAY,
|
||||
META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
|
||||
META_PREF_THEME,
|
||||
META_PREF_TITLEBAR_FONT,
|
||||
META_PREF_NUM_WORKSPACES,
|
||||
META_PREF_DYNAMIC_WORKSPACES,
|
||||
@@ -128,7 +126,6 @@ GDesktopFocusMode meta_prefs_get_focus_mode (void);
|
||||
GDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void);
|
||||
gboolean meta_prefs_get_attach_modal_dialogs (void);
|
||||
gboolean meta_prefs_get_raise_on_click (void);
|
||||
const char* meta_prefs_get_theme (void);
|
||||
/* returns NULL if GTK default should be used */
|
||||
const PangoFontDescription* meta_prefs_get_titlebar_font (void);
|
||||
int meta_prefs_get_num_workspaces (void);
|
||||
|
@@ -45,7 +45,6 @@ void meta_screen_get_size (MetaScreen *screen,
|
||||
int *height);
|
||||
|
||||
void meta_screen_set_cm_selection (MetaScreen *screen);
|
||||
void meta_screen_unset_cm_selection (MetaScreen *screen);
|
||||
|
||||
GSList *meta_screen_get_startup_sequences (MetaScreen *screen);
|
||||
|
||||
|
@@ -30,15 +30,8 @@
|
||||
*/
|
||||
typedef struct _MetaTheme MetaTheme;
|
||||
|
||||
MetaTheme* meta_theme_get_current (void);
|
||||
void meta_theme_set_current (const char *name);
|
||||
MetaTheme* meta_theme_get_default (void);
|
||||
|
||||
MetaTheme* meta_theme_new (void);
|
||||
void meta_theme_free (MetaTheme *theme);
|
||||
gboolean meta_theme_validate (MetaTheme *theme,
|
||||
GError **error);
|
||||
|
||||
MetaTheme* meta_theme_load (const char *theme_name,
|
||||
GError **err);
|
||||
|
||||
#endif
|
||||
|
@@ -330,8 +330,7 @@ test_client_do (TestClient *client,
|
||||
|
||||
out:
|
||||
g_string_free (command, TRUE);
|
||||
if (line)
|
||||
g_free (line);
|
||||
g_free (line);
|
||||
|
||||
return *error == NULL;
|
||||
}
|
||||
|
952
src/ui/frames.c
952
src/ui/frames.c
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <meta/common.h>
|
||||
#include <meta/types.h>
|
||||
#include "theme-private.h"
|
||||
|
||||
typedef enum
|
||||
@@ -72,14 +73,15 @@ typedef struct _MetaUIFrame MetaUIFrame;
|
||||
|
||||
struct _MetaUIFrame
|
||||
{
|
||||
MetaFrames *frames;
|
||||
MetaWindow *meta_window;
|
||||
Window xwindow;
|
||||
GdkWindow *window;
|
||||
GtkStyleContext *style;
|
||||
MetaFrameStyle *cache_style;
|
||||
PangoLayout *layout;
|
||||
MetaStyleInfo *style_info;
|
||||
MetaFrameLayout *cache_layout;
|
||||
PangoLayout *text_layout;
|
||||
int text_height;
|
||||
char *title; /* NULL once we have a layout */
|
||||
guint shape_applied : 1;
|
||||
guint maybe_ignore_leave_notify : 1;
|
||||
|
||||
/* FIXME get rid of this, it can just be in the MetaFrames struct */
|
||||
@@ -95,9 +97,8 @@ struct _MetaFrames
|
||||
GHashTable *text_heights;
|
||||
|
||||
GHashTable *frames;
|
||||
MetaUIFrame *last_motion_frame;
|
||||
|
||||
GtkStyleContext *normal_style;
|
||||
MetaStyleInfo *normal_style;
|
||||
GHashTable *style_variants;
|
||||
|
||||
MetaGrabOp current_grab_op;
|
||||
@@ -105,8 +106,6 @@ struct _MetaFrames
|
||||
guint grab_button;
|
||||
gdouble grab_x;
|
||||
gdouble grab_y;
|
||||
|
||||
Window grab_xwindow;
|
||||
};
|
||||
|
||||
struct _MetaFramesClass
|
||||
@@ -119,45 +118,31 @@ GType meta_frames_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaFrames *meta_frames_new (int screen_number);
|
||||
|
||||
void meta_frames_manage_window (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
GdkWindow *window);
|
||||
void meta_frames_unmanage_window (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_frames_set_title (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
const char *title);
|
||||
MetaUIFrame * meta_frames_manage_window (MetaFrames *frames,
|
||||
MetaWindow *meta_window,
|
||||
Window xwindow,
|
||||
GdkWindow *window);
|
||||
|
||||
void meta_frames_update_frame_style (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_ui_frame_unmanage (MetaUIFrame *frame);
|
||||
|
||||
void meta_frames_repaint_frame (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_ui_frame_set_title (MetaUIFrame *frame,
|
||||
const char *title);
|
||||
|
||||
void meta_frames_get_borders (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
MetaFrameBorders *borders);
|
||||
void meta_ui_frame_update_style (MetaUIFrame *frame);
|
||||
|
||||
cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
int window_height);
|
||||
void meta_ui_frame_get_borders (MetaUIFrame *frame,
|
||||
MetaFrameBorders *borders);
|
||||
|
||||
void meta_frames_get_mask (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
guint width,
|
||||
guint height,
|
||||
cairo_t *cr);
|
||||
cairo_region_t * meta_ui_frame_get_bounds (MetaUIFrame *frame);
|
||||
|
||||
void meta_frames_move_resize_frame (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void meta_frames_queue_draw (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_ui_frame_get_mask (MetaUIFrame *frame,
|
||||
cairo_t *cr);
|
||||
|
||||
Window meta_frames_get_moving_frame (MetaFrames *frames);
|
||||
void meta_ui_frame_move_resize (MetaUIFrame *frame,
|
||||
int x, int y, int width, int height);
|
||||
|
||||
void meta_ui_frame_queue_draw (MetaUIFrame *frame);
|
||||
|
||||
gboolean meta_ui_frame_handle_event (MetaUIFrame *frame, const ClutterEvent *event);
|
||||
|
||||
#endif
|
||||
|
@@ -1,238 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity resizing-terminal-window feedback */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "resizepopup.h"
|
||||
#include "util-private.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
struct _MetaResizePopup
|
||||
{
|
||||
GtkWidget *size_window;
|
||||
GtkWidget *size_label;
|
||||
Display *display;
|
||||
int screen_number;
|
||||
|
||||
int vertical_size;
|
||||
int horizontal_size;
|
||||
|
||||
gboolean showing;
|
||||
|
||||
MetaRectangle rect;
|
||||
};
|
||||
|
||||
MetaResizePopup*
|
||||
meta_ui_resize_popup_new (Display *display,
|
||||
int screen_number)
|
||||
{
|
||||
MetaResizePopup *popup;
|
||||
|
||||
popup = g_new0 (MetaResizePopup, 1);
|
||||
|
||||
popup->display = display;
|
||||
popup->screen_number = screen_number;
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_resize_popup_free (MetaResizePopup *popup)
|
||||
{
|
||||
g_return_if_fail (popup != NULL);
|
||||
|
||||
if (popup->size_window)
|
||||
gtk_widget_destroy (popup->size_window);
|
||||
|
||||
g_free (popup);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
size_window_draw (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
MetaResizePopup *popup)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
gint width, height;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
gtk_render_background (context, cr, 0, 0, width, height);
|
||||
gtk_render_frame (context, cr, 0, 0, width, height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_size_window (MetaResizePopup *popup)
|
||||
{
|
||||
GdkVisual *visual;
|
||||
GdkScreen *screen;
|
||||
|
||||
if (popup->size_window)
|
||||
return;
|
||||
|
||||
popup->size_window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
screen = gdk_display_get_screen (gdk_x11_lookup_xdisplay (popup->display),
|
||||
popup->screen_number);
|
||||
visual = gdk_screen_get_rgba_visual (screen);
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (popup->size_window), screen);
|
||||
if (visual != NULL)
|
||||
gtk_widget_set_visual (popup->size_window, visual);
|
||||
|
||||
gtk_window_set_type_hint (GTK_WINDOW (popup->size_window),
|
||||
GDK_WINDOW_TYPE_HINT_TOOLTIP);
|
||||
gtk_window_set_resizable (GTK_WINDOW (popup->size_window), FALSE);
|
||||
|
||||
gtk_widget_set_app_paintable (popup->size_window, TRUE);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (popup->size_window),
|
||||
GTK_STYLE_CLASS_TOOLTIP);
|
||||
g_signal_connect (popup->size_window, "draw",
|
||||
G_CALLBACK (size_window_draw), popup);
|
||||
|
||||
popup->size_label = gtk_label_new ("");
|
||||
g_object_set (popup->size_label, "margin", 6, NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (popup->size_window), popup->size_label);
|
||||
|
||||
gtk_widget_show (popup->size_label);
|
||||
}
|
||||
|
||||
static void
|
||||
update_size_window (MetaResizePopup *popup)
|
||||
{
|
||||
char *str;
|
||||
int x, y;
|
||||
int width, height;
|
||||
|
||||
g_return_if_fail (popup->size_window != NULL);
|
||||
|
||||
/* Translators: This represents the size of a window. The first number is
|
||||
* the width of the window and the second is the height.
|
||||
*/
|
||||
str = g_strdup_printf (_("%d x %d"),
|
||||
popup->horizontal_size,
|
||||
popup->vertical_size);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (popup->size_label), str);
|
||||
|
||||
g_free (str);
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (popup->size_window), &width, &height);
|
||||
|
||||
x = popup->rect.x + (popup->rect.width - width) / 2;
|
||||
y = popup->rect.y + (popup->rect.height - height) / 2;
|
||||
|
||||
if (gtk_widget_get_realized (popup->size_window))
|
||||
{
|
||||
/* using move_resize to avoid jumpiness */
|
||||
gdk_window_move_resize (gtk_widget_get_window (popup->size_window),
|
||||
x, y,
|
||||
width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_window_move (GTK_WINDOW (popup->size_window),
|
||||
x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sync_showing (MetaResizePopup *popup)
|
||||
{
|
||||
if (popup->showing)
|
||||
{
|
||||
if (popup->size_window)
|
||||
gtk_widget_show (popup->size_window);
|
||||
|
||||
if (popup->size_window && gtk_widget_get_realized (popup->size_window))
|
||||
gdk_window_raise (gtk_widget_get_window (popup->size_window));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (popup->size_window)
|
||||
gtk_widget_hide (popup->size_window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_resize_popup_set (MetaResizePopup *popup,
|
||||
MetaRectangle rect,
|
||||
int base_width,
|
||||
int base_height,
|
||||
int width_inc,
|
||||
int height_inc)
|
||||
{
|
||||
gboolean need_update_size;
|
||||
int display_w, display_h;
|
||||
|
||||
g_return_if_fail (popup != NULL);
|
||||
|
||||
need_update_size = FALSE;
|
||||
|
||||
display_w = rect.width - base_width;
|
||||
if (width_inc > 0)
|
||||
display_w /= width_inc;
|
||||
|
||||
display_h = rect.height - base_height;
|
||||
if (height_inc > 0)
|
||||
display_h /= height_inc;
|
||||
|
||||
if (!meta_rectangle_equal(&popup->rect, &rect) ||
|
||||
display_w != popup->horizontal_size ||
|
||||
display_h != popup->vertical_size)
|
||||
need_update_size = TRUE;
|
||||
|
||||
popup->rect = rect;
|
||||
popup->vertical_size = display_h;
|
||||
popup->horizontal_size = display_w;
|
||||
|
||||
if (need_update_size)
|
||||
{
|
||||
ensure_size_window (popup);
|
||||
update_size_window (popup);
|
||||
}
|
||||
|
||||
sync_showing (popup);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
|
||||
gboolean showing)
|
||||
{
|
||||
g_return_if_fail (popup != NULL);
|
||||
|
||||
if (showing == popup->showing)
|
||||
return;
|
||||
|
||||
popup->showing = !!showing;
|
||||
|
||||
if (popup->showing)
|
||||
{
|
||||
ensure_size_window (popup);
|
||||
update_size_window (popup);
|
||||
}
|
||||
|
||||
sync_showing (popup);
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Mutter resizing-terminal-window feedback */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_RESIZEPOPUP_H
|
||||
#define META_RESIZEPOPUP_H
|
||||
|
||||
/* Don't include gtk.h or gdk.h here */
|
||||
#include <meta/boxes.h>
|
||||
#include <meta/common.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <glib.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
typedef struct _MetaResizePopup MetaResizePopup;
|
||||
|
||||
MetaResizePopup* meta_ui_resize_popup_new (Display *display,
|
||||
int screen_number);
|
||||
void meta_ui_resize_popup_free (MetaResizePopup *popup);
|
||||
void meta_ui_resize_popup_set (MetaResizePopup *popup,
|
||||
MetaRectangle rect,
|
||||
int base_width,
|
||||
int base_height,
|
||||
int width_inc,
|
||||
int height_inc);
|
||||
void meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
|
||||
gboolean showing);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
5971
src/ui/theme.c
5971
src/ui/theme.c
File diff suppressed because it is too large
Load Diff
428
src/ui/ui.c
428
src/ui/ui.c
@@ -48,11 +48,20 @@ struct _MetaUI
|
||||
void
|
||||
meta_ui_init (void)
|
||||
{
|
||||
const char *gdk_gl_env = NULL;
|
||||
gdk_set_allowed_backends ("x11");
|
||||
|
||||
gdk_gl_env = g_getenv ("GDK_GL");
|
||||
g_setenv("GDK_GL", "disable", TRUE);
|
||||
|
||||
if (!gtk_init_check (NULL, NULL))
|
||||
meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
|
||||
|
||||
if (gdk_gl_env)
|
||||
g_setenv("GDK_GL", gdk_gl_env, TRUE);
|
||||
else
|
||||
unsetenv("GDK_GL");
|
||||
|
||||
/* We need to be able to fully trust that the window and monitor sizes
|
||||
that Gdk reports corresponds to the X ones, so we disable the automatic
|
||||
scale handling */
|
||||
@@ -71,202 +80,6 @@ meta_ui_get_screen_number (void)
|
||||
return gdk_screen_get_number (gdk_screen_get_default ());
|
||||
}
|
||||
|
||||
/* For XInput2 */
|
||||
#include "display-private.h"
|
||||
|
||||
static gboolean
|
||||
is_input_event (XEvent *event)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
return (event->type == GenericEvent &&
|
||||
event->xcookie.extension == display->xinput_opcode);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_interesting_input_event (XEvent *event)
|
||||
{
|
||||
XIEvent *input_event;
|
||||
|
||||
if (!is_input_event (event))
|
||||
return FALSE;
|
||||
|
||||
input_event = (XIEvent *) event->xcookie.data;
|
||||
switch (input_event->evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchEnd:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We do some of our event handling in frames.c, which expects
|
||||
* GDK events delivered by GTK+. However, since the transition to
|
||||
* client side windows, we can't let GDK see button events, since the
|
||||
* client-side tracking of implicit and explicit grabs it does will
|
||||
* get confused by our direct use of X grabs in the core code.
|
||||
*
|
||||
* So we do a very minimal GDK => GTK event conversion here and send on the
|
||||
* events we care about, and then filter them out so they don't go
|
||||
* through the normal GDK event handling.
|
||||
*
|
||||
* To reduce the amount of code, the only events fields filled out
|
||||
* below are the ones that frames.c uses. If frames.c is modified to
|
||||
* use more fields, more fields need to be filled out below.
|
||||
*/
|
||||
|
||||
static void
|
||||
maybe_redirect_mouse_event (XEvent *xevent)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
GdkDeviceManager *gmanager;
|
||||
GdkDevice *gdevice;
|
||||
MetaUI *ui;
|
||||
GdkEvent *gevent;
|
||||
GdkWindow *gdk_window;
|
||||
Window window;
|
||||
XIEvent *xev;
|
||||
XIDeviceEvent *xev_d = NULL;
|
||||
XIEnterEvent *xev_e = NULL;
|
||||
|
||||
xev = (XIEvent *) xevent->xcookie.data;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
xev_d = (XIDeviceEvent *) xev;
|
||||
window = xev_d->event;
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
xev_e = (XIEnterEvent *) xev;
|
||||
window = xev_e->event;
|
||||
break;
|
||||
default:
|
||||
/* Not interested in this event. */
|
||||
return;
|
||||
}
|
||||
|
||||
gdisplay = gdk_x11_lookup_xdisplay (xev->display);
|
||||
ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
|
||||
if (!ui)
|
||||
return;
|
||||
|
||||
gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window);
|
||||
if (gdk_window == NULL)
|
||||
return;
|
||||
|
||||
gmanager = gdk_display_get_device_manager (gdisplay);
|
||||
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
if (xev_d->evtype == XI_ButtonPress)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default ();
|
||||
int double_click_time;
|
||||
int double_click_distance;
|
||||
int button;
|
||||
|
||||
g_object_get (settings,
|
||||
"gtk-double-click-time", &double_click_time,
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
|
||||
button = xev_d->detail;
|
||||
|
||||
if (button == ui->button_click_number &&
|
||||
xev_d->event == ui->button_click_window &&
|
||||
xev_d->time < ui->button_click_time + double_click_time &&
|
||||
ABS (xev_d->event_x - ui->button_click_x) <= double_click_distance &&
|
||||
ABS (xev_d->event_y - ui->button_click_y) <= double_click_distance)
|
||||
{
|
||||
gevent = gdk_event_new (GDK_2BUTTON_PRESS);
|
||||
|
||||
ui->button_click_number = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gevent = gdk_event_new (GDK_BUTTON_PRESS);
|
||||
ui->button_click_number = button;
|
||||
ui->button_click_window = xev_d->event;
|
||||
ui->button_click_time = xev_d->time;
|
||||
ui->button_click_x = xev_d->event_x;
|
||||
ui->button_click_y = xev_d->event_y;
|
||||
}
|
||||
|
||||
gevent->button.button = button;
|
||||
}
|
||||
else
|
||||
{
|
||||
gevent = gdk_event_new (GDK_BUTTON_RELEASE);
|
||||
gevent->button.button = xev_d->detail;
|
||||
}
|
||||
|
||||
gevent->button.window = g_object_ref (gdk_window);
|
||||
gevent->button.time = xev_d->time;
|
||||
gevent->button.x = xev_d->event_x;
|
||||
gevent->button.y = xev_d->event_y;
|
||||
gevent->button.x_root = xev_d->root_x;
|
||||
gevent->button.y_root = xev_d->root_y;
|
||||
break;
|
||||
case XI_Motion:
|
||||
gevent = gdk_event_new (GDK_MOTION_NOTIFY);
|
||||
gevent->motion.window = g_object_ref (gdk_window);
|
||||
gevent->motion.time = xev_d->time;
|
||||
gevent->motion.x = xev_d->event_x;
|
||||
gevent->motion.y = xev_d->event_y;
|
||||
gevent->motion.x_root = xev_d->root_x;
|
||||
gevent->motion.y_root = xev_d->root_y;
|
||||
|
||||
if (XIMaskIsSet (xev_d->buttons.mask, 1))
|
||||
gevent->motion.state |= GDK_BUTTON1_MASK;
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
gevent = gdk_event_new (xev_e->evtype == XI_Enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
|
||||
gevent->crossing.window = g_object_ref (gdk_window);
|
||||
gevent->crossing.time = xev_e->time;
|
||||
gevent->crossing.x = xev_e->event_x;
|
||||
gevent->crossing.y = xev_e->event_y;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we've gotten here, we've created the gdk_event and should send it on */
|
||||
gdk_event_set_device (gevent, gdevice);
|
||||
gtk_main_do_event (gevent);
|
||||
gdk_event_free (gevent);
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
ui_filter_func (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (is_interesting_input_event (xevent))
|
||||
{
|
||||
maybe_redirect_mouse_event (xevent);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
MetaUI*
|
||||
meta_ui_new (Display *xdisplay,
|
||||
Screen *screen)
|
||||
@@ -290,8 +103,6 @@ meta_ui_new (Display *xdisplay,
|
||||
*/
|
||||
gtk_widget_show (GTK_WIDGET (ui->frames));
|
||||
|
||||
gdk_window_add_filter (NULL, ui_filter_func, NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||
|
||||
return ui;
|
||||
@@ -307,30 +118,9 @@ meta_ui_free (MetaUI *ui)
|
||||
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
||||
|
||||
gdk_window_remove_filter (NULL, ui_filter_func, NULL);
|
||||
|
||||
g_free (ui);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_get_frame_mask (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
guint width,
|
||||
guint height,
|
||||
cairo_t *cr)
|
||||
{
|
||||
meta_frames_get_mask (ui->frames, frame_xwindow, width, height, cr);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_get_frame_borders (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
MetaFrameBorders *borders)
|
||||
{
|
||||
meta_frames_get_borders (ui->frames, frame_xwindow,
|
||||
borders);
|
||||
}
|
||||
|
||||
static void
|
||||
set_background_none (Display *xdisplay,
|
||||
Window xwindow)
|
||||
@@ -342,16 +132,17 @@ set_background_none (Display *xdisplay,
|
||||
CWBackPixmap, &attrs);
|
||||
}
|
||||
|
||||
Window
|
||||
meta_ui_create_frame_window (MetaUI *ui,
|
||||
Display *xdisplay,
|
||||
Visual *xvisual,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint screen_no,
|
||||
gulong *create_serial)
|
||||
MetaUIFrame *
|
||||
meta_ui_create_frame (MetaUI *ui,
|
||||
Display *xdisplay,
|
||||
MetaWindow *meta_window,
|
||||
Visual *xvisual,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint screen_no,
|
||||
gulong *create_serial)
|
||||
{
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
|
||||
GdkScreen *screen = gdk_display_get_screen (display, screen_no);
|
||||
@@ -410,27 +201,7 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
gdk_window_resize (window, width, height);
|
||||
set_background_none (xdisplay, GDK_WINDOW_XID (window));
|
||||
|
||||
meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
|
||||
|
||||
return GDK_WINDOW_XID (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_destroy_frame_window (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_unmanage_window (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_move_resize_frame (MetaUI *ui,
|
||||
Window frame,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
|
||||
return meta_frames_manage_window (ui->frames, meta_window, GDK_WINDOW_XID (window), window);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -461,95 +232,6 @@ meta_ui_unmap_frame (MetaUI *ui,
|
||||
gdk_window_hide (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_update_frame_style (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_update_frame_style (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_repaint_frame (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_repaint_frame (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_ui_get_frame_bounds (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
int window_height)
|
||||
{
|
||||
return meta_frames_get_frame_bounds (ui->frames, xwindow,
|
||||
window_width, window_height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_queue_frame_draw (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_queue_draw (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_set_frame_title (MetaUI *ui,
|
||||
Window xwindow,
|
||||
const char *title)
|
||||
{
|
||||
meta_frames_set_title (ui->frames, xwindow, title);
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
Display *display;
|
||||
Window root_return;
|
||||
int x_ret, y_ret;
|
||||
unsigned int w_ret, h_ret, bw_ret, depth_ret;
|
||||
XWindowAttributes attrs;
|
||||
GdkPixbuf *retval;
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
if (!XGetGeometry (display, xpixmap, &root_return,
|
||||
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
|
||||
return NULL;
|
||||
|
||||
if (depth_ret == 1)
|
||||
{
|
||||
surface = cairo_xlib_surface_create_for_bitmap (display,
|
||||
xpixmap,
|
||||
GDK_SCREEN_XSCREEN (gdk_screen_get_default ()),
|
||||
w_ret,
|
||||
h_ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!XGetWindowAttributes (display, root_return, &attrs))
|
||||
return NULL;
|
||||
|
||||
surface = cairo_xlib_surface_create (display,
|
||||
xpixmap,
|
||||
attrs.visual,
|
||||
w_ret, h_ret);
|
||||
}
|
||||
|
||||
retval = gdk_pixbuf_get_from_surface (surface,
|
||||
src_x,
|
||||
src_y,
|
||||
width,
|
||||
height);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_ui_window_should_not_cause_focus (Display *xdisplay,
|
||||
Window xwindow)
|
||||
@@ -576,62 +258,36 @@ meta_ui_theme_get_frame_borders (MetaUI *ui,
|
||||
MetaFrameBorders *borders)
|
||||
{
|
||||
int text_height;
|
||||
GtkStyleContext *style = NULL;
|
||||
MetaStyleInfo *style_info = NULL;
|
||||
PangoContext *context;
|
||||
const PangoFontDescription *font_desc;
|
||||
PangoFontDescription *free_font_desc = NULL;
|
||||
|
||||
if (meta_ui_have_a_theme ())
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
GdkScreen *screen = gdk_display_get_screen (display, XScreenNumberOfScreen (ui->xscreen));
|
||||
|
||||
style_info = meta_theme_create_style_info (screen, NULL);
|
||||
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
|
||||
font_desc = meta_prefs_get_titlebar_font ();
|
||||
|
||||
if (!font_desc)
|
||||
{
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
|
||||
font_desc = meta_prefs_get_titlebar_font ();
|
||||
|
||||
if (!font_desc)
|
||||
{
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
GdkScreen *screen = gdk_display_get_screen (display, XScreenNumberOfScreen (ui->xscreen));
|
||||
GtkWidgetPath *widget_path;
|
||||
|
||||
style = gtk_style_context_new ();
|
||||
gtk_style_context_set_screen (style, screen);
|
||||
widget_path = gtk_widget_path_new ();
|
||||
gtk_widget_path_append_type (widget_path, GTK_TYPE_WINDOW);
|
||||
gtk_style_context_set_path (style, widget_path);
|
||||
gtk_widget_path_free (widget_path);
|
||||
|
||||
gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", &free_font_desc, NULL);
|
||||
font_desc = (const PangoFontDescription *) free_font_desc;
|
||||
}
|
||||
|
||||
text_height = meta_pango_font_desc_get_text_height (font_desc, context);
|
||||
|
||||
meta_theme_get_frame_borders (meta_theme_get_current (),
|
||||
type, text_height, flags,
|
||||
borders);
|
||||
|
||||
if (free_font_desc)
|
||||
pango_font_description_free (free_font_desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_frame_borders_clear (borders);
|
||||
free_font_desc = meta_style_info_create_font_desc (style_info);
|
||||
font_desc = (const PangoFontDescription *) free_font_desc;
|
||||
}
|
||||
|
||||
if (style != NULL)
|
||||
g_object_unref (style);
|
||||
}
|
||||
text_height = meta_pango_font_desc_get_text_height (font_desc, context);
|
||||
|
||||
void
|
||||
meta_ui_set_current_theme (const char *name)
|
||||
{
|
||||
meta_theme_set_current (name);
|
||||
meta_invalidate_default_icons ();
|
||||
}
|
||||
meta_theme_get_frame_borders (meta_theme_get_default (),
|
||||
style_info, type, text_height, flags,
|
||||
borders);
|
||||
|
||||
gboolean
|
||||
meta_ui_have_a_theme (void)
|
||||
{
|
||||
return meta_theme_get_current () != NULL;
|
||||
if (free_font_desc)
|
||||
pango_font_description_free (free_font_desc);
|
||||
|
||||
if (style_info != NULL)
|
||||
meta_style_info_unref (style_info);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
55
src/ui/ui.h
55
src/ui/ui.h
@@ -24,6 +24,7 @@
|
||||
|
||||
/* Don't include gtk.h or gdk.h here */
|
||||
#include <meta/common.h>
|
||||
#include <meta/types.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <cairo.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
typedef struct _MetaUI MetaUI;
|
||||
typedef struct _MetaUIFrame MetaUIFrame;
|
||||
|
||||
typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data);
|
||||
|
||||
@@ -48,27 +50,17 @@ void meta_ui_theme_get_frame_borders (MetaUI *ui,
|
||||
MetaFrameType type,
|
||||
MetaFrameFlags flags,
|
||||
MetaFrameBorders *borders);
|
||||
void meta_ui_get_frame_borders (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
MetaFrameBorders *borders);
|
||||
|
||||
void meta_ui_get_frame_mask (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
guint width,
|
||||
guint height,
|
||||
cairo_t *cr);
|
||||
|
||||
Window meta_ui_create_frame_window (MetaUI *ui,
|
||||
MetaUIFrame * meta_ui_create_frame (MetaUI *ui,
|
||||
Display *xdisplay,
|
||||
MetaWindow *meta_window,
|
||||
Visual *xvisual,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint screen_no,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint screen_no,
|
||||
gulong *create_serial);
|
||||
void meta_ui_destroy_frame_window (MetaUI *ui,
|
||||
Window xwindow);
|
||||
void meta_ui_move_resize_frame (MetaUI *ui,
|
||||
Window frame,
|
||||
int x,
|
||||
@@ -82,38 +74,9 @@ void meta_ui_map_frame (MetaUI *ui,
|
||||
void meta_ui_unmap_frame (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
cairo_region_t *meta_ui_get_frame_bounds (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
int window_height);
|
||||
|
||||
void meta_ui_queue_frame_draw (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
void meta_ui_set_frame_title (MetaUI *ui,
|
||||
Window xwindow,
|
||||
const char *title);
|
||||
|
||||
void meta_ui_update_frame_style (MetaUI *ui,
|
||||
Window window);
|
||||
|
||||
void meta_ui_repaint_frame (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
|
||||
/* FIXME these lack a display arg */
|
||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
|
||||
Window xwindow);
|
||||
|
||||
void meta_ui_set_current_theme (const char *name);
|
||||
gboolean meta_ui_have_a_theme (void);
|
||||
|
||||
gboolean meta_ui_window_is_widget (MetaUI *ui,
|
||||
Window xwindow);
|
||||
gboolean meta_ui_window_is_dummy (MetaUI *ui,
|
||||
|
@@ -91,13 +91,23 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer)
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglError *catch_error = NULL;
|
||||
CoglTexture *texture;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
|
||||
if (buffer->texture)
|
||||
goto out;
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||
|
||||
if (shm_buffer)
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
texture = COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx,
|
||||
buffer->resource,
|
||||
&catch_error));
|
||||
|
||||
if (shm_buffer)
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
cogl_error_free (catch_error);
|
||||
@@ -124,6 +134,8 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
|
||||
n_rectangles = cairo_region_num_rectangles (region);
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
@@ -133,5 +145,7 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
shm_buffer,
|
||||
rect.x, rect.y, 0, NULL);
|
||||
}
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
}
|
||||
|
@@ -410,6 +410,13 @@ data_device_start_drag (struct wl_client *client,
|
||||
seat->pointer.grab != &seat->pointer.default_grab)
|
||||
return;
|
||||
|
||||
if (icon_resource &&
|
||||
meta_wayland_surface_set_role (wl_resource_get_user_data (icon_resource),
|
||||
META_WAYLAND_SURFACE_ROLE_DND,
|
||||
resource,
|
||||
WL_DATA_DEVICE_ERROR_ROLE) != 0)
|
||||
return;
|
||||
|
||||
data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
|
||||
|
||||
drag_grab->generic.interface = &drag_grab_interface;
|
||||
@@ -547,9 +554,16 @@ data_device_set_selection (struct wl_client *client,
|
||||
meta_wayland_data_device_set_selection (data_device, source, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
data_device_release(struct wl_client *client, struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static const struct wl_data_device_interface data_device_interface = {
|
||||
data_device_start_drag,
|
||||
data_device_set_selection,
|
||||
data_device_release,
|
||||
};
|
||||
|
||||
static void
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user