Compare commits
124 Commits
Author | SHA1 | Date | |
---|---|---|---|
af45a50cb1 | |||
72d6efc0d5 | |||
e0ffef06dd | |||
d5b69bcd54 | |||
ac8fe2d9b2 | |||
e7a88dc6b2 | |||
bcdda506e1 | |||
9b26694bbc | |||
f053c09083 | |||
ec9abaf1ef | |||
6b88420465 | |||
fc0a834abb | |||
e30010b9f0 | |||
935d76ba04 | |||
cc013e1daa | |||
a7a376ae1f | |||
5e57af6286 | |||
42b3a34f7b | |||
19d814c887 | |||
46eb682c83 | |||
3aea8d8ce6 | |||
40c3c69435 | |||
8071e5b149 | |||
8a481b3e10 | |||
50e3e3b929 | |||
2c7ef2269f | |||
8bded7d497 | |||
9ebe3419c3 | |||
9385c835b8 | |||
efef0c993b | |||
3a2cd3389a | |||
88acfb8e60 | |||
8e22dce5d7 | |||
e0906a77aa | |||
053f5088df | |||
75b992c7d0 | |||
213f0fa160 | |||
5054b2a99c | |||
d455de32a0 | |||
e7390cff83 | |||
49ea6486e2 | |||
996aeaef41 | |||
a27b2597b9 | |||
0e8ca1a042 | |||
f5f26c9cff | |||
91ac69382d | |||
8cc345fcf5 | |||
96b5042dda | |||
428c687b5a | |||
82bdd1e353 | |||
4bebc5e5fa | |||
be5643cee7 | |||
2ee1c5fa61 | |||
c625d2ee9d | |||
3078f70f90 | |||
7309b20c25 | |||
c16a5ec1cf | |||
f3e1964362 | |||
9b9083180f | |||
7606f79a1e | |||
99c0b82b15 | |||
ca7c1d5e02 | |||
4a770907c1 | |||
049f1556dc | |||
7b20d151ed | |||
8ec0c99ff4 | |||
cf3ee327a0 | |||
3ec3cc248d | |||
7fb3ecc12c | |||
4c9af7267d | |||
db4355ba1e | |||
33150569cd | |||
af2a13ded4 | |||
8b200de35a | |||
57ae203aab | |||
bff75b64be | |||
8899b9da01 | |||
76e816a14f | |||
2750db2a89 | |||
86a913d37a | |||
2857fdbdb8 | |||
69a7d5ff02 | |||
a4f763ac3b | |||
f2afa7aa6c | |||
a5d2555196 | |||
dd5a4ecdf9 | |||
43a1d43f2b | |||
d6d377a447 | |||
ffd95c2ad5 | |||
72be89dfb9 | |||
2feeb57dee | |||
9c81b718f9 | |||
3a63d58d9e | |||
a95ae4d178 | |||
a692fd3808 | |||
377ecdb864 | |||
d7f544f42e | |||
1ab8b854df | |||
ae7aabd5de | |||
b975676c5d | |||
86d8c3954f | |||
54557f062e | |||
130807a308 | |||
e84f694668 | |||
b18542f2b6 | |||
da0aac665f | |||
8b0b0cf028 | |||
6f64d6b0aa | |||
ebeca983c7 | |||
cf88675807 | |||
405f1ce3d0 | |||
6190ae3873 | |||
69c267b142 | |||
9abc071283 | |||
a9df4bb81a | |||
bc9e63d3db | |||
5b5ceede2b | |||
4e63c95c02 | |||
67d3a7a2d7 | |||
bc00f118f3 | |||
5801b5518f | |||
25a796afc6 | |||
27b37407d0 | |||
e23e697043 |
10
.gitignore
vendored
10
.gitignore
vendored
@ -64,12 +64,10 @@ src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/gtk-shell-protocol.c
|
||||
src/gtk-shell-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/pointer-gestures-protocol.c
|
||||
src/pointer-gestures-server-protocol.h
|
||||
src/xserver-protocol.c
|
||||
src/xserver-server-protocol.h
|
||||
src/xdg-shell-unstable-v*-protocol.c
|
||||
src/xdg-shell-unstable-v*-server-protocol.h
|
||||
src/pointer-gestures-unstable-v*-protocol.c
|
||||
src/pointer-gestures-unstable-v*-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
|
75
NEWS
75
NEWS
@ -1,3 +1,78 @@
|
||||
3.19.4
|
||||
======
|
||||
* Fix updating stacking order when setting transient_for [Jonas; #755606]
|
||||
* Support screen rotation when supported by the driver [Carlos; #745079]
|
||||
* Protect against broken WM_CLASS property implementations [Sebastian; #759658]
|
||||
* Handle wl_pointer v5 events on wayland [Carlos; #760637]
|
||||
* Implement DND actions on wayland [Carlos; #760805]
|
||||
* Misc. bug fixes [Jonas, Rui, Ray, Marek; #754711, #756789, #759297, #758613,
|
||||
#760330, #760476, #759222, #760670]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Sebastian Keller, Rui Matos,
|
||||
Florian Müllner, Jasper St. Pierre, Ray Strode
|
||||
|
||||
Translations:
|
||||
Aurimas Černius [lt]
|
||||
|
||||
3.19.3
|
||||
======
|
||||
* Correct refresh rate units on KMS/Wayland [Daniel; #758653]
|
||||
* Fix crash when initial cursor position is not on a monitor [Marek; #756698]
|
||||
* Fix crash when more CRTs are enabled than outputs connected [Rui; #751638]
|
||||
* Fix touch pointer emulation on wayland [Carlos; #756754]
|
||||
* Allow minimizing windows that don't advertise supporting it [Jasper; #758186]
|
||||
* Force 2-finger scroll by default if available [Bastien; #759304]
|
||||
* Fix crash during XWayland initialization [Marek; #751845]
|
||||
* Ensure to send a ConfigureNotify to just mapped windows [Rui; #759492]
|
||||
* Misc. bug fixes and cleanups [Carlos, Jonas, Lionel; #758239, #758633,
|
||||
#755503, #759374]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Lionel Landwerlin, Rui Matos,
|
||||
Bastien Nocera, Daniel Stone, Jasper St. Pierre
|
||||
|
||||
3.19.2
|
||||
======
|
||||
* Fix crash on monitor unplug [Rui; #756796]
|
||||
* Exit cleanly on initialization errors [Owen; #757311]
|
||||
* Allow to determine backend setting from session type [Ray; #741666]
|
||||
* Fix DRM device detection for non-PCI devices [Alban; #754911]
|
||||
* Don't force placement of windows without buffer on wayland [Marek; #751887]
|
||||
* Fix initialization of bypass compositor hint [Rui; #758544]
|
||||
|
||||
Contributors:
|
||||
Alban Browaeys, Marek Chalupa, Rui Matos, Florian Müllner, Ray Strode,
|
||||
Owen W. Taylor
|
||||
|
||||
3.19.1
|
||||
======
|
||||
* wayland: Allow to trigger popups through keyboard/touch [Carlos; #756296]
|
||||
* Fix modifiers-only input source switching on Ubuntu [Alberts; #756543]
|
||||
* Misc. bug fixes [Jonas, Rui, Giovanni, Florian; #756675, #756660, #746420,
|
||||
#756548, #756796, #757101, #757148]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Rui Matos,
|
||||
Alberts Muktupāvels, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Daniel Șerbănescu [ro]
|
||||
|
||||
3.18.1
|
||||
======
|
||||
* Misc. crash fixes [Jonas, Rui, Carlos, Owen, Florian; #755096, #754979,
|
||||
#755490, #754357, #745785, #756642]
|
||||
* Improve HiDPI support on wayland [Jonas; #755097]
|
||||
* Fix doubly-scaled cursor on XWayland HiDPI [Jonas; #755099]
|
||||
* Stop hiding titlebar buttons in dialogs [Florian; #641630]
|
||||
* Add support for fullscreen/unfullscreen animations [Cosimo; #707248]
|
||||
* Misc. bug fixes [Rui, Colin, Florian; #743339, #752047, #756074, #756649]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Colin Walters, Owen W. Taylor
|
||||
|
||||
3.18.0
|
||||
======
|
||||
* Misc. fixes [Florian, Jonas; #753434]
|
||||
|
15
configure.ac
15
configure.ac
@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [18])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
m4_define([mutter_minor_version], [19])
|
||||
m4_define([mutter_micro_version], [4])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@ -46,6 +46,7 @@ IT_PROG_INTLTOOL([0.41])
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_SED
|
||||
AC_HEADER_STDC
|
||||
PKG_PROG_PKG_CONFIG([0.21])
|
||||
|
||||
@ -58,12 +59,12 @@ CANBERRA_GTK_VERSION=0.26
|
||||
CLUTTER_PACKAGE=clutter-1.0
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gtk+-3.0 >= 3.9.11
|
||||
gtk+-3.0 >= 3.19.7
|
||||
gio-unix-2.0 >= 2.35.1
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.15.92
|
||||
$CLUTTER_PACKAGE >= 1.23.4
|
||||
gsettings-desktop-schemas >= 3.19.3
|
||||
$CLUTTER_PACKAGE >= 1.25.1
|
||||
cogl-1.0 >= 1.17.1
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
@ -219,6 +220,10 @@ AS_IF([test "$have_wayland" = "yes"], [
|
||||
[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])
|
||||
|
||||
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.0],
|
||||
[ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
|
||||
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
desktopfiles_in_files = \
|
||||
mutter.desktop.in \
|
||||
mutter-wayland.desktop.in
|
||||
mutter.desktop.in
|
||||
desktopfilesdir = $(datadir)/applications
|
||||
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
_Name=Mutter (wayland compositor)
|
||||
Exec=mutter --wayland --display-server
|
||||
NoDisplay=true
|
||||
# name of loadable control center module
|
||||
X-GNOME-WMSettingsModule=metacity
|
||||
# name we put on the WM spec check window
|
||||
X-GNOME-WMName=Mutter
|
||||
# back compat only
|
||||
X-GnomeWMSettingsLibrary=metacity
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=mutter
|
||||
X-GNOME-Bugzilla-Component=general
|
||||
X-GNOME-Autostart-Phase=WindowManager
|
||||
X-GNOME-Provides=windowmanager
|
||||
X-GNOME-Autostart-Notify=true
|
@ -1 +1,2 @@
|
||||
data/mutter-wayland.desktop.in
|
||||
# List of source files that should NOT be translated.
|
||||
# Please keep this file sorted alphabetically.
|
||||
|
114
po/lt.po
114
po/lt.po
@ -13,8 +13,8 @@ msgstr ""
|
||||
"Project-Id-Version: lt\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2015-02-28 11:14+0000\n"
|
||||
"PO-Revision-Date: 2015-02-28 21:34+0200\n"
|
||||
"POT-Creation-Date: 2016-01-05 13:43+0000\n"
|
||||
"PO-Revision-Date: 2016-01-05 18:04+0200\n"
|
||||
"Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n"
|
||||
"Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n"
|
||||
"Language: lt\n"
|
||||
@ -23,7 +23,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
|
||||
"%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Gtranslator 2.91.6\n"
|
||||
"X-Generator: Poedit 1.8.6\n"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:1
|
||||
msgid "Navigation"
|
||||
@ -31,39 +31,39 @@ msgstr "Navigacija"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:2
|
||||
msgid "Move window to workspace 1"
|
||||
msgstr "Perkelti langą į darbalaukį Nr.1"
|
||||
msgstr "Perkelti langą į darbo sritį Nr.1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:3
|
||||
msgid "Move window to workspace 2"
|
||||
msgstr "Perkelti langą į darbalaukį Nr.2"
|
||||
msgstr "Perkelti langą į darbo sritį Nr.2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:4
|
||||
msgid "Move window to workspace 3"
|
||||
msgstr "Perkelti langą į darbalaukį Nr.3"
|
||||
msgstr "Perkelti langą į darbo sritį Nr.3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:5
|
||||
msgid "Move window to workspace 4"
|
||||
msgstr "Perkelti langą į darbalaukį Nr.4"
|
||||
msgstr "Perkelti langą į darbo sritį Nr.4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:6
|
||||
msgid "Move window to last workspace"
|
||||
msgstr "Perkelti langą į pastarąjį darbalaukį"
|
||||
msgstr "Perkelti langą į pastarąją darbo sritį"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:7
|
||||
msgid "Move window one workspace to the left"
|
||||
msgstr "Perkelti langą į kairiau esantį darbalaukį"
|
||||
msgstr "Perkelti langą į kairiau esančią darbo sritį"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:8
|
||||
msgid "Move window one workspace to the right"
|
||||
msgstr "Perkelti langą į dešiniau esantį darbalaukį"
|
||||
msgstr "Perkelti langą į dešiniau esančią darbo sritį"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:9
|
||||
msgid "Move window one workspace up"
|
||||
msgstr "Perkelti langą į aukščiau esantį darbalaukį"
|
||||
msgstr "Perkelti langą į aukščiau esančią darbo sritį"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:10
|
||||
msgid "Move window one workspace down"
|
||||
msgstr "Perkelti langą į žemiau esantį darbalaukį"
|
||||
msgstr "Perkelti langą į žemiau esančią darbo sritį"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:11
|
||||
msgid "Move window one monitor to the left"
|
||||
@ -143,39 +143,39 @@ msgstr "Paslėpti visus įprastinius langus"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Persijungti į darbalaukį Nr.1"
|
||||
msgstr "Persijungti į darbo sritį Nr.1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Persijungti į darbalaukį Nr.2"
|
||||
msgstr "Persijungti į darbo sritį Nr.2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:32
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Persijungti į darbalaukį Nr.3"
|
||||
msgstr "Persijungti į darbo sritį Nr.3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:33
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Persijungti į darbalaukį Nr.4"
|
||||
msgstr "Persijungti į darbo sritį Nr.4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Persijungti į pastarąjį darbalaukį"
|
||||
msgstr "Persijungti į pastarąją darbo sritį"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:35
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Perkelti į darbalaukį kairėje"
|
||||
msgstr "Perkelti į darbo sritį kairėje"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:36
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Perkelti į darbalaukį dešinėje"
|
||||
msgstr "Perkelti į darbo sritį dešinėje"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:37
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Perkelti į darbalaukį viršuje"
|
||||
msgstr "Perkelti į darbo sritį viršuje"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:38
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Perkelti į darbalaukį apačioje"
|
||||
msgstr "Perkelti į darbo sritį apačioje"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:1
|
||||
msgid "System"
|
||||
@ -235,7 +235,7 @@ msgstr "Keisti lango dydį"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:12
|
||||
msgid "Toggle window on all workspaces or one"
|
||||
msgstr "Perjungti lango buvimo visuose darbalaukiuose būseną"
|
||||
msgstr "Perjungti lango buvimo visose darbo srityse būseną"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:13
|
||||
msgid "Raise window if covered, otherwise lower it"
|
||||
@ -272,7 +272,7 @@ msgstr "Mutter"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
|
||||
msgid "Modifier to use for extended window management operations"
|
||||
msgstr "Klavišas, naudojamas kartu su specialiais lango valdymo veiksmais"
|
||||
msgstr "Klavišas, naudojamas kartu su specialiomis lango tvarkymo operacijomis"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
|
||||
msgid ""
|
||||
@ -315,7 +315,7 @@ msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Darbalaukiai valdomi dinamiškai"
|
||||
msgstr "Darbo sritys tvarkomos dinamiškai"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
|
||||
msgid ""
|
||||
@ -323,21 +323,21 @@ msgid ""
|
||||
"static number of workspaces (determined by the num-workspaces key in org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
"Nusako, ar darbastaliai yra valdomi dinamiškai, ar yra pastovus darbalaukių "
|
||||
"skaičius (nusakomas raktu num-workspaces schemoje org.gnome.desktop.wm."
|
||||
"preferences)."
|
||||
"Nusako, ar darbo sritys yra tvarkomos dinamiškai, ar yra pastovus darbo "
|
||||
"sričių skaičius (nusakomas raktu num-workspaces schemoje org.gnome.desktop."
|
||||
"wm.preferences)."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
|
||||
msgid "Workspaces only on primary"
|
||||
msgstr "Darbalaukiai tik pagrindiniame"
|
||||
msgstr "Darbo sritys tik pagrindiniame"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
|
||||
msgid ""
|
||||
"Determines whether workspace switching should happen for windows on all "
|
||||
"monitors or only for windows on the primary monitor."
|
||||
msgstr ""
|
||||
"Nusako, ar darbalaukių perjungimas turi įvykti langams viusose monitoriuose, "
|
||||
"ar tik langams pagrindiniame monitoriuje."
|
||||
"Nusako, ar darbo sričių perjungimas turi įvykti langams visuose "
|
||||
"monitoriuose, ar tik langams pagrindiniame monitoriuje."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
|
||||
msgid "No tab popup"
|
||||
@ -438,46 +438,41 @@ msgid "Switch to VT 7"
|
||||
msgstr "Persijungti į VT 7"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
#| msgid "Switch to VT 1"
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "Persijungti į VT 8"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
#| msgid "Switch to VT 1"
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "Persijungti į VT 9"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
#| msgid "Switch to VT 1"
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "Persijungti į VT 10"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
#| msgid "Switch to VT 1"
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "Persijungti į VT 11"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
#| msgid "Switch to VT 1"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Persijungti į VT 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
#: ../src/backends/meta-monitor-manager.c:518
|
||||
msgid "Built-in display"
|
||||
msgstr "Integruotas vaizduoklis"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
#: ../src/backends/meta-monitor-manager.c:544
|
||||
msgid "Unknown"
|
||||
msgstr "Nežinomas"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
#: ../src/backends/meta-monitor-manager.c:546
|
||||
msgid "Unknown Display"
|
||||
msgstr "Nežinomas vaizduoklis"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#: ../src/backends/meta-monitor-manager.c:554
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
@ -489,7 +484,7 @@ msgstr "%s %s"
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr "Kita kompozicijos valdyklė jau veikia ekrane %i vaizduoklyje „%s“."
|
||||
msgstr "Kita kompozicijos tvarkytuvė jau veikia ekrane %i vaizduoklyje „%s“."
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
@ -518,40 +513,40 @@ msgstr "_Laukti"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Priverstinai išeiti"
|
||||
|
||||
#: ../src/core/display.c:562
|
||||
#: ../src/core/display.c:563
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Nepavyko atverti X Window sistemos ekrano „%s“\n"
|
||||
|
||||
#: ../src/core/main.c:176
|
||||
#: ../src/core/main.c:180
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Išjungti susijungimą su sesijos valdykle"
|
||||
msgstr "Išjungti susijungimą su sesijos tvarkytuve"
|
||||
|
||||
#: ../src/core/main.c:182
|
||||
#: ../src/core/main.c:186
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Pakeisti veikiančią langų valdyklę"
|
||||
msgstr "Pakeisti veikiančią langų tvarkytuvę"
|
||||
|
||||
#: ../src/core/main.c:188
|
||||
#: ../src/core/main.c:192
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Nurodyti sesijos valdymo ID"
|
||||
msgstr "Nurodyti sesijos tvarkymo ID"
|
||||
|
||||
#: ../src/core/main.c:193
|
||||
#: ../src/core/main.c:197
|
||||
msgid "X Display to use"
|
||||
msgstr "Naudotinas X ekranas"
|
||||
|
||||
#: ../src/core/main.c:199
|
||||
#: ../src/core/main.c:203
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Inicializuoti sesiją iš išsaugojimo failo"
|
||||
|
||||
#: ../src/core/main.c:205
|
||||
#: ../src/core/main.c:209
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Sinchronizuoti X iškvietimus"
|
||||
|
||||
#: ../src/core/main.c:212
|
||||
#: ../src/core/main.c:216
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Vykdyti kaip wayland kompozitorių"
|
||||
|
||||
#: ../src/core/main.c:220
|
||||
#: ../src/core/main.c:224
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Vykdyti kaip visą vaizduoklio serverį, o ne vidinį"
|
||||
|
||||
@ -580,24 +575,21 @@ msgstr "Parodyti versiją"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Naudojamas Mutter įskiepis"
|
||||
|
||||
#: ../src/core/prefs.c:2004
|
||||
#: ../src/core/prefs.c:1997
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Darbalaukis %d"
|
||||
msgstr "Darbo sritis %d"
|
||||
|
||||
#: ../src/core/screen.c:525
|
||||
#: ../src/core/screen.c:526
|
||||
#, 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 ""
|
||||
"Vaizduoklis „%s“ jau turi langų valdyklę; pabandykite pakeisti esamą langų "
|
||||
"valdyklę naudodami parametrą --replace."
|
||||
"Vaizduoklis „%s“ jau turi langų tvarkytuvę; pabandykite pakeisti esamą langų "
|
||||
"tvarkytuvę, naudodami parametrą --replace."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#: ../src/core/screen.c:608
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Ekranas %d vaizduoklyje „%s“ netinkamas\n"
|
||||
|
@ -9,6 +9,7 @@ dist_stacking_DATA = \
|
||||
tests/stacking/basic-wayland.metatest \
|
||||
tests/stacking/minimized.metatest \
|
||||
tests/stacking/mixed-windows.metatest \
|
||||
tests/stacking/set-parent.metatest \
|
||||
tests/stacking/override-redirect.metatest
|
||||
|
||||
mutter-all.test: tests/mutter-all.test.in
|
||||
|
@ -45,19 +45,17 @@ mutter_built_sources = \
|
||||
|
||||
if HAVE_WAYLAND
|
||||
mutter_built_sources += \
|
||||
pointer-gestures-protocol.c \
|
||||
pointer-gestures-server-protocol.h \
|
||||
pointer-gestures-unstable-v1-protocol.c \
|
||||
pointer-gestures-unstable-v1-server-protocol.h \
|
||||
gtk-shell-protocol.c \
|
||||
gtk-shell-server-protocol.h \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-server-protocol.h \
|
||||
xdg-shell-unstable-v5-protocol.c \
|
||||
xdg-shell-unstable-v5-server-protocol.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
wayland_protocols = \
|
||||
wayland/protocol/pointer-gestures.xml \
|
||||
wayland/protocol/gtk-shell.xml \
|
||||
wayland/protocol/xdg-shell.xml \
|
||||
$(NULL)
|
||||
|
||||
libmutter_la_SOURCES = \
|
||||
@ -481,6 +479,20 @@ $(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
|
||||
--generate-c-code meta-dbus-login1 \
|
||||
$(srcdir)/org.freedesktop.login1.xml
|
||||
|
||||
.SECONDEXPANSION:
|
||||
|
||||
define protostability
|
||||
$(shell echo $1 | sed 's/.*\(\<unstable\>\|\<stable\>\).*/\1/')
|
||||
endef
|
||||
|
||||
define protoname
|
||||
$(shell echo $1 | sed 's/\([a-z\-]\+\)-[a-z]\+-v[0-9]\+/\1/')
|
||||
endef
|
||||
|
||||
%-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/$$(call protostability,$$*)/$$(call protoname,$$*)/$$*.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
%-server-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/$$(call protostability,$$*)/$$(call protoname,$$*)/$$*.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
|
||||
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-input-settings-private.h"
|
||||
@ -626,7 +628,10 @@ meta_clutter_init (void)
|
||||
meta_create_backend ();
|
||||
|
||||
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
|
||||
g_error ("Unable to initialize Clutter.\n");
|
||||
{
|
||||
g_warning ("Unable to initialize Clutter.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "meta-cursor-renderer.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <backends/meta-backend-private.h>
|
||||
#include <backends/meta-monitor-manager-private.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
@ -116,6 +118,14 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
||||
};
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_cursor_in_monitors_area (int x, int y)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (meta_get_backend ());
|
||||
return meta_monitor_manager_get_monitor_at_point (monitor_manager,
|
||||
(gfloat) x, (gfloat) y) >= 0;
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
@ -124,6 +134,11 @@ update_cursor (MetaCursorRenderer *renderer,
|
||||
gboolean handled_by_backend;
|
||||
gboolean should_redraw = FALSE;
|
||||
|
||||
/* do not render cursor if it is not on any monitor. Such situation
|
||||
* can occur e. g. after monitor hot-plug */
|
||||
if (!is_cursor_in_monitors_area (priv->current_x, priv->current_y))
|
||||
return;
|
||||
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_prepare_at (cursor_sprite,
|
||||
priv->current_x,
|
||||
|
@ -54,8 +54,6 @@ struct _MetaCursorRendererClass
|
||||
XcursorImage *xc_image);
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaCursorRenderer * meta_cursor_renderer_new (void);
|
||||
|
||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
|
@ -361,12 +361,12 @@ get_pointer_position_gdk (int *x,
|
||||
int *y,
|
||||
int *mods)
|
||||
{
|
||||
GdkDeviceManager *gmanager;
|
||||
GdkSeat *gseat;
|
||||
GdkDevice *gdevice;
|
||||
GdkScreen *gscreen;
|
||||
|
||||
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
|
||||
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
|
||||
gseat = gdk_display_get_default_seat (gdk_display_get_default ());
|
||||
gdevice = gdk_seat_get_pointer (gseat);
|
||||
|
||||
gdk_device_get_position (gdevice, &gscreen, x, y);
|
||||
if (mods)
|
||||
|
@ -60,8 +60,6 @@ struct _MetaCursorSprite
|
||||
gboolean theme_dirty;
|
||||
};
|
||||
|
||||
GType meta_cursor_sprite_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
|
||||
|
||||
static const char *
|
||||
|
@ -63,9 +63,9 @@ struct _MetaInputSettingsClass
|
||||
void (* set_invert_scroll) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted);
|
||||
void (* set_scroll_method) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode);
|
||||
void (* set_edge_scroll) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled);
|
||||
void (* set_scroll_button) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button);
|
||||
|
@ -395,11 +395,11 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
update_touchpad_edge_scroll (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
gboolean edge_scroll_enabled;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (device &&
|
||||
@ -408,19 +408,19 @@ update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
||||
|
||||
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");
|
||||
edge_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "edge-scrolling-enabled");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_uint_setting (input_settings, device,
|
||||
input_settings_class->set_scroll_method,
|
||||
method);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_edge_scroll,
|
||||
edge_scroll_enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
(ConfigUintFunc) input_settings_class->set_scroll_method,
|
||||
method);
|
||||
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
(ConfigBoolFunc) input_settings_class->set_edge_scroll,
|
||||
edge_scroll_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,7 +429,7 @@ update_touchpad_click_method (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
GDesktopTouchpadClickMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (device &&
|
||||
@ -523,15 +523,13 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
}
|
||||
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;
|
||||
device = devices->data;
|
||||
|
||||
if (device_is_trackball (device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
@ -647,8 +645,8 @@ meta_input_settings_changed_cb (GSettings *settings,
|
||||
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 (strcmp (key, "edge-scrolling-enabled") == 0)
|
||||
update_touchpad_edge_scroll (input_settings, NULL);
|
||||
else if (strcmp (key, "click-method") == 0)
|
||||
update_touchpad_click_method (input_settings, NULL);
|
||||
}
|
||||
@ -773,7 +771,7 @@ apply_device_settings (MetaInputSettings *input_settings,
|
||||
update_device_natural_scroll (input_settings, device);
|
||||
update_touchpad_tap_enabled (input_settings, device);
|
||||
update_touchpad_send_events (input_settings, device);
|
||||
update_touchpad_scroll_method (input_settings, device);
|
||||
update_touchpad_edge_scroll (input_settings, device);
|
||||
update_touchpad_click_method (input_settings, device);
|
||||
|
||||
update_trackball_scroll_button (input_settings, device);
|
||||
|
@ -1846,7 +1846,7 @@ crtc_assignment_assign (CrtcAssignment *assign,
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaCRTCInfo *info = g_slice_new0 (MetaCRTCInfo);
|
||||
info = g_slice_new0 (MetaCRTCInfo);
|
||||
|
||||
info->crtc = crtc;
|
||||
info->mode = mode;
|
||||
|
@ -197,7 +197,7 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
MetaOutput *output;
|
||||
int i, n_outputs;
|
||||
unsigned int j;
|
||||
int width, height;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
@ -223,10 +223,9 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
screen_width = MAX (screen_width, crtc_info->x + width);
|
||||
screen_height = MAX (screen_height, crtc_info->y + height);
|
||||
|
||||
n_outputs = crtc_info->outputs->len;
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||
{
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[i];
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
|
@ -414,6 +414,10 @@ gint meta_monitor_manager_get_monitor_at_point (MetaMonitorManager
|
||||
gfloat x,
|
||||
gfloat y);
|
||||
|
||||
void meta_monitor_manager_clear_output (MetaOutput *output);
|
||||
void meta_monitor_manager_clear_mode (MetaMonitorMode *mode);
|
||||
void meta_monitor_manager_clear_crtc (MetaCRTC *crtc);
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
static inline gboolean
|
||||
|
@ -178,7 +178,7 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
unsigned int i, j;
|
||||
|
||||
monitor_infos = g_array_sized_new (FALSE, TRUE, sizeof (MetaMonitorInfo),
|
||||
manager->n_outputs);
|
||||
manager->n_crtcs);
|
||||
|
||||
/* Walk the list of MetaCRTCs, and build a MetaMonitorInfo
|
||||
for each of them, unless they reference a rectangle that
|
||||
@ -346,6 +346,23 @@ meta_monitor_manager_constructed (GObject *object)
|
||||
manager->in_init = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_clear_output (MetaOutput *output)
|
||||
{
|
||||
g_free (output->name);
|
||||
g_free (output->vendor);
|
||||
g_free (output->product);
|
||||
g_free (output->serial);
|
||||
g_free (output->modes);
|
||||
g_free (output->possible_crtcs);
|
||||
g_free (output->possible_clones);
|
||||
|
||||
if (output->driver_notify)
|
||||
output->driver_notify (output);
|
||||
|
||||
memset (output, 0, sizeof (*output));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
int n_old_outputs)
|
||||
@ -353,22 +370,22 @@ meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_old_outputs; i++)
|
||||
{
|
||||
g_free (old_outputs[i].name);
|
||||
g_free (old_outputs[i].vendor);
|
||||
g_free (old_outputs[i].product);
|
||||
g_free (old_outputs[i].serial);
|
||||
g_free (old_outputs[i].modes);
|
||||
g_free (old_outputs[i].possible_crtcs);
|
||||
g_free (old_outputs[i].possible_clones);
|
||||
|
||||
if (old_outputs[i].driver_notify)
|
||||
old_outputs[i].driver_notify (&old_outputs[i]);
|
||||
}
|
||||
meta_monitor_manager_clear_output (&old_outputs[i]);
|
||||
|
||||
g_free (old_outputs);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_clear_mode (MetaMonitorMode *mode)
|
||||
{
|
||||
g_free (mode->name);
|
||||
|
||||
if (mode->driver_notify)
|
||||
mode->driver_notify (mode);
|
||||
|
||||
memset (mode, 0, sizeof (*mode));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
int n_old_modes)
|
||||
@ -376,16 +393,20 @@ meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_old_modes; i++)
|
||||
{
|
||||
g_free (old_modes[i].name);
|
||||
|
||||
if (old_modes[i].driver_notify)
|
||||
old_modes[i].driver_notify (&old_modes[i]);
|
||||
}
|
||||
meta_monitor_manager_clear_mode (&old_modes[i]);
|
||||
|
||||
g_free (old_modes);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_clear_crtc (MetaCRTC *crtc)
|
||||
{
|
||||
if (crtc->driver_notify)
|
||||
crtc->driver_notify (crtc);
|
||||
|
||||
memset (crtc, 0, sizeof (*crtc));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_free_crtc_array (MetaCRTC *old_crtcs,
|
||||
int n_old_crtcs)
|
||||
@ -393,10 +414,7 @@ meta_monitor_manager_free_crtc_array (MetaCRTC *old_crtcs,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_old_crtcs; i++)
|
||||
{
|
||||
if (old_crtcs[i].driver_notify)
|
||||
old_crtcs[i].driver_notify (&old_crtcs[i]);
|
||||
}
|
||||
meta_monitor_manager_clear_crtc (&old_crtcs[i]);
|
||||
|
||||
g_free (old_crtcs);
|
||||
}
|
||||
@ -884,8 +902,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
crtc_info->y = 0;
|
||||
}
|
||||
|
||||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
|
||||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
|
||||
if (transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
|
||||
((crtc->all_transforms & (1 << transform)) == 0))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
#include "meta-launcher.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct _MetaBackendNativePrivate
|
||||
{
|
||||
MetaLauncher *launcher;
|
||||
@ -327,8 +329,15 @@ static void
|
||||
meta_backend_native_init (MetaBackendNative *native)
|
||||
{
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
GError *error = NULL;
|
||||
|
||||
priv->launcher = meta_launcher_new (&error);
|
||||
if (priv->launcher == NULL)
|
||||
{
|
||||
g_warning ("Can't initialize KMS backend: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
priv->launcher = meta_launcher_new ();
|
||||
priv->barrier_manager = meta_barrier_manager_native_new ();
|
||||
|
||||
priv->up_client = up_client_new ();
|
||||
|
@ -258,6 +258,9 @@ has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
if (!cursor_priv)
|
||||
return FALSE;
|
||||
|
||||
switch (cursor_priv->pending_bo_state)
|
||||
{
|
||||
case META_CURSOR_GBM_BO_STATE_NONE:
|
||||
@ -273,6 +276,32 @@ has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cursor_over_transformed_crtc (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaMonitorManager *monitors;
|
||||
MetaCRTC *crtcs;
|
||||
unsigned int i, n_crtcs;
|
||||
MetaRectangle rect;
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
meta_monitor_manager_get_resources (monitors, NULL, NULL,
|
||||
&crtcs, &n_crtcs, NULL, NULL);
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
if (!meta_rectangle_overlap (&rect, &crtcs[i].rect))
|
||||
continue;
|
||||
|
||||
if (crtcs[i].transform != META_MONITOR_TRANSFORM_NORMAL)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_have_hw_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
@ -282,6 +311,9 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
|
||||
if (!cursor_sprite)
|
||||
return FALSE;
|
||||
|
||||
if (cursor_over_transformed_crtc (renderer, cursor_sprite))
|
||||
return FALSE;
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
@ -164,56 +164,36 @@ meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native)
|
||||
monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
MetaIdleMonitorNative *monitor_native;
|
||||
GList *fired_watches;
|
||||
} CheckNativeClosure;
|
||||
|
||||
static gboolean
|
||||
check_native_watch (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaIdleMonitorWatchNative *watch_native = value;
|
||||
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native;
|
||||
CheckNativeClosure *closure = user_data;
|
||||
gboolean steal;
|
||||
|
||||
if (watch->timeout_msec == 0)
|
||||
{
|
||||
closure->fired_watches = g_list_prepend (closure->fired_watches, watch);
|
||||
steal = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_source_set_ready_time (watch_native->timeout_source,
|
||||
closure->monitor_native->last_event_time +
|
||||
watch->timeout_msec * 1000);
|
||||
steal = FALSE;
|
||||
}
|
||||
|
||||
return steal;
|
||||
}
|
||||
|
||||
static void
|
||||
fire_native_watch (gpointer watch,
|
||||
gpointer data)
|
||||
{
|
||||
_meta_idle_monitor_watch_fire (watch);
|
||||
}
|
||||
|
||||
void
|
||||
meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor)
|
||||
{
|
||||
MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor);
|
||||
CheckNativeClosure closure;
|
||||
GList *node, *watch_ids;
|
||||
|
||||
monitor_native->last_event_time = g_get_monotonic_time ();
|
||||
|
||||
closure.monitor_native = monitor_native;
|
||||
closure.fired_watches = NULL;
|
||||
g_hash_table_foreach_steal (monitor->watches, check_native_watch, &closure);
|
||||
watch_ids = g_hash_table_get_keys (monitor->watches);
|
||||
|
||||
g_list_foreach (closure.fired_watches, fire_native_watch, NULL);
|
||||
g_list_free (closure.fired_watches);
|
||||
for (node = watch_ids; node != NULL; node = node->next)
|
||||
{
|
||||
guint watch_id = GPOINTER_TO_UINT (node->data);
|
||||
MetaIdleMonitorWatchNative *watch;
|
||||
|
||||
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
|
||||
if (!watch)
|
||||
continue;
|
||||
|
||||
if (watch->base.timeout_msec == 0)
|
||||
{
|
||||
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_source_set_ready_time (watch->timeout_source,
|
||||
monitor_native->last_event_time +
|
||||
watch->base.timeout_msec * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (watch_ids);
|
||||
}
|
||||
|
@ -154,30 +154,30 @@ device_set_click_method (struct libinput_device *libinput_device,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_scroll_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode)
|
||||
meta_input_settings_native_set_edge_scroll (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean edge_scrolling_enabled)
|
||||
{
|
||||
enum libinput_config_scroll_method scroll_method = 0;
|
||||
struct libinput_device *libinput_device;
|
||||
enum libinput_config_scroll_method supported;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
supported = libinput_device_config_scroll_get_methods (libinput_device);
|
||||
|
||||
switch (mode)
|
||||
if (supported & LIBINPUT_CONFIG_SCROLL_2FG)
|
||||
{
|
||||
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_EDGE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (supported & LIBINPUT_CONFIG_SCROLL_EDGE &&
|
||||
edge_scrolling_enabled)
|
||||
{
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
}
|
||||
|
||||
device_set_scroll_method (libinput_device, scroll_method);
|
||||
}
|
||||
@ -252,7 +252,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
||||
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_edge_scroll = meta_input_settings_native_set_edge_scroll;
|
||||
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
|
||||
input_settings_class->set_click_method = meta_input_settings_native_set_click_method;
|
||||
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;
|
||||
|
@ -54,30 +54,22 @@ struct _MetaLauncher
|
||||
gboolean session_active;
|
||||
};
|
||||
|
||||
static void
|
||||
report_error_and_die (const char *prefix,
|
||||
GError *error)
|
||||
{
|
||||
/* if a function returns due to g_return_val_if_fail,
|
||||
* then the error may not be set */
|
||||
if (error)
|
||||
g_error ("%s: %s", prefix, error->message);
|
||||
else
|
||||
g_error ("%s", prefix);
|
||||
|
||||
/* the error is not freed, but it is ok as g_error aborts the process */
|
||||
}
|
||||
|
||||
static Login1Session *
|
||||
get_session_proxy (GCancellable *cancellable)
|
||||
get_session_proxy (GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
char *proxy_path;
|
||||
char *session_id;
|
||||
Login1Session *session_proxy;
|
||||
GError *error = NULL;
|
||||
|
||||
if (sd_pid_get_session (getpid (), &session_id) < 0)
|
||||
return NULL;
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get session ID: %m");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
|
||||
|
||||
@ -85,9 +77,9 @@ get_session_proxy (GCancellable *cancellable)
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
proxy_path,
|
||||
cancellable, &error);
|
||||
cancellable, error);
|
||||
if (!session_proxy)
|
||||
report_error_and_die ("Failed getting session proxy", error);
|
||||
g_prefix_error(error, "Could not get session proxy: ");
|
||||
|
||||
free (proxy_path);
|
||||
|
||||
@ -95,16 +87,16 @@ get_session_proxy (GCancellable *cancellable)
|
||||
}
|
||||
|
||||
static Login1Seat *
|
||||
get_seat_proxy (GCancellable *cancellable)
|
||||
get_seat_proxy (GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/seat/self",
|
||||
cancellable, &error);
|
||||
cancellable, error);
|
||||
if (!seat)
|
||||
report_error_and_die ("Could not get seat proxy", error);
|
||||
g_prefix_error(error, "Could not get seat proxy: ");
|
||||
|
||||
return seat;
|
||||
}
|
||||
@ -112,12 +104,12 @@ get_seat_proxy (GCancellable *cancellable)
|
||||
static void
|
||||
session_unpause (void)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
ClutterBackend *clutter_backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
clutter_backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
cogl_display = cogl_context_get_display (cogl_context);
|
||||
cogl_kms_display_queue_modes_reset (cogl_display);
|
||||
|
||||
@ -305,7 +297,7 @@ get_primary_gpu_path (const gchar *seat_name)
|
||||
|
||||
for (tmp = devices; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
GUdevDevice *pci_device;
|
||||
GUdevDevice *platform_device = NULL, *pci_device = NULL;
|
||||
GUdevDevice *dev = tmp->data;
|
||||
gint boot_vga;
|
||||
const gchar *device_seat;
|
||||
@ -332,20 +324,28 @@ get_primary_gpu_path (const gchar *seat_name)
|
||||
if (g_strcmp0 (seat_name, device_seat))
|
||||
continue;
|
||||
|
||||
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
|
||||
if (!pci_device)
|
||||
continue;
|
||||
|
||||
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
|
||||
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
|
||||
g_object_unref (pci_device);
|
||||
|
||||
if (boot_vga == 1)
|
||||
platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
|
||||
if (platform_device != NULL)
|
||||
{
|
||||
/* found the boot_vga device */
|
||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||
g_object_unref (platform_device);
|
||||
break;
|
||||
}
|
||||
|
||||
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
|
||||
if (pci_device != NULL)
|
||||
{
|
||||
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
|
||||
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
|
||||
if (boot_vga == 1)
|
||||
{
|
||||
/* found the boot_vga device */
|
||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_unref (pci_device);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
@ -357,69 +357,114 @@ out:
|
||||
return path;
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
get_kms_fd (Login1Session *session_proxy,
|
||||
const gchar *seat_id,
|
||||
int *fd_out)
|
||||
const gchar *seat_id,
|
||||
int *fd_out,
|
||||
GError **error)
|
||||
{
|
||||
int major, minor;
|
||||
int fd;
|
||||
gchar *path;
|
||||
GError *error = NULL;
|
||||
|
||||
path = get_primary_gpu_path (seat_id);
|
||||
g_autofree gchar *path = get_primary_gpu_path (seat_id);
|
||||
if (!path)
|
||||
g_error ("could not find drm kms device");
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"could not find drm kms device");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!get_device_info_from_path (path, &major, &minor))
|
||||
g_error ("Could not stat %s: %m", path);
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get device info for path %s: %m", path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
|
||||
report_error_and_die ("Could not open DRM device", error);
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, error))
|
||||
{
|
||||
g_prefix_error (error, "Could not open DRM device: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*fd_out = fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_seat_id (void)
|
||||
get_seat_id (GError **error)
|
||||
{
|
||||
char *session_id, *seat_id = NULL;
|
||||
char *session_id, *seat_id;
|
||||
int r;
|
||||
|
||||
if (sd_pid_get_session (0, &session_id) < 0)
|
||||
return NULL;
|
||||
r = sd_pid_get_session (0, &session_id);
|
||||
if (r < 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get session for PID: %s", g_strerror (-r));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* on error the seat_id will remain NULL */
|
||||
sd_session_get_seat (session_id, &seat_id);
|
||||
r = sd_session_get_seat (session_id, &seat_id);
|
||||
free (session_id);
|
||||
|
||||
if (r < 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get seat for session: %s", g_strerror (-r));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return seat_id;
|
||||
}
|
||||
|
||||
MetaLauncher *
|
||||
meta_launcher_new (void)
|
||||
meta_launcher_new (GError **error)
|
||||
{
|
||||
MetaLauncher *self = NULL;
|
||||
Login1Session *session_proxy;
|
||||
char *seat_id;
|
||||
GError *error = NULL;
|
||||
Login1Session *session_proxy = NULL;
|
||||
Login1Seat *seat_proxy = NULL;
|
||||
char *seat_id = NULL;
|
||||
gboolean have_control = FALSE;
|
||||
int kms_fd;
|
||||
|
||||
session_proxy = get_session_proxy (NULL);
|
||||
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
|
||||
report_error_and_die ("Could not take control", error);
|
||||
session_proxy = get_session_proxy (NULL, error);
|
||||
if (!session_proxy)
|
||||
goto fail;
|
||||
|
||||
seat_id = get_seat_id ();
|
||||
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, error))
|
||||
{
|
||||
g_prefix_error (error, "Could not take control: ");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
have_control = TRUE;
|
||||
|
||||
seat_id = get_seat_id (error);
|
||||
if (!seat_id)
|
||||
g_error ("Failed getting seat id");
|
||||
goto fail;
|
||||
|
||||
seat_proxy = get_seat_proxy (NULL, error);
|
||||
if (!seat_proxy)
|
||||
goto fail;
|
||||
|
||||
if (!get_kms_fd (session_proxy, seat_id, &kms_fd, error))
|
||||
goto fail;
|
||||
|
||||
get_kms_fd (session_proxy, seat_id, &kms_fd);
|
||||
free (seat_id);
|
||||
|
||||
self = g_slice_new0 (MetaLauncher);
|
||||
self->session_proxy = session_proxy;
|
||||
self->seat_proxy = get_seat_proxy (NULL);
|
||||
self->seat_proxy = seat_proxy;
|
||||
|
||||
self->session_active = TRUE;
|
||||
|
||||
@ -429,8 +474,16 @@ meta_launcher_new (void)
|
||||
self);
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
return self;
|
||||
|
||||
fail:
|
||||
if (have_control)
|
||||
login1_session_call_release_control_sync (session_proxy, NULL, NULL);
|
||||
g_clear_object (&session_proxy);
|
||||
g_clear_object (&seat_proxy);
|
||||
free (seat_id);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
typedef struct _MetaLauncher MetaLauncher;
|
||||
|
||||
MetaLauncher *meta_launcher_new (void);
|
||||
MetaLauncher *meta_launcher_new (GError **error);
|
||||
void meta_launcher_free (MetaLauncher *self);
|
||||
|
||||
gboolean meta_launcher_activate_session (MetaLauncher *self,
|
||||
|
@ -42,6 +42,8 @@
|
||||
|
||||
#include <gudev/gudev.h>
|
||||
|
||||
#define ALL_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)
|
||||
|
||||
typedef struct {
|
||||
drmModeConnector *connector;
|
||||
|
||||
@ -66,6 +68,9 @@ typedef struct {
|
||||
uint32_t underscan_prop_id;
|
||||
uint32_t underscan_hborder_prop_id;
|
||||
uint32_t underscan_vborder_prop_id;
|
||||
uint32_t primary_plane_id;
|
||||
uint32_t rotation_prop_id;
|
||||
uint32_t rotation_map[ALL_TRANSFORMS];
|
||||
} MetaCRTCKms;
|
||||
|
||||
struct _MetaMonitorManagerKms
|
||||
@ -429,6 +434,137 @@ get_output_scale (MetaMonitorManager *manager,
|
||||
return compute_scale (output);
|
||||
}
|
||||
|
||||
static int
|
||||
find_property_index (MetaMonitorManager *manager,
|
||||
drmModeObjectPropertiesPtr props,
|
||||
const gchar *prop_name,
|
||||
drmModePropertyPtr *found)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < props->count_props; i++)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
|
||||
prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
if (strcmp (prop->name, prop_name) == 0)
|
||||
{
|
||||
*found = prop;
|
||||
return i;
|
||||
}
|
||||
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_transforms (MetaMonitorManager *manager,
|
||||
drmModePropertyPtr prop,
|
||||
MetaCRTC *crtc)
|
||||
{
|
||||
MetaCRTCKms *crtc_kms = crtc->driver_private;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < prop->count_enums; i++)
|
||||
{
|
||||
int cur = -1;
|
||||
|
||||
if (strcmp (prop->enums[i].name, "rotate-0") == 0)
|
||||
cur = META_MONITOR_TRANSFORM_NORMAL;
|
||||
else if (strcmp (prop->enums[i].name, "rotate-90") == 0)
|
||||
cur = META_MONITOR_TRANSFORM_90;
|
||||
else if (strcmp (prop->enums[i].name, "rotate-180") == 0)
|
||||
cur = META_MONITOR_TRANSFORM_180;
|
||||
else if (strcmp (prop->enums[i].name, "rotate-270") == 0)
|
||||
cur = META_MONITOR_TRANSFORM_270;
|
||||
|
||||
if (cur != -1)
|
||||
{
|
||||
crtc->all_transforms |= 1 << cur;
|
||||
crtc_kms->rotation_map[cur] = 1 << prop->enums[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_primary_plane (MetaMonitorManager *manager,
|
||||
drmModeObjectPropertiesPtr props)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
int idx;
|
||||
|
||||
idx = find_property_index (manager, props, "type", &prop);
|
||||
if (idx < 0)
|
||||
return FALSE;
|
||||
|
||||
drmModeFreeProperty (prop);
|
||||
return props->prop_values[idx] == DRM_PLANE_TYPE_PRIMARY;
|
||||
}
|
||||
|
||||
static void
|
||||
init_crtc_rotations (MetaMonitorManager *manager,
|
||||
MetaCRTC *crtc,
|
||||
unsigned int idx)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
drmModeObjectPropertiesPtr props;
|
||||
drmModePlaneRes *planes;
|
||||
drmModePlane *drm_plane;
|
||||
MetaCRTCKms *crtc_kms;
|
||||
unsigned int i;
|
||||
|
||||
crtc_kms = crtc->driver_private;
|
||||
|
||||
planes = drmModeGetPlaneResources(manager_kms->fd);
|
||||
if (planes == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < planes->count_planes; i++)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
|
||||
drm_plane = drmModeGetPlane (manager_kms->fd, planes->planes[i]);
|
||||
|
||||
if (!drm_plane)
|
||||
continue;
|
||||
|
||||
if ((drm_plane->possible_crtcs & (1 << idx)))
|
||||
{
|
||||
props = drmModeObjectGetProperties (manager_kms->fd,
|
||||
drm_plane->plane_id,
|
||||
DRM_MODE_OBJECT_PLANE);
|
||||
|
||||
if (props && is_primary_plane (manager, props))
|
||||
{
|
||||
int rotation_idx;
|
||||
|
||||
crtc_kms->primary_plane_id = drm_plane->plane_id;
|
||||
rotation_idx = find_property_index (manager, props, "rotation", &prop);
|
||||
|
||||
if (rotation_idx >= 0)
|
||||
{
|
||||
crtc_kms->rotation_prop_id = props->props[rotation_idx];
|
||||
parse_transforms (manager, prop, crtc);
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
}
|
||||
|
||||
if (props)
|
||||
drmModeFreeObjectProperties (props);
|
||||
}
|
||||
|
||||
drmModeFreePlane (drm_plane);
|
||||
}
|
||||
|
||||
drmModeFreePlaneResources (planes);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -496,8 +632,18 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
|
||||
meta_mode->width = mode->hdisplay;
|
||||
meta_mode->height = mode->vdisplay;
|
||||
meta_mode->refresh_rate = (1000 * mode->clock /
|
||||
((float)mode->htotal * mode->vtotal));
|
||||
|
||||
/* Calculate refresh rate in milliHz first for extra precision. */
|
||||
meta_mode->refresh_rate = (mode->clock * 1000000LL) / mode->htotal;
|
||||
meta_mode->refresh_rate += (mode->vtotal / 2);
|
||||
meta_mode->refresh_rate /= mode->vtotal;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
meta_mode->refresh_rate *= 2;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
meta_mode->refresh_rate /= 2;
|
||||
if (mode->vscan > 1)
|
||||
meta_mode->refresh_rate /= mode->vscan;
|
||||
meta_mode->refresh_rate /= 1000.0;
|
||||
|
||||
meta_mode->driver_private = g_slice_dup (drmModeModeInfo, mode);
|
||||
meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
|
||||
@ -546,6 +692,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
|
||||
meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
|
||||
find_crtc_properties (manager_kms, meta_crtc);
|
||||
init_crtc_rotations (manager, meta_crtc, i);
|
||||
|
||||
drmModeFreeCrtc (crtc);
|
||||
}
|
||||
@ -928,6 +1075,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaCRTCInfo *crtc_info = crtcs[i];
|
||||
MetaCRTC *crtc = crtc_info->crtc;
|
||||
MetaCRTCKms *crtc_kms = crtc->driver_private;
|
||||
CoglKmsCrtc *cogl_crtc;
|
||||
|
||||
crtc->is_dirty = TRUE;
|
||||
@ -1000,6 +1148,13 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
crtc->current_mode = mode;
|
||||
crtc->transform = crtc_info->transform;
|
||||
}
|
||||
|
||||
if (crtc->all_transforms & (1 << crtc->transform))
|
||||
drmModeObjectSetProperty (manager_kms->fd,
|
||||
crtc_kms->primary_plane_id,
|
||||
DRM_MODE_OBJECT_PLANE,
|
||||
crtc_kms->rotation_prop_id,
|
||||
crtc_kms->rotation_map[crtc->transform]);
|
||||
}
|
||||
|
||||
/* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
|
||||
@ -1152,6 +1307,8 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
|
||||
manager_kms->fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||
|
||||
drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
|
||||
const char *subsystems[2] = { "drm", NULL };
|
||||
manager_kms->udev = g_udev_client_new (subsystems);
|
||||
g_signal_connect (manager_kms->udev, "uevent",
|
||||
|
@ -82,6 +82,7 @@ struct _MetaBackendX11Private
|
||||
gchar *keymap_layouts;
|
||||
gchar *keymap_variants;
|
||||
gchar *keymap_options;
|
||||
int locked_group;
|
||||
};
|
||||
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||
|
||||
@ -297,15 +298,23 @@ handle_host_xevent (MetaBackend *backend,
|
||||
|
||||
if (event->type == priv->xkb_event_base)
|
||||
{
|
||||
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
|
||||
XkbEvent *xkb_ev = (XkbEvent *) event;
|
||||
|
||||
if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
|
||||
if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
|
||||
{
|
||||
switch (xkb_ev->xkb_type)
|
||||
switch (xkb_ev->any.xkb_type)
|
||||
{
|
||||
case XkbNewKeyboardNotify:
|
||||
case XkbMapNotify:
|
||||
keymap_changed (backend);
|
||||
break;
|
||||
case XkbStateNotify:
|
||||
if (xkb_ev->state.changed & XkbGroupLockMask)
|
||||
{
|
||||
if (priv->locked_group != xkb_ev->state.locked_group)
|
||||
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -441,6 +450,7 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
int major, minor;
|
||||
gboolean has_xi = FALSE;
|
||||
|
||||
priv->xdisplay = clutter_x11_get_default_display ();
|
||||
|
||||
@ -450,27 +460,23 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
!XSyncInitialize (priv->xdisplay, &major, &minor))
|
||||
meta_fatal ("Could not initialize XSync");
|
||||
|
||||
{
|
||||
int major = 2, minor = 3;
|
||||
gboolean has_xi = FALSE;
|
||||
if (XQueryExtension (priv->xdisplay,
|
||||
"XInputExtension",
|
||||
&priv->xinput_opcode,
|
||||
&priv->xinput_error_base,
|
||||
&priv->xinput_event_base))
|
||||
{
|
||||
major = 2; minor = 3;
|
||||
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
|
||||
{
|
||||
int version = (major * 10) + minor;
|
||||
if (version >= 22)
|
||||
has_xi = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (XQueryExtension (priv->xdisplay,
|
||||
"XInputExtension",
|
||||
&priv->xinput_opcode,
|
||||
&priv->xinput_error_base,
|
||||
&priv->xinput_event_base))
|
||||
{
|
||||
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
|
||||
{
|
||||
int version = (major * 10) + minor;
|
||||
if (version >= 22)
|
||||
has_xi = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_xi)
|
||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||
}
|
||||
if (!has_xi)
|
||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||
|
||||
/* We only take the passive touch grab if we are a X11 compositor */
|
||||
if (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
|
||||
@ -763,6 +769,9 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
|
||||
priv->xcb,
|
||||
xkb_x11_get_core_keyboard_device_id (priv->xcb),
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (priv->keymap == NULL)
|
||||
priv->keymap = xkb_keymap_new_from_names (context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
xkb_context_unref (context);
|
||||
}
|
||||
|
||||
@ -776,6 +785,7 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend,
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
priv->locked_group = idx;
|
||||
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
|
||||
}
|
||||
|
||||
@ -795,8 +805,6 @@ meta_backend_x11_update_screen_size (MetaBackend *backend,
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window xwin = meta_backend_x11_get_xwindow (x11);
|
||||
XResizeWindow (priv->xdisplay, xwin, width, height);
|
||||
}
|
||||
|
@ -107,20 +107,6 @@ set_alarm_enabled (Display *dpy,
|
||||
XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr);
|
||||
}
|
||||
|
||||
static void
|
||||
check_x11_watch (gpointer data,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaIdleMonitorWatchXSync *watch_xsync = data;
|
||||
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync;
|
||||
XSyncAlarm alarm = (XSyncAlarm) user_data;
|
||||
|
||||
if (watch_xsync->xalarm != alarm)
|
||||
return;
|
||||
|
||||
_meta_idle_monitor_watch_fire (watch);
|
||||
}
|
||||
|
||||
static char *
|
||||
counter_name_for_device (int device_id)
|
||||
{
|
||||
@ -327,13 +313,38 @@ meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync)
|
||||
monitor_xsync->alarms = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
check_x11_watches (MetaIdleMonitor *monitor,
|
||||
XSyncAlarm alarm)
|
||||
{
|
||||
GList *node, *watch_ids;
|
||||
|
||||
/* we get the keys and do explicit look ups in case
|
||||
* an early iteration of the loop ends up leading
|
||||
* to watches from later iterations getting invalidated
|
||||
*/
|
||||
watch_ids = g_hash_table_get_keys (monitor->watches);
|
||||
|
||||
for (node = watch_ids; node != NULL; node = node->next)
|
||||
{
|
||||
guint watch_id = GPOINTER_TO_UINT (node->data);
|
||||
MetaIdleMonitorWatchXSync *watch;
|
||||
|
||||
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
|
||||
|
||||
if (watch && watch->xalarm == alarm)
|
||||
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
|
||||
}
|
||||
|
||||
g_list_free (watch_ids);
|
||||
}
|
||||
|
||||
void
|
||||
meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor,
|
||||
XSyncAlarmNotifyEvent *alarm_event)
|
||||
{
|
||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
|
||||
XSyncAlarm alarm;
|
||||
GList *watches;
|
||||
gboolean has_alarm;
|
||||
|
||||
if (alarm_event->state != XSyncAlarmActive)
|
||||
@ -358,10 +369,5 @@ meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor,
|
||||
}
|
||||
|
||||
if (has_alarm)
|
||||
{
|
||||
watches = g_hash_table_get_values (monitor->watches);
|
||||
|
||||
g_list_foreach (watches, check_x11_watch, (gpointer) alarm);
|
||||
g_list_free (watches);
|
||||
}
|
||||
check_x11_watches (monitor, alarm);
|
||||
}
|
||||
|
@ -199,9 +199,9 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_scroll_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode)
|
||||
meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean edge_scroll_enabled)
|
||||
{
|
||||
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
|
||||
guchar *available;
|
||||
@ -211,26 +211,21 @@ meta_input_settings_x11_set_scroll_method (MetaInputSettings *setting
|
||||
if (!available)
|
||||
return;
|
||||
|
||||
switch (mode)
|
||||
if (available[0])
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
else if (available[1] && edge_scroll_enabled)
|
||||
{
|
||||
values[1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disabled */
|
||||
}
|
||||
|
||||
if ((values[0] && !available[0]) || (values[1] && !available[1]))
|
||||
g_warning ("Device '%s' does not support scroll mode %d\n",
|
||||
clutter_input_device_get_device_name (device), mode);
|
||||
else
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
XA_INTEGER, 8, &values, 3);
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
XA_INTEGER, 8, &values, 3);
|
||||
|
||||
meta_XFree (available);
|
||||
}
|
||||
@ -321,7 +316,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
||||
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_edge_scroll = meta_input_settings_x11_set_edge_scroll;
|
||||
input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button;
|
||||
input_settings_class->set_click_method = meta_input_settings_x11_set_click_method;
|
||||
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;
|
||||
|
@ -419,12 +419,6 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "XFree86_DDC_EDID1_RAWDATA", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (len > 0 && len % 128 == 0)
|
||||
@ -637,6 +631,70 @@ output_get_connector_type (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static void
|
||||
output_get_modes (MetaMonitorManager *manager,
|
||||
MetaOutput *meta_output,
|
||||
XRROutputInfo *output)
|
||||
{
|
||||
guint j, k;
|
||||
guint n_actual_modes;
|
||||
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, output->nmode);
|
||||
|
||||
n_actual_modes = 0;
|
||||
for (j = 0; j < (guint)output->nmode; j++)
|
||||
{
|
||||
for (k = 0; k < manager->n_modes; k++)
|
||||
{
|
||||
if (output->modes[j] == (XID)manager->modes[k].mode_id)
|
||||
{
|
||||
meta_output->modes[n_actual_modes] = &manager->modes[k];
|
||||
n_actual_modes += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
meta_output->n_modes = n_actual_modes;
|
||||
if (n_actual_modes > 0)
|
||||
meta_output->preferred_mode = meta_output->modes[0];
|
||||
}
|
||||
|
||||
static void
|
||||
output_get_crtcs (MetaMonitorManager *manager,
|
||||
MetaOutput *meta_output,
|
||||
XRROutputInfo *output)
|
||||
{
|
||||
guint j, k;
|
||||
guint n_actual_crtcs;
|
||||
|
||||
meta_output->possible_crtcs = g_new0 (MetaCRTC *, output->ncrtc);
|
||||
|
||||
n_actual_crtcs = 0;
|
||||
for (j = 0; j < (unsigned)output->ncrtc; j++)
|
||||
{
|
||||
for (k = 0; k < manager->n_crtcs; k++)
|
||||
{
|
||||
if ((XID)manager->crtcs[k].crtc_id == output->crtcs[j])
|
||||
{
|
||||
meta_output->possible_crtcs[n_actual_crtcs] = &manager->crtcs[k];
|
||||
n_actual_crtcs += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
meta_output->n_possible_crtcs = n_actual_crtcs;
|
||||
|
||||
meta_output->crtc = NULL;
|
||||
for (j = 0; j < manager->n_crtcs; j++)
|
||||
{
|
||||
if ((XID)manager->crtcs[j].crtc_id == output->crtc)
|
||||
{
|
||||
meta_output->crtc = &manager->crtcs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
get_xmode_name (XRRModeInfo *xmode)
|
||||
{
|
||||
@ -773,6 +831,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
MetaOutput *meta_output;
|
||||
|
||||
output = XRRGetOutputInfo (manager_xrandr->xdisplay, resources, resources->outputs[i]);
|
||||
if (!output)
|
||||
continue;
|
||||
|
||||
meta_output = &manager->outputs[n_actual_outputs];
|
||||
|
||||
@ -796,44 +856,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
|
||||
|
||||
output_get_tile_info (manager_xrandr, meta_output);
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
for (j = 0; j < meta_output->n_modes; j++)
|
||||
{
|
||||
for (k = 0; k < manager->n_modes; k++)
|
||||
{
|
||||
if (output->modes[j] == (XID)manager->modes[k].mode_id)
|
||||
{
|
||||
meta_output->modes[j] = &manager->modes[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
meta_output->preferred_mode = meta_output->modes[0];
|
||||
|
||||
meta_output->n_possible_crtcs = output->ncrtc;
|
||||
meta_output->possible_crtcs = g_new0 (MetaCRTC *, meta_output->n_possible_crtcs);
|
||||
for (j = 0; j < (unsigned)output->ncrtc; j++)
|
||||
{
|
||||
for (k = 0; k < manager->n_crtcs; k++)
|
||||
{
|
||||
if ((XID)manager->crtcs[k].crtc_id == output->crtcs[j])
|
||||
{
|
||||
meta_output->possible_crtcs[j] = &manager->crtcs[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meta_output->crtc = NULL;
|
||||
for (j = 0; j < manager->n_crtcs; j++)
|
||||
{
|
||||
if ((XID)manager->crtcs[j].crtc_id == output->crtc)
|
||||
{
|
||||
meta_output->crtc = &manager->crtcs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
output_get_modes (manager, meta_output, output);
|
||||
output_get_crtcs (manager, meta_output, output);
|
||||
|
||||
meta_output->n_possible_clones = output->nclone;
|
||||
meta_output->possible_clones = g_new0 (MetaOutput *, meta_output->n_possible_clones);
|
||||
@ -857,7 +881,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
else
|
||||
meta_output->backlight = -1;
|
||||
|
||||
n_actual_outputs++;
|
||||
if (meta_output->n_modes == 0 || meta_output->n_possible_crtcs == 0)
|
||||
meta_monitor_manager_clear_output (meta_output);
|
||||
else
|
||||
n_actual_outputs++;
|
||||
}
|
||||
|
||||
XRRFreeOutputInfo (output);
|
||||
@ -1133,17 +1160,16 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
if (crtc_info->mode != NULL)
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
g_autofree XID *outputs = NULL;
|
||||
unsigned int j, n_outputs;
|
||||
int width, height;
|
||||
g_autofree XID *output_ids = NULL;
|
||||
unsigned int j, n_output_ids;
|
||||
Status ok;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
|
||||
n_outputs = crtc_info->outputs->len;
|
||||
outputs = g_new (XID, n_outputs);
|
||||
n_output_ids = crtc_info->outputs->len;
|
||||
output_ids = g_new (XID, n_output_ids);
|
||||
|
||||
for (j = 0; j < n_outputs; j++)
|
||||
for (j = 0; j < n_output_ids; j++)
|
||||
{
|
||||
MetaOutput *output;
|
||||
|
||||
@ -1152,7 +1178,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
|
||||
outputs[j] = output->winsys_id;
|
||||
output_ids[j] = output->winsys_id;
|
||||
}
|
||||
|
||||
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
@ -1162,7 +1188,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
crtc_info->x, crtc_info->y,
|
||||
(XID)mode->mode_id,
|
||||
meta_monitor_transform_to_xrandr (crtc_info->transform),
|
||||
outputs, n_outputs);
|
||||
output_ids, n_output_ids);
|
||||
|
||||
if (ok != Success)
|
||||
{
|
||||
|
@ -33,8 +33,6 @@ struct _MetaCursorRendererX11Nested
|
||||
MetaCursorRenderer parent;
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_x11_nested_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorRendererX11Nested, meta_cursor_renderer_x11_nested,
|
||||
META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
|
@ -779,7 +779,7 @@ meta_compositor_size_change_window (MetaCompositor *compositor,
|
||||
MetaRectangle *old_buffer_rect)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_size_change (window_actor, META_SIZE_CHANGE_MAXIMIZE, old_frame_rect, old_buffer_rect);
|
||||
meta_window_actor_size_change (window_actor, which_change, old_frame_rect, old_buffer_rect);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -832,21 +832,23 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* Do not add shadows to non-opaque windows; eventually we should generate
|
||||
* a shadow from the input shape for such windows.
|
||||
* Do not add shadows to non-opaque (ARGB32) windows, as we can't easily
|
||||
* generate shadows for them.
|
||||
*/
|
||||
if (is_non_opaque (self))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Add shadows to override redirect windows on X11 unless the toolkit
|
||||
* indicates that it is handling shadows itself (e.g., Gtk menus).
|
||||
* If a window specifies that it has custom frame extents, that likely
|
||||
* means that it is drawing a shadow itself. Don't draw our own.
|
||||
*/
|
||||
if (priv->window->override_redirect &&
|
||||
!priv->window->has_custom_frame_extents)
|
||||
return TRUE;
|
||||
if (priv->window->has_custom_frame_extents)
|
||||
return FALSE;
|
||||
|
||||
return FALSE;
|
||||
/*
|
||||
* Generate shadows for all other windows.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -255,6 +255,31 @@ get_actor_private (MetaWindowActor *actor)
|
||||
return priv;
|
||||
}
|
||||
|
||||
static ClutterTimeline *
|
||||
actor_animate (ClutterActor *actor,
|
||||
ClutterAnimationMode mode,
|
||||
guint duration,
|
||||
const gchar *first_property,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
ClutterTransition *transition;
|
||||
|
||||
clutter_actor_save_easing_state (actor);
|
||||
clutter_actor_set_easing_mode (actor, mode);
|
||||
clutter_actor_set_easing_duration (actor, duration);
|
||||
|
||||
va_start (args, first_property);
|
||||
g_object_set_valist (G_OBJECT (actor), first_property, args);
|
||||
va_end (args);
|
||||
|
||||
transition = clutter_actor_get_transition (actor, first_property);
|
||||
|
||||
clutter_actor_restore_easing_state (actor);
|
||||
|
||||
return CLUTTER_TIMELINE (transition);
|
||||
}
|
||||
|
||||
static void
|
||||
on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
|
||||
{
|
||||
@ -271,7 +296,10 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
|
||||
|
||||
if (apriv->orig_parent)
|
||||
{
|
||||
clutter_actor_reparent (a, apriv->orig_parent);
|
||||
g_object_ref (a);
|
||||
clutter_actor_remove_child (clutter_actor_get_parent (a), a);
|
||||
clutter_actor_add_child (apriv->orig_parent, a);
|
||||
g_object_unref (a);
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
|
||||
@ -360,11 +388,10 @@ switch_workspace (MetaPlugin *plugin,
|
||||
MetaScreen *screen;
|
||||
MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
|
||||
GList *l;
|
||||
ClutterActor *workspace0 = clutter_group_new ();
|
||||
ClutterActor *workspace1 = clutter_group_new ();
|
||||
ClutterActor *workspace0 = clutter_actor_new ();
|
||||
ClutterActor *workspace1 = clutter_actor_new ();
|
||||
ClutterActor *stage;
|
||||
int screen_width, screen_height;
|
||||
ClutterAnimation *animation;
|
||||
|
||||
screen = meta_plugin_get_screen (plugin);
|
||||
stage = meta_get_stage_for_screen (screen);
|
||||
@ -373,17 +400,15 @@ switch_workspace (MetaPlugin *plugin,
|
||||
&screen_width,
|
||||
&screen_height);
|
||||
|
||||
clutter_actor_set_anchor_point (workspace1,
|
||||
screen_width,
|
||||
screen_height);
|
||||
clutter_actor_set_pivot_point (workspace1, 1.0, 1.0);
|
||||
clutter_actor_set_position (workspace1,
|
||||
screen_width,
|
||||
screen_height);
|
||||
|
||||
clutter_actor_set_scale (workspace1, 0.0, 0.0);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0);
|
||||
clutter_actor_add_child (stage, workspace1);
|
||||
clutter_actor_add_child (stage, workspace0);
|
||||
|
||||
if (from == to)
|
||||
{
|
||||
@ -406,12 +431,15 @@ switch_workspace (MetaPlugin *plugin,
|
||||
|
||||
if (win_workspace == to || win_workspace == from)
|
||||
{
|
||||
ClutterActor *parent = win_workspace == to ? workspace1 : workspace0;
|
||||
apriv->orig_parent = clutter_actor_get_parent (actor);
|
||||
|
||||
clutter_actor_reparent (actor,
|
||||
win_workspace == to ? workspace1 : workspace0);
|
||||
clutter_actor_show_all (actor);
|
||||
clutter_actor_raise_top (actor);
|
||||
g_object_ref (actor);
|
||||
clutter_actor_remove_child (clutter_actor_get_parent (actor), actor);
|
||||
clutter_actor_add_child (parent, actor);
|
||||
clutter_actor_show (actor);
|
||||
clutter_actor_set_child_below_sibling (parent, actor, NULL);
|
||||
g_object_unref (actor);
|
||||
}
|
||||
else if (win_workspace < 0)
|
||||
{
|
||||
@ -431,23 +459,21 @@ switch_workspace (MetaPlugin *plugin,
|
||||
priv->desktop1 = workspace0;
|
||||
priv->desktop2 = workspace1;
|
||||
|
||||
animation = clutter_actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
"scale-x", 1.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
priv->tml_switch_workspace1 = clutter_animation_get_timeline (animation);
|
||||
priv->tml_switch_workspace1 = actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
"scale-x", 1.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
g_signal_connect (priv->tml_switch_workspace1,
|
||||
"completed",
|
||||
G_CALLBACK (on_switch_workspace_effect_complete),
|
||||
plugin);
|
||||
|
||||
animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 0.0,
|
||||
NULL);
|
||||
priv->tml_switch_workspace2 = clutter_animation_get_timeline (animation);
|
||||
priv->tml_switch_workspace2 = actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 0.0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -504,19 +530,17 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
|
||||
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (window_actor);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_IN_SINE,
|
||||
MINIMIZE_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 0.0,
|
||||
"x", (double)icon_geometry.x,
|
||||
"y", (double)icon_geometry.y,
|
||||
NULL);
|
||||
apriv->tml_minimize = clutter_animation_get_timeline (animation);
|
||||
apriv->tml_minimize = actor_animate (actor,
|
||||
CLUTTER_EASE_IN_SINE,
|
||||
MINIMIZE_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 0.0,
|
||||
"x", (double)icon_geometry.x,
|
||||
"y", (double)icon_geometry.y,
|
||||
NULL);
|
||||
data->plugin = plugin;
|
||||
data->actor = actor;
|
||||
g_signal_connect (apriv->tml_minimize, "completed",
|
||||
@ -561,7 +585,6 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor)
|
||||
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (window_actor);
|
||||
|
||||
@ -570,14 +593,13 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor)
|
||||
clutter_actor_set_scale (actor, 0.5, 0.5);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_OUT_QUAD,
|
||||
MAP_TIMEOUT,
|
||||
"opacity", 255,
|
||||
"scale-x", 1.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
apriv->tml_map = clutter_animation_get_timeline (animation);
|
||||
apriv->tml_map = actor_animate (actor,
|
||||
CLUTTER_EASE_OUT_QUAD,
|
||||
MAP_TIMEOUT,
|
||||
"opacity", 255,
|
||||
"scale-x", 1.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
data->actor = actor;
|
||||
data->plugin = plugin;
|
||||
g_signal_connect (apriv->tml_map, "completed",
|
||||
@ -618,18 +640,16 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
|
||||
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (window_actor);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_OUT_QUAD,
|
||||
DESTROY_TIMEOUT,
|
||||
"opacity", 0,
|
||||
"scale-x", 0.8,
|
||||
"scale-y", 0.8,
|
||||
NULL);
|
||||
apriv->tml_destroy = clutter_animation_get_timeline (animation);
|
||||
apriv->tml_destroy = actor_animate (actor,
|
||||
CLUTTER_EASE_OUT_QUAD,
|
||||
DESTROY_TIMEOUT,
|
||||
"opacity", 0,
|
||||
"scale-x", 0.8,
|
||||
"scale-y", 0.8,
|
||||
NULL);
|
||||
data->plugin = plugin;
|
||||
data->actor = actor;
|
||||
g_signal_connect (apriv->tml_destroy, "completed",
|
||||
@ -702,7 +722,9 @@ show_tile_preview (MetaPlugin *plugin,
|
||||
clutter_actor_show (preview->actor);
|
||||
|
||||
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
|
||||
clutter_actor_lower (preview->actor, window_actor);
|
||||
clutter_actor_set_child_below_sibling (clutter_actor_get_parent (preview->actor),
|
||||
preview->actor,
|
||||
window_actor);
|
||||
|
||||
preview->tile_rect = *tile_rect;
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ meta_display_open (void)
|
||||
guint32 timestamp;
|
||||
|
||||
/* A list of all atom names, so that we can intern them in one go. */
|
||||
char *atom_names[] = {
|
||||
const char *atom_names[] = {
|
||||
#define item(x) #x,
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
@ -605,14 +605,13 @@ meta_display_open (void)
|
||||
meta_prefs_add_listener (prefs_changed_callback, display);
|
||||
|
||||
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
|
||||
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
XInternAtoms (display->xdisplay, (char **)atom_names, G_N_ELEMENTS (atom_names),
|
||||
False, atoms);
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
i = 0;
|
||||
#define item(x) display->atom_##x = atoms[i++];
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
}
|
||||
|
||||
display->prop_hooks = NULL;
|
||||
meta_display_init_window_prop_hooks (display);
|
||||
@ -1964,9 +1963,12 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u at time %u\n", grab_op, timestamp);
|
||||
|
||||
if (display->event_route == META_EVENT_ROUTE_NORMAL)
|
||||
if (display->event_route == META_EVENT_ROUTE_NORMAL ||
|
||||
display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB)
|
||||
return;
|
||||
|
||||
g_assert (grab_window != NULL);
|
||||
|
||||
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
|
||||
display->screen, grab_window, grab_op);
|
||||
|
||||
|
@ -182,10 +182,25 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
/* Set the pointer emulating sequence on touch begin, if eligible */
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN &&
|
||||
!display->pointer_emulating_sequence &&
|
||||
sequence_is_pointer_emulated (display, event))
|
||||
display->pointer_emulating_sequence = sequence;
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN)
|
||||
{
|
||||
if (sequence_is_pointer_emulated (display, event))
|
||||
{
|
||||
/* This is the new pointer emulating sequence */
|
||||
display->pointer_emulating_sequence = sequence;
|
||||
}
|
||||
else if (display->pointer_emulating_sequence == sequence)
|
||||
{
|
||||
/* This sequence was "pointer emulating" in a prior incarnation,
|
||||
* but now it isn't. We unset the pointer emulating sequence at
|
||||
* this point so the current sequence is not mistaken as pointer
|
||||
* emulating, while we've ensured that it's been deemed
|
||||
* "pointer emulating" throughout all of the event processing
|
||||
* of the previous incarnation.
|
||||
*/
|
||||
display->pointer_emulating_sequence = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *compositor = NULL;
|
||||
@ -206,8 +221,8 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
|
||||
{
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
meta_cursor_tracker_update_position (tracker, event->motion.x, event->motion.y);
|
||||
meta_cursor_tracker_update_position (meta_cursor_tracker_get_for_screen (NULL),
|
||||
event->motion.x, event->motion.y);
|
||||
display->monitor_cache_invalidated = TRUE;
|
||||
}
|
||||
|
||||
@ -335,11 +350,6 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Unset the pointer emulating sequence after its end event is processed */
|
||||
if (event->type == CLUTTER_TOUCH_END &&
|
||||
display->pointer_emulating_sequence == sequence)
|
||||
display->pointer_emulating_sequence = NULL;
|
||||
|
||||
display->current_time = CurrentTime;
|
||||
return bypass_clutter;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ reload_modmap (MetaKeyBindingManager *keys)
|
||||
|
||||
/* Modifiers to find. */
|
||||
struct {
|
||||
char *name;
|
||||
const char *name;
|
||||
xkb_mod_mask_t *mask_p;
|
||||
} mods[] = {
|
||||
{ "ScrollLock", &scroll_lock_mask },
|
||||
|
104
src/core/main.c
104
src/core/main.c
@ -80,6 +80,10 @@
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland.h"
|
||||
# endif
|
||||
|
||||
#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND)
|
||||
#include <systemd/sd-login.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -291,6 +295,95 @@ on_sigterm (gpointer user_data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
|
||||
static char *
|
||||
find_logind_session_type (void)
|
||||
{
|
||||
char **sessions;
|
||||
char *session_id;
|
||||
char *session_type;
|
||||
int ret, i;
|
||||
|
||||
ret = sd_pid_get_session (0, &session_id);
|
||||
|
||||
if (ret == 0 && session_id != NULL)
|
||||
{
|
||||
ret = sd_session_get_type (session_id, &session_type);
|
||||
free (session_id);
|
||||
|
||||
if (ret < 0)
|
||||
session_type = NULL;
|
||||
|
||||
goto out;
|
||||
}
|
||||
session_type = NULL;
|
||||
|
||||
ret = sd_uid_get_sessions (getuid (), TRUE, &sessions);
|
||||
|
||||
if (ret < 0 || sessions == NULL)
|
||||
goto out;
|
||||
|
||||
for (i = 0; sessions[i] != NULL; i++)
|
||||
{
|
||||
ret = sd_session_get_type (sessions[i], &session_type);
|
||||
|
||||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
if (g_strcmp0 (session_type, "x11") == 0||
|
||||
g_strcmp0 (session_type, "wayland") == 0)
|
||||
break;
|
||||
|
||||
g_clear_pointer (&session_type, (GDestroyNotify) free);
|
||||
}
|
||||
|
||||
for (i = 0; sessions[i] != NULL; i++)
|
||||
free (sessions[i]);
|
||||
free (sessions);
|
||||
|
||||
out:
|
||||
return session_type;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_for_wayland_session_type (void)
|
||||
{
|
||||
char *session_type = NULL;
|
||||
gboolean is_wayland = FALSE;
|
||||
|
||||
session_type = find_logind_session_type ();
|
||||
|
||||
if (session_type != NULL)
|
||||
{
|
||||
is_wayland = g_strcmp0 (session_type, "wayland") == 0;
|
||||
free (session_type);
|
||||
}
|
||||
|
||||
return is_wayland;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
init_backend (void)
|
||||
{
|
||||
gboolean session_type_is_wayland = FALSE;
|
||||
|
||||
#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
|
||||
session_type_is_wayland = check_for_wayland_session_type ();
|
||||
#endif
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (opt_display_server || session_type_is_wayland)
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
else
|
||||
#endif
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_set_is_wayland_compositor (opt_wayland || session_type_is_wayland);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_init: (skip)
|
||||
*
|
||||
@ -323,16 +416,7 @@ meta_init (void)
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
meta_set_debugging (TRUE);
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (opt_display_server)
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
else
|
||||
#endif
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_set_is_wayland_compositor (opt_wayland);
|
||||
#endif
|
||||
init_backend ();
|
||||
|
||||
if (g_get_home_dir ())
|
||||
if (chdir (g_get_home_dir ()) < 0)
|
||||
|
@ -44,7 +44,7 @@ print_version (const gchar *option_name,
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static gchar *plugin = "default";
|
||||
static const char *plugin = "default";
|
||||
|
||||
GOptionEntry mutter_options[] = {
|
||||
{
|
||||
|
121
src/core/prefs.c
121
src/core/prefs.c
@ -96,6 +96,10 @@ static gboolean bell_is_audible = TRUE;
|
||||
static gboolean gnome_accessibility = FALSE;
|
||||
static gboolean gnome_animations = TRUE;
|
||||
static char *cursor_theme = NULL;
|
||||
/* cursor_size will, when running as an X11 compositing window manager, be the
|
||||
* actual cursor size, multiplied with the global window scaling factor. On
|
||||
* Wayland, it will be the actual cursor size retrieved from gsettings.
|
||||
*/
|
||||
static int cursor_size = 24;
|
||||
static int draggable_border_width = 10;
|
||||
static int drag_threshold;
|
||||
@ -123,6 +127,9 @@ static gboolean update_binding (MetaKeyPref *binding,
|
||||
static gboolean update_key_binding (const char *key,
|
||||
gchar **strokes);
|
||||
|
||||
static void wayland_settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data);
|
||||
static void settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data);
|
||||
@ -134,9 +141,10 @@ static void shell_shows_app_menu_changed (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
|
||||
static void update_cursor_size (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
static void update_cursor_size_from_gtk (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
static void update_cursor_size (void);
|
||||
|
||||
static void queue_changed (MetaPreference pref);
|
||||
|
||||
@ -161,8 +169,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *key;
|
||||
char *schema;
|
||||
const char *key;
|
||||
const char *schema;
|
||||
MetaPreference pref;
|
||||
} MetaBasePreference;
|
||||
|
||||
@ -963,14 +971,18 @@ meta_prefs_init (void)
|
||||
G_CALLBACK (settings_changed), NULL);
|
||||
g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_THEME,
|
||||
G_CALLBACK (settings_changed), NULL);
|
||||
if (meta_is_wayland_compositor ())
|
||||
g_signal_connect (settings, "changed::cursor-size",
|
||||
G_CALLBACK (wayland_settings_changed), NULL);
|
||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
|
||||
|
||||
g_signal_connect (gtk_settings_get_default (),
|
||||
"notify::gtk-shell-shows-app-menu",
|
||||
G_CALLBACK (shell_shows_app_menu_changed), NULL);
|
||||
|
||||
g_signal_connect (gtk_settings_get_default (), "notify::gtk-cursor-theme-size",
|
||||
G_CALLBACK (update_cursor_size), NULL);
|
||||
if (!meta_is_wayland_compositor ())
|
||||
g_signal_connect (gtk_settings_get_default (), "notify::gtk-cursor-theme-size",
|
||||
G_CALLBACK (update_cursor_size_from_gtk), NULL);
|
||||
|
||||
settings = g_settings_new (SCHEMA_INPUT_SOURCES);
|
||||
g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
|
||||
@ -992,7 +1004,7 @@ meta_prefs_init (void)
|
||||
handle_preference_init_string_array ();
|
||||
handle_preference_init_int ();
|
||||
|
||||
update_cursor_size (gtk_settings_get_default (), NULL, NULL);
|
||||
update_cursor_size ();
|
||||
shell_shows_app_menu_changed (gtk_settings_get_default (), NULL, NULL);
|
||||
|
||||
init_bindings ();
|
||||
@ -1133,6 +1145,20 @@ meta_prefs_override_preference_schema (const char *key, const char *schema)
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static void
|
||||
wayland_settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data)
|
||||
{
|
||||
GVariant *value = g_settings_get_value (settings, key);
|
||||
const GVariantType *type = g_variant_get_type (value);
|
||||
|
||||
g_return_if_fail (g_variant_type_equal (type, G_VARIANT_TYPE_INT32));
|
||||
g_return_if_fail (g_str_equal (key, "cursor-size"));
|
||||
|
||||
update_cursor_size ();
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
@ -1216,9 +1242,29 @@ shell_shows_app_menu_changed (GtkSettings *settings,
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor_size (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
update_cursor_size (void)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* When running as a Wayland compositor, since we size of the cursor
|
||||
* depends on what output it is on, we cannot use the GTK+
|
||||
* "gtk-cursor-theme-size" setting because it has already been multiplied
|
||||
* by the primary monitor scale. So, instead get the non-premultiplied
|
||||
* cursor size value directly from gsettings instead.
|
||||
*/
|
||||
cursor_size =
|
||||
g_settings_get_int (SETTINGS (SCHEMA_INTERFACE), "cursor-size");
|
||||
}
|
||||
else
|
||||
{
|
||||
update_cursor_size_from_gtk (gtk_settings_get_default (), NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor_size_from_gtk (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
GdkScreen *screen = gdk_screen_get_default ();
|
||||
GValue value = G_VALUE_INIT;
|
||||
@ -1431,42 +1477,11 @@ button_function_from_string (const char *str)
|
||||
return META_BUTTON_FUNCTION_MAXIMIZE;
|
||||
else if (strcmp (str, "close") == 0)
|
||||
return META_BUTTON_FUNCTION_CLOSE;
|
||||
else if (strcmp (str, "shade") == 0)
|
||||
return META_BUTTON_FUNCTION_SHADE;
|
||||
else if (strcmp (str, "above") == 0)
|
||||
return META_BUTTON_FUNCTION_ABOVE;
|
||||
else if (strcmp (str, "stick") == 0)
|
||||
return META_BUTTON_FUNCTION_STICK;
|
||||
else
|
||||
/* don't know; give up */
|
||||
return META_BUTTON_FUNCTION_LAST;
|
||||
}
|
||||
|
||||
static MetaButtonFunction
|
||||
button_opposite_function (MetaButtonFunction ofwhat)
|
||||
{
|
||||
switch (ofwhat)
|
||||
{
|
||||
case META_BUTTON_FUNCTION_SHADE:
|
||||
return META_BUTTON_FUNCTION_UNSHADE;
|
||||
case META_BUTTON_FUNCTION_UNSHADE:
|
||||
return META_BUTTON_FUNCTION_SHADE;
|
||||
|
||||
case META_BUTTON_FUNCTION_ABOVE:
|
||||
return META_BUTTON_FUNCTION_UNABOVE;
|
||||
case META_BUTTON_FUNCTION_UNABOVE:
|
||||
return META_BUTTON_FUNCTION_ABOVE;
|
||||
|
||||
case META_BUTTON_FUNCTION_STICK:
|
||||
return META_BUTTON_FUNCTION_UNSTICK;
|
||||
case META_BUTTON_FUNCTION_UNSTICK:
|
||||
return META_BUTTON_FUNCTION_STICK;
|
||||
|
||||
default:
|
||||
return META_BUTTON_FUNCTION_LAST;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
button_layout_handler (GVariant *value,
|
||||
gpointer *result,
|
||||
@ -1510,12 +1525,6 @@ button_layout_handler (GVariant *value,
|
||||
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
|
||||
{
|
||||
new_layout.left_buttons_has_spacer[i-1] = TRUE;
|
||||
f = button_opposite_function (f);
|
||||
|
||||
if (f != META_BUTTON_FUNCTION_LAST)
|
||||
{
|
||||
new_layout.left_buttons_has_spacer[i-2] = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1524,11 +1533,6 @@ button_layout_handler (GVariant *value,
|
||||
new_layout.left_buttons[i] = f;
|
||||
used[f] = TRUE;
|
||||
++i;
|
||||
|
||||
f = button_opposite_function (f);
|
||||
|
||||
if (f != META_BUTTON_FUNCTION_LAST)
|
||||
new_layout.left_buttons[i++] = f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1572,11 +1576,6 @@ button_layout_handler (GVariant *value,
|
||||
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
|
||||
{
|
||||
new_layout.right_buttons_has_spacer[i-1] = TRUE;
|
||||
f = button_opposite_function (f);
|
||||
if (f != META_BUTTON_FUNCTION_LAST)
|
||||
{
|
||||
new_layout.right_buttons_has_spacer[i-2] = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1585,12 +1584,6 @@ button_layout_handler (GVariant *value,
|
||||
new_layout.right_buttons[i] = f;
|
||||
used[f] = TRUE;
|
||||
++i;
|
||||
|
||||
f = button_opposite_function (f);
|
||||
|
||||
if (f != META_BUTTON_FUNCTION_LAST)
|
||||
new_layout.right_buttons[i++] = f;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2100,7 +2100,7 @@ meta_screen_queue_workarea_recalc (MetaScreen *screen)
|
||||
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static char *
|
||||
static const char *
|
||||
meta_screen_corner_to_string (MetaScreenCorner corner)
|
||||
{
|
||||
switch (corner)
|
||||
|
@ -1055,7 +1055,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
x11_hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
||||
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
|
||||
meta_push_no_msg_prefix ();
|
||||
|
||||
for (tmp = g_list_last(stack->sorted); tmp != NULL; tmp = tmp->prev)
|
||||
@ -1088,11 +1088,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
if (w->hidden)
|
||||
{
|
||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
guint64 stack_id = top_level_window;
|
||||
|
||||
g_array_append_val (x11_hidden_stack_ids, stack_id);
|
||||
}
|
||||
g_array_append_val (x11_hidden_stack_ids, top_level_window);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define NUM_RANDOM_RUNS 10000
|
||||
|
||||
static void
|
||||
init_random_ness ()
|
||||
init_random_ness (void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
}
|
||||
@ -99,7 +99,7 @@ new_monitor_edge (int x, int y, int width, int height, int side_type)
|
||||
}
|
||||
|
||||
static void
|
||||
test_area ()
|
||||
test_area (void)
|
||||
{
|
||||
MetaRectangle temp;
|
||||
int i;
|
||||
@ -116,7 +116,7 @@ test_area ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_intersect ()
|
||||
test_intersect (void)
|
||||
{
|
||||
MetaRectangle a = {100, 200, 50, 40};
|
||||
MetaRectangle b = { 0, 50, 110, 152};
|
||||
@ -144,7 +144,7 @@ test_intersect ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_equal ()
|
||||
test_equal (void)
|
||||
{
|
||||
MetaRectangle a = {10, 12, 4, 18};
|
||||
MetaRectangle b = a;
|
||||
@ -163,7 +163,7 @@ test_equal ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_overlap_funcs ()
|
||||
test_overlap_funcs (void)
|
||||
{
|
||||
MetaRectangle temp1, temp2;
|
||||
int i;
|
||||
@ -186,7 +186,7 @@ test_overlap_funcs ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_basic_fitting ()
|
||||
test_basic_fitting (void)
|
||||
{
|
||||
MetaRectangle temp1, temp2, temp3;
|
||||
int i;
|
||||
@ -357,7 +357,7 @@ get_monitor_edges (int which_monitor_set, int which_strut_set)
|
||||
|
||||
#if 0
|
||||
static void
|
||||
test_merge_regions ()
|
||||
test_merge_regions (void)
|
||||
{
|
||||
/* logarithmically distributed random number of struts (range?)
|
||||
* logarithmically distributed random size of struts (up to screen size???)
|
||||
@ -579,7 +579,7 @@ verify_lists_are_equal (GList *code, GList *answer)
|
||||
}
|
||||
|
||||
static void
|
||||
test_regions_okay ()
|
||||
test_regions_okay (void)
|
||||
{
|
||||
GList* region;
|
||||
GList* tmp;
|
||||
@ -665,7 +665,7 @@ test_regions_okay ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_region_fitting ()
|
||||
test_region_fitting (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect;
|
||||
@ -709,7 +709,7 @@ test_region_fitting ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_clamping_to_region ()
|
||||
test_clamping_to_region (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect;
|
||||
@ -826,7 +826,7 @@ rect_overlaps_region (const GList *spanning_rects,
|
||||
gboolean time_to_print = FALSE;
|
||||
|
||||
static void
|
||||
test_clipping_to_region ()
|
||||
test_clipping_to_region (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect, temp;
|
||||
@ -888,7 +888,7 @@ test_clipping_to_region ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_shoving_into_region ()
|
||||
test_shoving_into_region (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect, temp;
|
||||
@ -1005,7 +1005,7 @@ verify_edge_lists_are_equal (GList *code, GList *answer)
|
||||
}
|
||||
|
||||
static void
|
||||
test_find_onscreen_edges ()
|
||||
test_find_onscreen_edges (void)
|
||||
{
|
||||
GList* edges;
|
||||
GList* tmp;
|
||||
@ -1138,7 +1138,7 @@ test_find_onscreen_edges ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_find_nonintersected_monitor_edges ()
|
||||
test_find_nonintersected_monitor_edges (void)
|
||||
{
|
||||
GList* edges;
|
||||
GList* tmp;
|
||||
@ -1227,7 +1227,7 @@ test_find_nonintersected_monitor_edges ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_gravity_resize ()
|
||||
test_gravity_resize (void)
|
||||
{
|
||||
MetaRectangle oldrect, rect, temp;
|
||||
|
||||
@ -1329,7 +1329,7 @@ test_gravity_resize ()
|
||||
|
||||
#define EPSILON 0.000000001
|
||||
static void
|
||||
test_find_closest_point_to_line ()
|
||||
test_find_closest_point_to_line (void)
|
||||
{
|
||||
double x1, y1, x2, y2, px, py, rx, ry;
|
||||
double answer_x, answer_y;
|
||||
@ -1381,7 +1381,7 @@ test_find_closest_point_to_line ()
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
main(void)
|
||||
{
|
||||
init_random_ness ();
|
||||
test_area ();
|
||||
|
@ -46,7 +46,7 @@
|
||||
static void
|
||||
meta_topic_real_valist (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
va_list args);
|
||||
va_list args) G_GNUC_PRINTF(2, 0);
|
||||
#endif
|
||||
|
||||
static gint verbose_topics = 0;
|
||||
|
@ -763,10 +763,22 @@ meta_window_update_desc (MetaWindow *window)
|
||||
{
|
||||
g_clear_pointer (&window->desc, g_free);
|
||||
|
||||
if (window->title)
|
||||
window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title);
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
if (window->title)
|
||||
window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title);
|
||||
else
|
||||
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
|
||||
}
|
||||
else
|
||||
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
|
||||
{
|
||||
guint64 small_stamp = window->stamp - G_GUINT64_CONSTANT(0x100000000);
|
||||
|
||||
if (window->title)
|
||||
window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT " (%.10s)", small_stamp, window->title);
|
||||
else
|
||||
window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT , small_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1567,8 +1579,10 @@ implement_showing (MetaWindow *window,
|
||||
* windows we might want to know where they are on the screen,
|
||||
* so we should place the window even if we're hiding it rather
|
||||
* than showing it.
|
||||
* Force placing windows only when they should be already mapped,
|
||||
* see #751887
|
||||
*/
|
||||
if (!window->placed)
|
||||
if (!window->placed && client_window_should_be_mapped (window))
|
||||
meta_window_force_placement (window);
|
||||
|
||||
meta_window_hide (window);
|
||||
@ -3183,12 +3197,23 @@ meta_window_make_fullscreen (MetaWindow *window)
|
||||
|
||||
if (!window->fullscreen)
|
||||
{
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
MetaRectangle old_frame_rect, old_buffer_rect;
|
||||
|
||||
meta_window_get_frame_rect (window, &old_frame_rect);
|
||||
meta_window_get_buffer_rect (window, &old_buffer_rect);
|
||||
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
meta_window_move_resize_internal (window,
|
||||
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
|
||||
(META_MOVE_RESIZE_MOVE_ACTION |
|
||||
META_MOVE_RESIZE_RESIZE_ACTION |
|
||||
META_MOVE_RESIZE_STATE_CHANGED |
|
||||
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
|
||||
NorthWestGravity,
|
||||
window->unconstrained_rect);
|
||||
|
||||
meta_compositor_size_change_window (window->display->compositor,
|
||||
window, META_SIZE_CHANGE_FULLSCREEN,
|
||||
&old_frame_rect, &old_buffer_rect);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3199,7 +3224,7 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
|
||||
if (window->fullscreen)
|
||||
{
|
||||
MetaRectangle target_rect;
|
||||
MetaRectangle old_frame_rect, old_buffer_rect, target_rect;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Unfullscreening %s\n", window->desc);
|
||||
@ -3208,6 +3233,8 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
target_rect = window->saved_rect;
|
||||
|
||||
meta_window_frame_size_changed (window);
|
||||
meta_window_get_frame_rect (window, &old_frame_rect);
|
||||
meta_window_get_buffer_rect (window, &old_buffer_rect);
|
||||
|
||||
/* Window's size hints may have changed while maximized, making
|
||||
* saved_rect invalid. #329152
|
||||
@ -3222,10 +3249,17 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
set_net_wm_state (window);
|
||||
|
||||
meta_window_move_resize_internal (window,
|
||||
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
|
||||
(META_MOVE_RESIZE_MOVE_ACTION |
|
||||
META_MOVE_RESIZE_RESIZE_ACTION |
|
||||
META_MOVE_RESIZE_STATE_CHANGED |
|
||||
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
|
||||
NorthWestGravity,
|
||||
target_rect);
|
||||
|
||||
meta_compositor_size_change_window (window->display->compositor,
|
||||
window, META_SIZE_CHANGE_UNFULLSCREEN,
|
||||
&old_frame_rect, &old_buffer_rect);
|
||||
|
||||
meta_window_update_layer (window);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]);
|
||||
@ -3502,10 +3536,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
|
||||
{
|
||||
const MetaMonitorInfo *old, *new;
|
||||
|
||||
if (window->type == META_WINDOW_DESKTOP)
|
||||
return;
|
||||
|
||||
if (window->override_redirect)
|
||||
if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
|
||||
{
|
||||
meta_window_update_monitor (window, FALSE);
|
||||
return;
|
||||
@ -4312,8 +4343,8 @@ set_workspace_state (MetaWindow *window,
|
||||
GList *l;
|
||||
for (l = window->screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *workspace = l->data;
|
||||
meta_workspace_remove_window (workspace, window);
|
||||
MetaWorkspace *ws = l->data;
|
||||
meta_workspace_remove_window (ws, window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4327,8 +4358,8 @@ set_workspace_state (MetaWindow *window,
|
||||
GList *l;
|
||||
for (l = window->screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *workspace = l->data;
|
||||
meta_workspace_add_window (workspace, window);
|
||||
MetaWorkspace *ws = l->data;
|
||||
meta_workspace_add_window (ws, window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5271,6 +5302,11 @@ meta_window_recalc_features (MetaWindow *window)
|
||||
|
||||
meta_window_recalc_skip_features (window);
|
||||
|
||||
/* To prevent users from losing windows, let's prevent users from
|
||||
* minimizing skip-taskbar windows through the window decorations. */
|
||||
if (window->skip_taskbar)
|
||||
window->has_minimize_func = FALSE;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Window %s decorated = %d border_only = %d has_close = %d has_minimize = %d has_maximize = %d has_move = %d has_shade = %d skip_taskbar = %d skip_pager = %d\n",
|
||||
window->desc,
|
||||
@ -6272,7 +6308,7 @@ find_ancestor_func (MetaWindow *window,
|
||||
* so by traversing the @transient's ancestors until it either locates @window
|
||||
* or reaches an ancestor that is not transient.
|
||||
*
|
||||
* Return Value: (transfer none): %TRUE if window is an ancestor of transient.
|
||||
* Return Value: %TRUE if window is an ancestor of transient.
|
||||
*/
|
||||
gboolean
|
||||
meta_window_is_ancestor_of_transient (MetaWindow *window,
|
||||
@ -7010,7 +7046,7 @@ meta_window_get_transient_for (MetaWindow *window)
|
||||
* Returns pid of the process that created this window, if known (obtained from
|
||||
* the _NET_WM_PID property).
|
||||
*
|
||||
* Return value: (transfer none): the pid, or -1 if not known.
|
||||
* Return value: the pid, or -1 if not known.
|
||||
*/
|
||||
int
|
||||
meta_window_get_pid (MetaWindow *window)
|
||||
@ -7381,14 +7417,14 @@ meta_window_set_transient_for (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
/* update stacking constraints */
|
||||
if (!window->override_redirect)
|
||||
meta_stack_update_transient (window->screen->stack, window);
|
||||
|
||||
/* We know this won't create a reference cycle because we check for loops */
|
||||
g_clear_object (&window->transient_for);
|
||||
window->transient_for = parent ? g_object_ref (parent) : NULL;
|
||||
|
||||
/* update stacking constraints */
|
||||
if (!window->override_redirect)
|
||||
meta_stack_update_transient (window->screen->stack, window);
|
||||
|
||||
/* possibly change its group. We treat being a window's transient as
|
||||
* equivalent to making it your group leader, to work around shortcomings
|
||||
* in programs such as xmms-- see #328211.
|
||||
@ -7399,7 +7435,7 @@ meta_window_set_transient_for (MetaWindow *window,
|
||||
meta_window_group_leader_changed (window);
|
||||
|
||||
if (!window->constructing && !window->override_redirect)
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
|
||||
|
||||
if (meta_window_appears_focused (window) && window->transient_for != NULL)
|
||||
meta_window_propagate_focus_appearance (window, TRUE);
|
||||
@ -7638,13 +7674,29 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
MetaDisplay *display = window->display;
|
||||
gboolean unmodified;
|
||||
gboolean is_window_grab;
|
||||
ClutterModifierType grab_mods, event_mods;
|
||||
gfloat x, y;
|
||||
guint button;
|
||||
|
||||
if (window->frame && meta_ui_frame_handle_event (window->frame->ui_frame, event))
|
||||
return;
|
||||
|
||||
if (event->type != CLUTTER_BUTTON_PRESS)
|
||||
if (event->type != CLUTTER_BUTTON_PRESS &&
|
||||
event->type != CLUTTER_TOUCH_BEGIN)
|
||||
return;
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
|
||||
button = 1;
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
if (!meta_display_is_pointer_emulating_sequence (window->display, sequence))
|
||||
return;
|
||||
}
|
||||
else
|
||||
button = clutter_event_get_button (event);
|
||||
|
||||
if (display->grab_op != META_GRAB_OP_NONE)
|
||||
return;
|
||||
|
||||
@ -7655,6 +7707,22 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
if (window->override_redirect)
|
||||
return;
|
||||
|
||||
/* Don't focus panels--they must explicitly request focus.
|
||||
* See bug 160470
|
||||
*/
|
||||
if (window->type != META_WINDOW_DOCK)
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing %s due to button %u press (display.c)\n",
|
||||
window->desc, button);
|
||||
meta_window_focus (window, event->any.time);
|
||||
}
|
||||
else
|
||||
/* However, do allow terminals to lose focus due to new
|
||||
* window mappings after the user clicks on a panel.
|
||||
*/
|
||||
display->allow_terminal_deactivation = TRUE;
|
||||
|
||||
/* We have three passive button grabs:
|
||||
* - on any button, without modifiers => focuses and maybe raises the window
|
||||
* - on resize button, with modifiers => start an interactive resizing
|
||||
@ -7675,9 +7743,12 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
* care about. Just let the event through.
|
||||
*/
|
||||
|
||||
ClutterModifierType grab_mods = meta_display_get_window_grab_modifiers (display);
|
||||
unmodified = (event->button.modifier_state & grab_mods) == 0;
|
||||
is_window_grab = (event->button.modifier_state & grab_mods) == grab_mods;
|
||||
grab_mods = meta_display_get_window_grab_modifiers (display);
|
||||
event_mods = clutter_event_get_state (event);
|
||||
unmodified = (event_mods & grab_mods) == 0;
|
||||
is_window_grab = (event_mods & grab_mods) == grab_mods;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
if (unmodified)
|
||||
{
|
||||
@ -7686,27 +7757,8 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Not raising window on click due to don't-raise-on-click option\n");
|
||||
|
||||
/* Don't focus panels--they must explicitly request focus.
|
||||
* See bug 160470
|
||||
*/
|
||||
if (window->type != META_WINDOW_DOCK)
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing %s due to unmodified button %u press (display.c)\n",
|
||||
window->desc, event->button.button);
|
||||
meta_window_focus (window, event->any.time);
|
||||
}
|
||||
else
|
||||
/* However, do allow terminals to lose focus due to new
|
||||
* window mappings after the user clicks on a panel.
|
||||
*/
|
||||
display->allow_terminal_deactivation = TRUE;
|
||||
|
||||
meta_verbose ("Allowing events time %u\n",
|
||||
(unsigned int)event->button.time);
|
||||
}
|
||||
else if (is_window_grab && (int) event->button.button == meta_prefs_get_mouse_button_resize ())
|
||||
else if (is_window_grab && (int) button == meta_prefs_get_mouse_button_resize ())
|
||||
{
|
||||
if (window->has_resize_func)
|
||||
{
|
||||
@ -7717,10 +7769,10 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3);
|
||||
east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3);
|
||||
north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3);
|
||||
south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3);
|
||||
west = x < (frame_rect.x + 1 * frame_rect.width / 3);
|
||||
east = x > (frame_rect.x + 2 * frame_rect.width / 3);
|
||||
north = y < (frame_rect.y + 1 * frame_rect.height / 3);
|
||||
south = y > (frame_rect.y + 2 * frame_rect.height / 3);
|
||||
|
||||
if (west)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_WEST;
|
||||
@ -7738,23 +7790,21 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
op,
|
||||
TRUE,
|
||||
FALSE,
|
||||
event->button.button,
|
||||
button,
|
||||
0,
|
||||
event->any.time,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
x, y);
|
||||
}
|
||||
}
|
||||
else if (is_window_grab && (int) event->button.button == meta_prefs_get_mouse_button_menu ())
|
||||
else if (is_window_grab && (int) button == meta_prefs_get_mouse_button_menu ())
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
meta_window_show_menu (window,
|
||||
META_WINDOW_MENU_WM,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
x, y);
|
||||
}
|
||||
else if (is_window_grab && (int) event->button.button == 1)
|
||||
else if (is_window_grab && (int) button == 1)
|
||||
{
|
||||
if (window->has_move_func)
|
||||
{
|
||||
@ -7764,11 +7814,10 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
META_GRAB_OP_MOVING,
|
||||
TRUE,
|
||||
FALSE,
|
||||
event->button.button,
|
||||
button,
|
||||
0,
|
||||
event->any.time,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1055,7 +1055,7 @@ meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
|
||||
}
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static char *
|
||||
static const char *
|
||||
meta_motion_direction_to_string (MetaMotionDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
|
@ -372,12 +372,6 @@ typedef enum
|
||||
* @META_BUTTON_FUNCTION_MINIMIZE: Minimize
|
||||
* @META_BUTTON_FUNCTION_MAXIMIZE: Maximize
|
||||
* @META_BUTTON_FUNCTION_CLOSE: Close
|
||||
* @META_BUTTON_FUNCTION_SHADE: Shade
|
||||
* @META_BUTTON_FUNCTION_ABOVE: Above
|
||||
* @META_BUTTON_FUNCTION_STICK: Stick
|
||||
* @META_BUTTON_FUNCTION_UNSHADE: Unshade
|
||||
* @META_BUTTON_FUNCTION_UNABOVE: Unabove
|
||||
* @META_BUTTON_FUNCTION_UNSTICK: Unstick
|
||||
* @META_BUTTON_FUNCTION_LAST: Marks the end of the #MetaButtonFunction enumeration
|
||||
*
|
||||
* Function a window button can have. Note, you can't add stuff here
|
||||
@ -390,12 +384,6 @@ typedef enum
|
||||
META_BUTTON_FUNCTION_MINIMIZE,
|
||||
META_BUTTON_FUNCTION_MAXIMIZE,
|
||||
META_BUTTON_FUNCTION_CLOSE,
|
||||
META_BUTTON_FUNCTION_SHADE,
|
||||
META_BUTTON_FUNCTION_ABOVE,
|
||||
META_BUTTON_FUNCTION_STICK,
|
||||
META_BUTTON_FUNCTION_UNSHADE,
|
||||
META_BUTTON_FUNCTION_UNABOVE,
|
||||
META_BUTTON_FUNCTION_UNSTICK,
|
||||
META_BUTTON_FUNCTION_APPMENU,
|
||||
META_BUTTON_FUNCTION_LAST
|
||||
} MetaButtonFunction;
|
||||
@ -405,10 +393,10 @@ typedef enum
|
||||
/* Keep array size in sync with MAX_BUTTONS_PER_CORNER */
|
||||
/**
|
||||
* MetaButtonLayout:
|
||||
* @left_buttons: (array fixed-size=11):
|
||||
* @right_buttons: (array fixed-size=11):
|
||||
* @left_buttons_has_spacer: (array fixed-size=11):
|
||||
* @right_buttons_has_spacer: (array fixed-size=11):
|
||||
* @left_buttons: (array fixed-size=5):
|
||||
* @right_buttons: (array fixed-size=5):
|
||||
* @left_buttons_has_spacer: (array fixed-size=5):
|
||||
* @right_buttons_has_spacer: (array fixed-size=5):
|
||||
*/
|
||||
typedef struct _MetaButtonLayout MetaButtonLayout;
|
||||
struct _MetaButtonLayout
|
||||
|
@ -57,6 +57,8 @@ typedef enum
|
||||
typedef enum {
|
||||
META_SIZE_CHANGE_MAXIMIZE,
|
||||
META_SIZE_CHANGE_UNMAXIMIZE,
|
||||
META_SIZE_CHANGE_FULLSCREEN,
|
||||
META_SIZE_CHANGE_UNFULLSCREEN,
|
||||
} MetaSizeChange;
|
||||
|
||||
MetaCompositor *meta_compositor_new (MetaDisplay *display);
|
||||
|
@ -49,7 +49,7 @@ typedef enum
|
||||
} MetaExitCode;
|
||||
|
||||
/* exit immediately */
|
||||
void meta_exit (MetaExitCode code);
|
||||
void meta_exit (MetaExitCode code) G_GNUC_NORETURN;
|
||||
|
||||
/* g_main_loop_quit() then fall out of main() */
|
||||
void meta_quit (MetaExitCode code);
|
||||
|
@ -9,6 +9,8 @@
|
||||
<method name="TakeControl">
|
||||
<arg name="force" type="b"/>
|
||||
</method>
|
||||
<method name="ReleaseControl">
|
||||
</method>
|
||||
<method name="TakeDevice">
|
||||
<annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
|
||||
<arg name="major" type="u" direction="in"/>
|
||||
|
14
src/tests/stacking/set-parent.metatest
Normal file
14
src/tests/stacking/set-parent.metatest
Normal file
@ -0,0 +1,14 @@
|
||||
new_client 1 wayland
|
||||
create 1/1
|
||||
show 1/1
|
||||
create 1/2
|
||||
show 1/2
|
||||
wait
|
||||
assert_stacking 1/1 1/2
|
||||
|
||||
set_parent 1/1 2
|
||||
wait
|
||||
assert_stacking 1/2 1/1
|
||||
|
||||
local_activate 1/2
|
||||
assert_stacking 1/2 1/1
|
@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
char *client_id = "0";
|
||||
const char *client_id = "0";
|
||||
static gboolean wayland;
|
||||
GHashTable *windows;
|
||||
|
||||
@ -41,6 +41,16 @@ lookup_window (const char *window_id)
|
||||
return window;
|
||||
}
|
||||
|
||||
static void
|
||||
on_after_paint (GdkFrameClock *clock,
|
||||
GMainLoop *loop)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (clock,
|
||||
(gpointer) on_after_paint,
|
||||
loop);
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static void
|
||||
process_line (const char *line)
|
||||
{
|
||||
@ -126,6 +136,31 @@ process_line (const char *line)
|
||||
}
|
||||
|
||||
}
|
||||
else if (strcmp (argv[0], "set_parent") == 0)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
g_print ("usage: menu <window-id> <parent-id>");
|
||||
goto out;
|
||||
}
|
||||
|
||||
GtkWidget *window = lookup_window (argv[1]);
|
||||
if (!window)
|
||||
{
|
||||
g_print ("unknown window %s", argv[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
GtkWidget *parent_window = lookup_window (argv[2]);
|
||||
if (!parent_window)
|
||||
{
|
||||
g_print ("unknown parent window %s", argv[2]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (parent_window));
|
||||
}
|
||||
else if (strcmp (argv[0], "show") == 0)
|
||||
{
|
||||
if (argc != 2)
|
||||
@ -135,10 +170,25 @@ process_line (const char *line)
|
||||
}
|
||||
|
||||
GtkWidget *window = lookup_window (argv[1]);
|
||||
GdkWindow *gdk_window = gtk_widget_get_window (window);
|
||||
if (!window)
|
||||
goto out;
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
/* When a Wayland client, we cannot be really sure that the window has
|
||||
* been mappable until after we have painted. So, in order to have the
|
||||
* test runner rely on the "show" command to have done what the client
|
||||
* needs to do in order for a window to be mappable compositor side, lets
|
||||
* wait with returning until after the first frame.
|
||||
*/
|
||||
GdkFrameClock *frame_clock = gdk_window_get_frame_clock (gdk_window);
|
||||
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
|
||||
g_signal_connect (frame_clock, "after-paint",
|
||||
G_CALLBACK (on_after_paint),
|
||||
loop);
|
||||
g_main_loop_run (loop);
|
||||
g_main_loop_unref (loop);
|
||||
}
|
||||
else if (strcmp (argv[0], "hide") == 0)
|
||||
{
|
||||
|
@ -767,6 +767,23 @@ test_case_do (TestCase *test,
|
||||
NULL))
|
||||
return FALSE;
|
||||
}
|
||||
else if (strcmp (argv[0], "set_parent") == 0)
|
||||
{
|
||||
if (argc != 3)
|
||||
BAD_COMMAND("usage: %s <client-id>/<window-id> <parent-window-id>",
|
||||
argv[0]);
|
||||
|
||||
TestClient *client;
|
||||
const char *window_id;
|
||||
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
|
||||
return FALSE;
|
||||
|
||||
if (!test_client_do (client, error,
|
||||
"set_parent", window_id,
|
||||
argv[2],
|
||||
NULL))
|
||||
return FALSE;
|
||||
}
|
||||
else if (strcmp (argv[0], "show") == 0 ||
|
||||
strcmp (argv[0], "hide") == 0 ||
|
||||
strcmp (argv[0], "activate") == 0 ||
|
||||
@ -1094,7 +1111,6 @@ main (int argc, char **argv)
|
||||
if (all_tests)
|
||||
{
|
||||
GFile *test_dir = g_file_new_for_path (MUTTER_PKGDATADIR "/tests");
|
||||
GError *error = NULL;
|
||||
|
||||
if (!find_metatests_in_directory (test_dir, tests, &error))
|
||||
{
|
||||
@ -1120,7 +1136,7 @@ main (int argc, char **argv)
|
||||
|
||||
/* Then initalize mutter with a different set of arguments */
|
||||
|
||||
char *fake_args[] = { NULL, "--wayland" };
|
||||
char *fake_args[] = { NULL, (char *)"--wayland" };
|
||||
fake_args[0] = argv[0];
|
||||
char **fake_argv = fake_args;
|
||||
int fake_argc = 2;
|
||||
|
117
src/ui/frames.c
117
src/ui/frames.c
@ -970,12 +970,6 @@ meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
case META_FRAME_CONTROL_UNMAXIMIZE:
|
||||
case META_FRAME_CONTROL_MINIMIZE:
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
case META_FRAME_CONTROL_SHADE:
|
||||
case META_FRAME_CONTROL_UNSHADE:
|
||||
case META_FRAME_CONTROL_ABOVE:
|
||||
case META_FRAME_CONTROL_UNABOVE:
|
||||
case META_FRAME_CONTROL_STICK:
|
||||
case META_FRAME_CONTROL_UNSTICK:
|
||||
case META_FRAME_CONTROL_MENU:
|
||||
case META_FRAME_CONTROL_APPMENU:
|
||||
frame->grab_button = event->button;
|
||||
@ -1074,7 +1068,10 @@ handle_button_press_event (MetaUIFrame *frame,
|
||||
|
||||
control = get_control (frame, event->x, event->y);
|
||||
|
||||
/* focus on click, even if click was on client area */
|
||||
/* don't do the rest of this if on client area */
|
||||
if (control == META_FRAME_CONTROL_CLIENT_AREA)
|
||||
return FALSE; /* not on the frame, just passed through from client */
|
||||
|
||||
if (event->button == 1 &&
|
||||
!(control == META_FRAME_CONTROL_MINIMIZE ||
|
||||
control == META_FRAME_CONTROL_DELETE ||
|
||||
@ -1086,10 +1083,6 @@ handle_button_press_event (MetaUIFrame *frame,
|
||||
meta_window_focus (frame->meta_window, event->time);
|
||||
}
|
||||
|
||||
/* don't do the rest of this if on client area */
|
||||
if (control == META_FRAME_CONTROL_CLIENT_AREA)
|
||||
return FALSE; /* not on the frame, just passed through from client */
|
||||
|
||||
/* We want to shade even if we have a GrabOp, since we'll have a move grab
|
||||
* if we double click the titlebar.
|
||||
*/
|
||||
@ -1154,24 +1147,6 @@ handle_button_release_event (MetaUIFrame *frame,
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
meta_window_delete (frame->meta_window, event->time);
|
||||
break;
|
||||
case META_FRAME_CONTROL_SHADE:
|
||||
meta_window_shade (frame->meta_window, event->time);
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSHADE:
|
||||
meta_window_unshade (frame->meta_window, event->time);
|
||||
break;
|
||||
case META_FRAME_CONTROL_ABOVE:
|
||||
meta_window_make_above (frame->meta_window);
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNABOVE:
|
||||
meta_window_unmake_above (frame->meta_window);
|
||||
break;
|
||||
case META_FRAME_CONTROL_STICK:
|
||||
meta_window_stick (frame->meta_window);
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSTICK:
|
||||
meta_window_unstick (frame->meta_window);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1220,18 +1195,6 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNMAXIMIZE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_SHADE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSHADE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_ABOVE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNABOVE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_STICK:
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSTICK:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_SE:
|
||||
cursor = META_CURSOR_SE_RESIZE;
|
||||
break;
|
||||
@ -1270,12 +1233,6 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
|
||||
case META_FRAME_CONTROL_MINIMIZE:
|
||||
case META_FRAME_CONTROL_MAXIMIZE:
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
case META_FRAME_CONTROL_SHADE:
|
||||
case META_FRAME_CONTROL_UNSHADE:
|
||||
case META_FRAME_CONTROL_ABOVE:
|
||||
case META_FRAME_CONTROL_UNABOVE:
|
||||
case META_FRAME_CONTROL_STICK:
|
||||
case META_FRAME_CONTROL_UNSTICK:
|
||||
case META_FRAME_CONTROL_UNMAXIMIZE:
|
||||
/* leave control set */
|
||||
break;
|
||||
@ -1487,24 +1444,6 @@ meta_ui_frame_paint (MetaUIFrame *frame,
|
||||
case META_FRAME_CONTROL_UNMAXIMIZE:
|
||||
button_type = META_BUTTON_TYPE_MAXIMIZE;
|
||||
break;
|
||||
case META_FRAME_CONTROL_SHADE:
|
||||
button_type = META_BUTTON_TYPE_SHADE;
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSHADE:
|
||||
button_type = META_BUTTON_TYPE_UNSHADE;
|
||||
break;
|
||||
case META_FRAME_CONTROL_ABOVE:
|
||||
button_type = META_BUTTON_TYPE_ABOVE;
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNABOVE:
|
||||
button_type = META_BUTTON_TYPE_UNABOVE;
|
||||
break;
|
||||
case META_FRAME_CONTROL_STICK:
|
||||
button_type = META_BUTTON_TYPE_STICK;
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSTICK:
|
||||
button_type = META_BUTTON_TYPE_UNSTICK;
|
||||
break;
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
button_type = META_BUTTON_TYPE_CLOSE;
|
||||
break;
|
||||
@ -1624,24 +1563,6 @@ control_rect (MetaFrameControl control,
|
||||
case META_FRAME_CONTROL_UNMAXIMIZE:
|
||||
rect = &fgeom->max_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_SHADE:
|
||||
rect = &fgeom->shade_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSHADE:
|
||||
rect = &fgeom->unshade_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_ABOVE:
|
||||
rect = &fgeom->above_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNABOVE:
|
||||
rect = &fgeom->unabove_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_STICK:
|
||||
rect = &fgeom->stick_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_UNSTICK:
|
||||
rect = &fgeom->unstick_rect.visible;
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_SE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_S:
|
||||
@ -1726,36 +1647,6 @@ get_control (MetaUIFrame *frame, int root_x, int root_y)
|
||||
return META_FRAME_CONTROL_MAXIMIZE;
|
||||
}
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.shade_rect.clickable))
|
||||
{
|
||||
return META_FRAME_CONTROL_SHADE;
|
||||
}
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.unshade_rect.clickable))
|
||||
{
|
||||
return META_FRAME_CONTROL_UNSHADE;
|
||||
}
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.above_rect.clickable))
|
||||
{
|
||||
return META_FRAME_CONTROL_ABOVE;
|
||||
}
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.unabove_rect.clickable))
|
||||
{
|
||||
return META_FRAME_CONTROL_UNABOVE;
|
||||
}
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.stick_rect.clickable))
|
||||
{
|
||||
return META_FRAME_CONTROL_STICK;
|
||||
}
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.unstick_rect.clickable))
|
||||
{
|
||||
return META_FRAME_CONTROL_UNSTICK;
|
||||
}
|
||||
|
||||
/* South resize always has priority over north resize,
|
||||
* in case of overlap.
|
||||
*/
|
||||
|
@ -39,12 +39,6 @@ typedef enum
|
||||
META_FRAME_CONTROL_MINIMIZE,
|
||||
META_FRAME_CONTROL_MAXIMIZE,
|
||||
META_FRAME_CONTROL_UNMAXIMIZE,
|
||||
META_FRAME_CONTROL_SHADE,
|
||||
META_FRAME_CONTROL_UNSHADE,
|
||||
META_FRAME_CONTROL_ABOVE,
|
||||
META_FRAME_CONTROL_UNABOVE,
|
||||
META_FRAME_CONTROL_STICK,
|
||||
META_FRAME_CONTROL_UNSTICK,
|
||||
META_FRAME_CONTROL_RESIZE_SE,
|
||||
META_FRAME_CONTROL_RESIZE_S,
|
||||
META_FRAME_CONTROL_RESIZE_SW,
|
||||
|
@ -60,6 +60,16 @@ struct _MetaFrameLayout
|
||||
/** Border/padding of titlebar buttons */
|
||||
GtkBorder button_border;
|
||||
|
||||
/** Margin of title */
|
||||
GtkBorder title_margin;
|
||||
/** Margin of titlebar buttons */
|
||||
GtkBorder button_margin;
|
||||
|
||||
/** Min size of titlebar region */
|
||||
GtkRequisition titlebar_min_size;
|
||||
/** Min size of titlebar buttons */
|
||||
GtkRequisition button_min_size;
|
||||
|
||||
/** Size of images in buttons */
|
||||
guint icon_size;
|
||||
|
||||
@ -115,7 +125,7 @@ struct _MetaFrameGeometry
|
||||
|
||||
/* used for a memset hack */
|
||||
#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
|
||||
#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, unstick_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
|
||||
#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, appmenu_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
|
||||
|
||||
/* The button rects (if changed adjust memset hack) */
|
||||
MetaButtonSpace close_rect;
|
||||
@ -123,12 +133,6 @@ struct _MetaFrameGeometry
|
||||
MetaButtonSpace min_rect;
|
||||
MetaButtonSpace menu_rect;
|
||||
MetaButtonSpace appmenu_rect;
|
||||
MetaButtonSpace shade_rect;
|
||||
MetaButtonSpace above_rect;
|
||||
MetaButtonSpace stick_rect;
|
||||
MetaButtonSpace unshade_rect;
|
||||
MetaButtonSpace unabove_rect;
|
||||
MetaButtonSpace unstick_rect;
|
||||
/* End of button rects (if changed adjust memset hack) */
|
||||
|
||||
/* Saved button layout */
|
||||
@ -158,12 +162,6 @@ typedef enum
|
||||
META_BUTTON_TYPE_MINIMIZE,
|
||||
META_BUTTON_TYPE_MENU,
|
||||
META_BUTTON_TYPE_APPMENU,
|
||||
META_BUTTON_TYPE_SHADE,
|
||||
META_BUTTON_TYPE_ABOVE,
|
||||
META_BUTTON_TYPE_STICK,
|
||||
META_BUTTON_TYPE_UNSHADE,
|
||||
META_BUTTON_TYPE_UNABOVE,
|
||||
META_BUTTON_TYPE_UNSTICK,
|
||||
META_BUTTON_TYPE_LAST
|
||||
} MetaButtonType;
|
||||
|
||||
|
130
src/ui/theme.c
130
src/ui/theme.c
@ -79,10 +79,14 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout,
|
||||
|
||||
if (!layout->has_title)
|
||||
text_height = 0;
|
||||
else
|
||||
text_height = layout->title_margin.top + text_height + layout->title_margin.bottom;
|
||||
|
||||
buttons_height = layout->icon_size +
|
||||
layout->button_border.top + layout->button_border.bottom;
|
||||
content_height = MAX (buttons_height, text_height) +
|
||||
buttons_height = MAX ((int)layout->icon_size, layout->button_min_size.height) +
|
||||
layout->button_margin.top + layout->button_border.top +
|
||||
layout->button_margin.bottom + layout->button_border.bottom;
|
||||
content_height = MAX (buttons_height, text_height);
|
||||
content_height = MAX (content_height, layout->titlebar_min_size.height) +
|
||||
layout->titlebar_border.top + layout->titlebar_border.bottom;
|
||||
|
||||
borders->visible.top = layout->frame_border.top + content_height;
|
||||
@ -177,17 +181,6 @@ rect_for_function (MetaFrameGeometry *fgeom,
|
||||
return &fgeom->close_rect;
|
||||
else
|
||||
return NULL;
|
||||
case META_BUTTON_FUNCTION_STICK:
|
||||
case META_BUTTON_FUNCTION_SHADE:
|
||||
case META_BUTTON_FUNCTION_ABOVE:
|
||||
case META_BUTTON_FUNCTION_UNSTICK:
|
||||
case META_BUTTON_FUNCTION_UNSHADE:
|
||||
case META_BUTTON_FUNCTION_UNABOVE:
|
||||
/* Fringe buttons that used to be supported by theme versions >v1;
|
||||
* if we want to support them again, we need to return the
|
||||
* correspondings rects here
|
||||
*/
|
||||
return NULL;
|
||||
|
||||
case META_BUTTON_FUNCTION_LAST:
|
||||
return NULL;
|
||||
@ -245,6 +238,16 @@ get_padding_and_border (GtkStyleContext *style,
|
||||
border->bottom += tmp.bottom;
|
||||
}
|
||||
|
||||
static void
|
||||
get_min_size (GtkStyleContext *style,
|
||||
GtkRequisition *requisition)
|
||||
{
|
||||
gtk_style_context_get (style, gtk_style_context_get_state (style),
|
||||
"min-width", &requisition->width,
|
||||
"min-height", &requisition->height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_border (GtkBorder *border,
|
||||
double factor)
|
||||
@ -262,6 +265,7 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
|
||||
{
|
||||
GtkStyleContext *style;
|
||||
GtkBorder border;
|
||||
GtkRequisition requisition;
|
||||
int border_radius, max_radius;
|
||||
|
||||
meta_style_info_set_flags (style_info, flags);
|
||||
@ -292,14 +296,25 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
|
||||
max_radius = MIN (layout->frame_border.bottom, layout->frame_border.right);
|
||||
layout->bottom_right_corner_rounded_radius = MAX (border_radius, max_radius);
|
||||
|
||||
get_min_size (style, &layout->titlebar_min_size);
|
||||
get_padding_and_border (style, &layout->titlebar_border);
|
||||
scale_border (&layout->titlebar_border, layout->title_scale);
|
||||
|
||||
style = style_info->styles[META_STYLE_ELEMENT_TITLE];
|
||||
gtk_style_context_get_margin (style, gtk_style_context_get_state (style),
|
||||
&layout->title_margin);
|
||||
scale_border (&layout->title_margin, layout->title_scale);
|
||||
|
||||
style = style_info->styles[META_STYLE_ELEMENT_BUTTON];
|
||||
get_min_size (style, &layout->button_min_size);
|
||||
get_padding_and_border (style, &layout->button_border);
|
||||
scale_border (&layout->button_border, layout->title_scale);
|
||||
gtk_style_context_get_margin (style, gtk_style_context_get_state (style),
|
||||
&layout->button_margin);
|
||||
scale_border (&layout->button_margin, layout->title_scale);
|
||||
|
||||
style = style_info->styles[META_STYLE_ELEMENT_IMAGE];
|
||||
get_min_size (style, &requisition);
|
||||
get_padding_and_border (style, &border);
|
||||
scale_border (&border, layout->title_scale);
|
||||
|
||||
@ -307,6 +322,18 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
|
||||
layout->button_border.right += border.right;
|
||||
layout->button_border.top += border.top;
|
||||
layout->button_border.bottom += border.bottom;
|
||||
|
||||
gtk_style_context_get_margin (style, gtk_style_context_get_state (style),
|
||||
&border);
|
||||
layout->button_border.left += border.left;
|
||||
layout->button_border.right += border.right;
|
||||
layout->button_border.top += border.top;
|
||||
layout->button_border.bottom += border.bottom;
|
||||
|
||||
layout->button_min_size.width = MAX(layout->button_min_size.width,
|
||||
requisition.width);
|
||||
layout->button_min_size.height = MAX(layout->button_min_size.height,
|
||||
requisition.height);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -370,9 +397,9 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
(fgeom->content_border.right + borders.invisible.right);
|
||||
content_height = borders.visible.top - fgeom->content_border.top - fgeom->content_border.bottom;
|
||||
|
||||
button_width = layout->icon_size +
|
||||
button_width = MAX ((int)layout->icon_size, layout->button_min_size.width) +
|
||||
layout->button_border.left + layout->button_border.right;
|
||||
button_height = layout->icon_size +
|
||||
button_height = MAX ((int)layout->icon_size, layout->button_min_size.height) +
|
||||
layout->button_border.top + layout->button_border.bottom;
|
||||
button_width *= scale;
|
||||
button_height *= scale;
|
||||
@ -433,11 +460,15 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
|
||||
space_used_by_buttons = 0;
|
||||
|
||||
space_used_by_buttons += layout->button_margin.left * scale * n_left;
|
||||
space_used_by_buttons += button_width * n_left;
|
||||
space_used_by_buttons += layout->button_margin.right * scale * n_left;
|
||||
space_used_by_buttons += (button_width * 0.75) * n_left_spacers;
|
||||
space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_left - 1, 0);
|
||||
|
||||
space_used_by_buttons += layout->button_margin.left * scale * n_right;
|
||||
space_used_by_buttons += button_width * n_right;
|
||||
space_used_by_buttons += layout->button_margin.right * scale * n_right;
|
||||
space_used_by_buttons += (button_width * 0.75) * n_right_spacers;
|
||||
space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_right - 1, 0);
|
||||
|
||||
@ -457,22 +488,10 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
}
|
||||
|
||||
/* Otherwise we need to shave out a button. Shave
|
||||
* above, stick, shade, min, max, close, then menu (menu is most useful);
|
||||
* min, max, close, then menu (menu is most useful);
|
||||
* prefer the default button locations.
|
||||
*/
|
||||
if (strip_button (left_func_rects, &n_left, &fgeom->above_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, &n_right, &fgeom->above_rect))
|
||||
continue;
|
||||
else if (strip_button (left_func_rects, &n_left, &fgeom->stick_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, &n_right, &fgeom->stick_rect))
|
||||
continue;
|
||||
else if (strip_button (left_func_rects, &n_left, &fgeom->shade_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, &n_right, &fgeom->shade_rect))
|
||||
continue;
|
||||
else if (strip_button (left_func_rects, &n_left, &fgeom->min_rect))
|
||||
if (strip_button (left_func_rects, &n_left, &fgeom->min_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, &n_right, &fgeom->min_rect))
|
||||
continue;
|
||||
@ -519,6 +538,8 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */
|
||||
break;
|
||||
|
||||
x -= layout->button_margin.right * scale;
|
||||
|
||||
rect = right_func_rects[i];
|
||||
rect->visible.x = x - button_width;
|
||||
if (right_buttons_has_spacer[i])
|
||||
@ -544,7 +565,7 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
else
|
||||
g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
|
||||
|
||||
x = rect->visible.x;
|
||||
x = rect->visible.x - layout->button_margin.left * scale;
|
||||
|
||||
if (i > 0)
|
||||
x -= layout->titlebar_spacing;
|
||||
@ -563,6 +584,8 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
{
|
||||
MetaButtonSpace *rect;
|
||||
|
||||
x += layout->button_margin.left * scale;
|
||||
|
||||
rect = left_func_rects[i];
|
||||
|
||||
rect->visible.x = x;
|
||||
@ -589,7 +612,7 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
else
|
||||
g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
|
||||
|
||||
x = rect->visible.x + rect->visible.width;
|
||||
x = rect->visible.x + rect->visible.width + layout->button_margin.right * scale;
|
||||
if (i < n_left - 1)
|
||||
x += layout->titlebar_spacing * scale;
|
||||
if (left_buttons_has_spacer[i])
|
||||
@ -643,30 +666,6 @@ get_button_rect (MetaButtonType type,
|
||||
*rect = fgeom->close_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_SHADE:
|
||||
*rect = fgeom->shade_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_UNSHADE:
|
||||
*rect = fgeom->unshade_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_ABOVE:
|
||||
*rect = fgeom->above_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_UNABOVE:
|
||||
*rect = fgeom->unabove_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_STICK:
|
||||
*rect = fgeom->stick_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_UNSTICK:
|
||||
*rect = fgeom->unstick_rect.visible;
|
||||
break;
|
||||
|
||||
case META_BUTTON_TYPE_MAXIMIZE:
|
||||
*rect = fgeom->max_rect.visible;
|
||||
break;
|
||||
@ -890,6 +889,7 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
|
||||
cairo_restore (cr);
|
||||
if (button_class)
|
||||
gtk_style_context_remove_class (style, button_class);
|
||||
gtk_style_context_set_state (style, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -915,11 +915,9 @@ meta_theme_get_default (void)
|
||||
switch (frame_type)
|
||||
{
|
||||
case META_FRAME_TYPE_NORMAL:
|
||||
break;
|
||||
case META_FRAME_TYPE_DIALOG:
|
||||
case META_FRAME_TYPE_MODAL_DIALOG:
|
||||
case META_FRAME_TYPE_ATTACHED:
|
||||
layout->hide_buttons = TRUE;
|
||||
break;
|
||||
case META_FRAME_TYPE_MENU:
|
||||
case META_FRAME_TYPE_UTILITY:
|
||||
@ -977,6 +975,7 @@ static GtkStyleContext *
|
||||
create_style_context (GType widget_type,
|
||||
GtkStyleContext *parent_style,
|
||||
GtkCssProvider *provider,
|
||||
const char *object_name,
|
||||
const char *first_class,
|
||||
...)
|
||||
{
|
||||
@ -996,6 +995,9 @@ create_style_context (GType widget_type,
|
||||
|
||||
gtk_widget_path_append_type (path, widget_type);
|
||||
|
||||
if (object_name)
|
||||
gtk_widget_path_iter_set_object_name (path, -1, object_name);
|
||||
|
||||
va_start (ap, first_class);
|
||||
for (name = first_class; name; name = va_arg (ap, const char *))
|
||||
gtk_widget_path_iter_add_class (path, -1, name);
|
||||
@ -1035,6 +1037,7 @@ meta_theme_create_style_info (GdkScreen *screen,
|
||||
create_style_context (META_TYPE_FRAMES,
|
||||
NULL,
|
||||
provider,
|
||||
"decoration",
|
||||
GTK_STYLE_CLASS_BACKGROUND,
|
||||
"window-frame",
|
||||
"ssd",
|
||||
@ -1043,28 +1046,30 @@ meta_theme_create_style_info (GdkScreen *screen,
|
||||
create_style_context (GTK_TYPE_HEADER_BAR,
|
||||
style_info->styles[META_STYLE_ELEMENT_FRAME],
|
||||
provider,
|
||||
"headerbar",
|
||||
GTK_STYLE_CLASS_TITLEBAR,
|
||||
GTK_STYLE_CLASS_HORIZONTAL,
|
||||
"default-decoration",
|
||||
"header-bar",
|
||||
NULL);
|
||||
style_info->styles[META_STYLE_ELEMENT_TITLE] =
|
||||
create_style_context (GTK_TYPE_LABEL,
|
||||
style_info->styles[META_STYLE_ELEMENT_TITLEBAR],
|
||||
provider,
|
||||
"label",
|
||||
GTK_STYLE_CLASS_TITLE,
|
||||
NULL);
|
||||
style_info->styles[META_STYLE_ELEMENT_BUTTON] =
|
||||
create_style_context (GTK_TYPE_BUTTON,
|
||||
style_info->styles[META_STYLE_ELEMENT_TITLEBAR],
|
||||
provider,
|
||||
GTK_STYLE_CLASS_BUTTON,
|
||||
"button",
|
||||
"titlebutton",
|
||||
NULL);
|
||||
style_info->styles[META_STYLE_ELEMENT_IMAGE] =
|
||||
create_style_context (GTK_TYPE_IMAGE,
|
||||
style_info->styles[META_STYLE_ELEMENT_BUTTON],
|
||||
provider,
|
||||
"image",
|
||||
NULL);
|
||||
return style_info;
|
||||
}
|
||||
@ -1171,9 +1176,10 @@ meta_style_info_create_font_desc (MetaStyleInfo *style_info)
|
||||
{
|
||||
PangoFontDescription *font_desc;
|
||||
const PangoFontDescription *override = meta_prefs_get_titlebar_font ();
|
||||
GtkStyleContext *context = style_info->styles[META_STYLE_ELEMENT_TITLE];
|
||||
|
||||
gtk_style_context_get (style_info->styles[META_STYLE_ELEMENT_TITLE],
|
||||
GTK_STATE_FLAG_NORMAL,
|
||||
gtk_style_context_get (context,
|
||||
gtk_style_context_get_state (context),
|
||||
"font", &font_desc, NULL);
|
||||
|
||||
if (override)
|
||||
|
@ -37,17 +37,30 @@
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-dnd-actor-private.h"
|
||||
|
||||
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
|
||||
struct _MetaWaylandDataOffer
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_listener source_destroy_listener;
|
||||
uint32_t dnd_actions;
|
||||
enum wl_data_device_manager_dnd_action preferred_dnd_action;
|
||||
};
|
||||
|
||||
typedef struct _MetaWaylandDataSourcePrivate
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
struct wl_array mime_types;
|
||||
gboolean has_target;
|
||||
uint32_t dnd_actions;
|
||||
enum wl_data_device_manager_dnd_action user_dnd_action;
|
||||
enum wl_data_device_manager_dnd_action current_dnd_action;
|
||||
MetaWaylandSeat *seat;
|
||||
guint actions_set : 1;
|
||||
guint in_ask : 1;
|
||||
} MetaWaylandDataSourcePrivate;
|
||||
|
||||
typedef struct _MetaWaylandDataSourceWayland
|
||||
@ -57,8 +70,6 @@ typedef struct _MetaWaylandDataSourceWayland
|
||||
struct wl_resource *resource;
|
||||
} MetaWaylandDataSourceWayland;
|
||||
|
||||
GType meta_wayland_data_source_wayland_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source,
|
||||
G_TYPE_OBJECT);
|
||||
G_DEFINE_TYPE (MetaWaylandDataSourceWayland, meta_wayland_data_source_wayland,
|
||||
@ -76,6 +87,75 @@ unbind_resource (struct wl_resource *resource)
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_wayland_source_get_in_ask (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->in_ask;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_source_update_in_ask (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->in_ask =
|
||||
priv->current_dnd_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
}
|
||||
|
||||
static enum wl_data_device_manager_dnd_action
|
||||
data_offer_choose_action (MetaWaylandDataOffer *offer)
|
||||
{
|
||||
MetaWaylandDataSource *source = offer->source;
|
||||
uint32_t actions, user_action, available_actions;
|
||||
|
||||
actions = meta_wayland_data_source_get_actions (source);
|
||||
user_action = meta_wayland_data_source_get_user_action (source);
|
||||
|
||||
available_actions = actions & offer->dnd_actions;
|
||||
|
||||
if (!available_actions)
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||
|
||||
/* If the user is forcing an action, go for it */
|
||||
if ((user_action & available_actions) != 0)
|
||||
return user_action;
|
||||
|
||||
/* If the dest side has a preferred DnD action, use it */
|
||||
if ((offer->preferred_dnd_action & available_actions) != 0)
|
||||
return offer->preferred_dnd_action;
|
||||
|
||||
/* Use the first found action, in bit order */
|
||||
return 1 << (ffs (available_actions) - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_update_action (MetaWaylandDataOffer *offer)
|
||||
{
|
||||
enum wl_data_device_manager_dnd_action current_action, action;
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
if (!offer->source)
|
||||
return;
|
||||
|
||||
source = offer->source;
|
||||
current_action = meta_wayland_data_source_get_current_action (source);
|
||||
action = data_offer_choose_action (offer);
|
||||
|
||||
if (current_action == action)
|
||||
return;
|
||||
|
||||
meta_wayland_data_source_set_current_action (source, action);
|
||||
|
||||
if (!meta_wayland_source_get_in_ask (source) &&
|
||||
wl_resource_get_version (offer->resource) >=
|
||||
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||
wl_data_offer_send_action (offer->resource, action);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_target (MetaWaylandDataSource *source,
|
||||
const char *mime_type)
|
||||
@ -100,6 +180,25 @@ meta_wayland_data_source_has_target (MetaWaylandDataSource *source)
|
||||
return priv->has_target;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_set_seat (MetaWaylandDataSource *source,
|
||||
MetaWaylandSeat *seat)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->seat = seat;
|
||||
}
|
||||
|
||||
static MetaWaylandSeat *
|
||||
meta_wayland_data_source_get_seat (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->seat;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
||||
gboolean has_target)
|
||||
@ -114,7 +213,7 @@ struct wl_array *
|
||||
meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
meta_wayland_data_source_get_instance_private ((MetaWaylandDataSource *)source);
|
||||
|
||||
return &priv->mime_types;
|
||||
}
|
||||
@ -125,6 +224,100 @@ meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
meta_wayland_data_source_get_actions (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->dnd_actions;
|
||||
}
|
||||
|
||||
enum wl_data_device_manager_dnd_action
|
||||
meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (!priv->seat)
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||
|
||||
return priv->user_dnd_action;
|
||||
}
|
||||
|
||||
enum wl_data_device_manager_dnd_action
|
||||
meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->current_dnd_action;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source,
|
||||
MetaWaylandDataOffer *offer)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->offer = offer;
|
||||
}
|
||||
|
||||
static MetaWaylandDataOffer *
|
||||
meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->offer;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||
enum wl_data_device_manager_dnd_action action)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (priv->current_dnd_action == action)
|
||||
return;
|
||||
|
||||
priv->current_dnd_action = action;
|
||||
|
||||
if (!meta_wayland_source_get_in_ask (source))
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->action (source, action);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||
uint32_t dnd_actions)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->dnd_actions = dnd_actions;
|
||||
priv->actions_set = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
||||
enum wl_data_device_manager_dnd_action action)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
MetaWaylandDataOffer *offer;
|
||||
|
||||
if (priv->user_dnd_action == action)
|
||||
return;
|
||||
|
||||
priv->user_dnd_action = action;
|
||||
offer = meta_wayland_data_source_get_current_offer (source);
|
||||
|
||||
if (offer)
|
||||
data_offer_update_action (offer);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_accept (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
@ -163,21 +356,117 @@ data_offer_destroy (struct wl_client *client, struct wl_resource *resource)
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_finish (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
enum wl_data_device_manager_dnd_action current_action;
|
||||
|
||||
if (!offer->source ||
|
||||
offer != meta_wayland_data_source_get_current_offer (offer->source))
|
||||
return;
|
||||
|
||||
if (meta_wayland_data_source_get_seat (offer->source) ||
|
||||
!meta_wayland_data_source_has_target (offer->source))
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_FINISH,
|
||||
"premature finish request");
|
||||
return;
|
||||
}
|
||||
|
||||
current_action = meta_wayland_data_source_get_current_action (offer->source);
|
||||
|
||||
if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE ||
|
||||
current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_OFFER,
|
||||
"offer finished with an invalid action");
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_data_source_notify_finish (offer->source);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_set_actions (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t dnd_actions,
|
||||
uint32_t preferred_action)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
if (dnd_actions & ~(ALL_ACTIONS))
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
|
||||
"invalid actions mask %x", dnd_actions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (preferred_action &&
|
||||
(!(preferred_action & dnd_actions) ||
|
||||
__builtin_popcount (preferred_action) > 1))
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_ACTION,
|
||||
"invalid action %x", preferred_action);
|
||||
return;
|
||||
}
|
||||
|
||||
offer->dnd_actions = dnd_actions;
|
||||
offer->preferred_dnd_action = preferred_action;
|
||||
|
||||
data_offer_update_action (offer);
|
||||
}
|
||||
|
||||
static const struct wl_data_offer_interface data_offer_interface = {
|
||||
data_offer_accept,
|
||||
data_offer_receive,
|
||||
data_offer_destroy,
|
||||
data_offer_finish,
|
||||
data_offer_set_actions,
|
||||
};
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source)
|
||||
{
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drop_performed (source);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source)
|
||||
{
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drag_finished (source);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_data_offer (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
if (offer->source)
|
||||
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||
(gpointer *)&offer->source);
|
||||
{
|
||||
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||
{
|
||||
if (wl_resource_get_version (offer->resource) <
|
||||
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||
meta_wayland_data_source_notify_finish (offer->source);
|
||||
else
|
||||
{
|
||||
meta_wayland_data_source_cancel (offer->source);
|
||||
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||
(gpointer *)&offer->source);
|
||||
offer->source = NULL;
|
||||
}
|
||||
|
||||
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||
g_slice_free (MetaWaylandDataOffer, offer);
|
||||
}
|
||||
|
||||
@ -205,6 +494,9 @@ meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
|
||||
wl_array_for_each (p, &priv->mime_types)
|
||||
wl_data_offer_send_offer (offer->resource, *p);
|
||||
|
||||
data_offer_update_action (offer);
|
||||
meta_wayland_data_source_set_current_offer (source, offer);
|
||||
|
||||
return offer->resource;
|
||||
}
|
||||
|
||||
@ -224,14 +516,56 @@ data_source_destroy (struct wl_client *client, struct wl_resource *resource)
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_set_actions (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t dnd_actions)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
MetaWaylandDataSourceWayland *source_wayland =
|
||||
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
|
||||
|
||||
if (priv->actions_set)
|
||||
{
|
||||
wl_resource_post_error (source_wayland->resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||
"cannot set actions more than once");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dnd_actions & ~(ALL_ACTIONS))
|
||||
{
|
||||
wl_resource_post_error (source_wayland->resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||
"invalid actions mask %x", dnd_actions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_wayland_data_source_get_seat (source))
|
||||
{
|
||||
wl_resource_post_error (source_wayland->resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||
"invalid action change after "
|
||||
"wl_data_device.start_drag");
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_data_source_set_actions (source, dnd_actions);
|
||||
}
|
||||
|
||||
static struct wl_data_source_interface data_source_interface = {
|
||||
data_source_offer,
|
||||
data_source_destroy
|
||||
data_source_destroy,
|
||||
data_source_set_actions
|
||||
};
|
||||
|
||||
struct _MetaWaylandDragGrab {
|
||||
MetaWaylandPointerGrab generic;
|
||||
|
||||
MetaWaylandKeyboardGrab keyboard_grab;
|
||||
|
||||
MetaWaylandSeat *seat;
|
||||
struct wl_client *drag_client;
|
||||
|
||||
@ -250,6 +584,7 @@ struct _MetaWaylandDragGrab {
|
||||
struct wl_listener drag_origin_listener;
|
||||
|
||||
int drag_start_x, drag_start_y;
|
||||
ClutterModifierType buttons;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -258,6 +593,24 @@ destroy_drag_focus (struct wl_listener *listener, void *data)
|
||||
MetaWaylandDragGrab *grab = wl_container_of (listener, grab, drag_focus_listener);
|
||||
|
||||
grab->drag_focus_data_device = NULL;
|
||||
grab->drag_focus = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_drag_grab_set_source (MetaWaylandDragGrab *drag_grab,
|
||||
MetaWaylandDataSource *source)
|
||||
{
|
||||
if (drag_grab->drag_data_source)
|
||||
g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
|
||||
drag_grab_data_source_destroyed,
|
||||
drag_grab);
|
||||
|
||||
drag_grab->drag_data_source = source;
|
||||
|
||||
if (source)
|
||||
g_object_weak_ref (G_OBJECT (source),
|
||||
drag_grab_data_source_destroyed,
|
||||
drag_grab);
|
||||
}
|
||||
|
||||
void
|
||||
@ -277,6 +630,9 @@ meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
|
||||
drag_grab->drag_focus = NULL;
|
||||
}
|
||||
|
||||
if (drag_grab->drag_data_source)
|
||||
meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
@ -314,6 +670,22 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
meta_wayland_drag_grab_set_focus (drag_grab, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_update_user_dnd_action (MetaWaylandDataSource *source,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
enum wl_data_device_manager_dnd_action user_dnd_action = 0;
|
||||
|
||||
if (modifiers & CLUTTER_SHIFT_MASK)
|
||||
user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
else if (modifiers & CLUTTER_CONTROL_MASK)
|
||||
user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
else if (modifiers & (CLUTTER_MOD1_MASK | CLUTTER_BUTTON2_MASK))
|
||||
user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
meta_wayland_data_source_set_user_action (source, user_dnd_action);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_grab_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
@ -345,10 +717,7 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
|
||||
wl_list_remove (&drag_grab->drag_icon_listener.link);
|
||||
}
|
||||
|
||||
if (drag_grab->drag_data_source)
|
||||
g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
|
||||
drag_grab_data_source_destroyed,
|
||||
drag_grab);
|
||||
meta_wayland_drag_grab_set_source (drag_grab, NULL);
|
||||
|
||||
if (drag_grab->feedback_actor)
|
||||
{
|
||||
@ -358,7 +727,15 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
|
||||
|
||||
drag_grab->seat->data_device.current_grab = NULL;
|
||||
|
||||
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
|
||||
/* There might be other grabs created in result to DnD actions like popups
|
||||
* on "ask" actions, we must not reset those, only our own.
|
||||
*/
|
||||
if (drag_grab->generic.pointer->grab == (MetaWaylandPointerGrab *) drag_grab)
|
||||
{
|
||||
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
|
||||
meta_wayland_keyboard_end_grab (drag_grab->keyboard_grab.keyboard);
|
||||
}
|
||||
|
||||
g_slice_free (MetaWaylandDragGrab, drag_grab);
|
||||
}
|
||||
|
||||
@ -373,17 +750,33 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
|
||||
if (drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
|
||||
event_type == CLUTTER_BUTTON_RELEASE)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
MetaWaylandDataSource *source = drag_grab->drag_data_source;
|
||||
gboolean success;
|
||||
|
||||
if (meta_wayland_data_source_has_target (drag_grab->drag_data_source))
|
||||
if (drag_grab->drag_focus && source &&
|
||||
meta_wayland_data_source_has_target (source) &&
|
||||
meta_wayland_data_source_get_current_action (source))
|
||||
{
|
||||
/* Detach the data source from the grab, it's meant to live longer */
|
||||
meta_wayland_drag_grab_set_source (drag_grab, NULL);
|
||||
meta_wayland_data_source_set_seat (source, NULL);
|
||||
|
||||
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
|
||||
meta_wayland_data_source_notify_drop_performed (source);
|
||||
|
||||
meta_wayland_source_update_in_ask (source);
|
||||
success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_wayland_data_source_cancel (source);
|
||||
meta_wayland_data_source_set_current_offer (source, NULL);
|
||||
meta_wayland_data_device_set_dnd_source (&seat->data_device, NULL);
|
||||
success= FALSE;
|
||||
}
|
||||
|
||||
/* Finish drag and let actor self-destruct */
|
||||
meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor),
|
||||
success);
|
||||
meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor), success);
|
||||
drag_grab->feedback_actor = NULL;
|
||||
}
|
||||
|
||||
@ -398,6 +791,40 @@ static const MetaWaylandPointerGrabInterface drag_grab_interface = {
|
||||
drag_grab_button,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
keyboard_drag_grab_key (MetaWaylandKeyboardGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_drag_grab_modifiers (MetaWaylandKeyboardGrab *grab,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab;
|
||||
|
||||
drag_grab = wl_container_of (grab, drag_grab, keyboard_grab);
|
||||
|
||||
/* The modifiers here just contain keyboard modifiers, mix it with the
|
||||
* mouse button modifiers we got when starting the drag operation.
|
||||
*/
|
||||
modifiers |= drag_grab->buttons;
|
||||
|
||||
if (drag_grab->drag_data_source)
|
||||
{
|
||||
data_source_update_user_dnd_action (drag_grab->drag_data_source, modifiers);
|
||||
|
||||
if (drag_grab->drag_focus)
|
||||
meta_wayland_surface_drag_dest_update (drag_grab->drag_focus);
|
||||
}
|
||||
}
|
||||
|
||||
static const MetaWaylandKeyboardGrabInterface keyboard_drag_grab_interface = {
|
||||
keyboard_drag_grab_key,
|
||||
keyboard_drag_grab_modifiers
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_data_device_origin (struct wl_listener *listener, void *data)
|
||||
{
|
||||
@ -405,8 +832,8 @@ destroy_data_device_origin (struct wl_listener *listener, void *data)
|
||||
wl_container_of (listener, drag_grab, drag_origin_listener);
|
||||
|
||||
drag_grab->drag_origin = NULL;
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -415,8 +842,8 @@ drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was)
|
||||
MetaWaylandDragGrab *drag_grab = data;
|
||||
|
||||
drag_grab->drag_data_source = NULL;
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -442,12 +869,16 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
MetaWaylandDragGrab *drag_grab;
|
||||
ClutterPoint pos, stage_pos;
|
||||
ClutterModifierType modifiers;
|
||||
|
||||
data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
|
||||
|
||||
drag_grab->generic.interface = funcs;
|
||||
drag_grab->generic.pointer = &seat->pointer;
|
||||
|
||||
drag_grab->keyboard_grab.interface = &keyboard_drag_grab_interface;
|
||||
drag_grab->keyboard_grab.keyboard = &seat->keyboard;
|
||||
|
||||
drag_grab->drag_client = client;
|
||||
drag_grab->seat = seat;
|
||||
|
||||
@ -462,13 +893,15 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
|
||||
drag_grab->drag_start_x = stage_pos.x;
|
||||
drag_grab->drag_start_y = stage_pos.y;
|
||||
|
||||
g_object_weak_ref (G_OBJECT (source),
|
||||
drag_grab_data_source_destroyed,
|
||||
drag_grab);
|
||||
modifiers = clutter_input_device_get_modifier_state (seat->pointer.device);
|
||||
drag_grab->buttons = modifiers &
|
||||
(CLUTTER_BUTTON1_MASK | CLUTTER_BUTTON2_MASK | CLUTTER_BUTTON3_MASK |
|
||||
CLUTTER_BUTTON4_MASK | CLUTTER_BUTTON5_MASK);
|
||||
|
||||
drag_grab->drag_data_source = source;
|
||||
meta_wayland_drag_grab_set_source (drag_grab, source);
|
||||
meta_wayland_data_device_set_dnd_source (data_device,
|
||||
drag_grab->drag_data_source);
|
||||
data_source_update_user_dnd_action (source, modifiers);
|
||||
|
||||
if (icon_surface)
|
||||
{
|
||||
@ -482,8 +915,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
|
||||
drag_grab->drag_start_x,
|
||||
drag_grab->drag_start_y);
|
||||
meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
|
||||
-drag_grab->drag_surface->offset_x,
|
||||
-drag_grab->drag_surface->offset_y);
|
||||
0, 0);
|
||||
clutter_actor_add_child (drag_grab->feedback_actor,
|
||||
CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor));
|
||||
|
||||
@ -492,6 +924,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
|
||||
}
|
||||
|
||||
meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*) drag_grab);
|
||||
meta_wayland_data_source_set_seat (source, seat);
|
||||
}
|
||||
|
||||
void
|
||||
@ -550,6 +983,10 @@ data_device_start_drag (struct wl_client *client,
|
||||
meta_wayland_data_device_start_drag (data_device, client,
|
||||
&drag_grab_interface,
|
||||
surface, drag_source, icon_surface);
|
||||
|
||||
meta_wayland_keyboard_set_focus (&seat->keyboard, NULL);
|
||||
meta_wayland_keyboard_start_grab (&seat->keyboard,
|
||||
&seat->data_device.current_grab->keyboard_grab);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -602,6 +1039,47 @@ meta_wayland_source_cancel (MetaWaylandDataSource *source)
|
||||
wl_data_source_send_cancelled (source_wayland->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_source_action (MetaWaylandDataSource *source,
|
||||
enum wl_data_device_manager_dnd_action action)
|
||||
{
|
||||
MetaWaylandDataSourceWayland *source_wayland =
|
||||
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
|
||||
|
||||
if (wl_resource_get_version (source_wayland->resource) >=
|
||||
WL_DATA_SOURCE_ACTION_SINCE_VERSION)
|
||||
wl_data_source_send_action (source_wayland->resource, action);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_source_drop_performed (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourceWayland *source_wayland =
|
||||
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
|
||||
|
||||
if (wl_resource_get_version (source_wayland->resource) >=
|
||||
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
|
||||
wl_data_source_send_dnd_drop_performed (source_wayland->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_source_drag_finished (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourceWayland *source_wayland =
|
||||
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
|
||||
enum wl_data_device_manager_dnd_action action;
|
||||
|
||||
if (meta_wayland_source_get_in_ask (source))
|
||||
{
|
||||
action = meta_wayland_data_source_get_current_action (source);
|
||||
meta_wayland_source_action (source, action);
|
||||
}
|
||||
|
||||
if (wl_resource_get_version (source_wayland->resource) >=
|
||||
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
|
||||
wl_data_source_send_dnd_finished (source_wayland->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_source_finalize (GObject *object)
|
||||
{
|
||||
@ -625,6 +1103,9 @@ meta_wayland_data_source_wayland_class_init (MetaWaylandDataSourceWaylandClass *
|
||||
data_source_class->send = meta_wayland_source_send;
|
||||
data_source_class->target = meta_wayland_source_target;
|
||||
data_source_class->cancel = meta_wayland_source_cancel;
|
||||
data_source_class->action = meta_wayland_source_action;
|
||||
data_source_class->drop_performed = meta_wayland_source_drop_performed;
|
||||
data_source_class->drag_finished = meta_wayland_source_drag_finished;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -649,6 +1130,7 @@ meta_wayland_data_source_init (MetaWaylandDataSource *source)
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
wl_array_init (&priv->mime_types);
|
||||
priv->current_dnd_action = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -667,6 +1149,7 @@ meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandDragGrab *grab = data_device->current_grab;
|
||||
struct wl_display *display;
|
||||
struct wl_client *client;
|
||||
uint32_t source_actions;
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
if (!grab->drag_focus_data_device)
|
||||
@ -679,6 +1162,13 @@ meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device,
|
||||
wl_resource_add_destroy_listener (grab->drag_focus_data_device,
|
||||
&grab->drag_focus_listener);
|
||||
|
||||
if (wl_resource_get_version (offer->resource) >=
|
||||
WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
source_actions = meta_wayland_data_source_get_actions (offer->source);
|
||||
wl_data_offer_send_source_actions (offer->resource, source_actions);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer,
|
||||
surface, &sx, &sy);
|
||||
wl_data_device_send_enter (grab->drag_focus_data_device,
|
||||
@ -724,11 +1214,18 @@ meta_wayland_drag_dest_drop (MetaWaylandDataDevice *data_device,
|
||||
wl_data_device_send_drop (grab->drag_focus_data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_drag_dest_update (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static const MetaWaylandDragDestFuncs meta_wayland_drag_dest_funcs = {
|
||||
meta_wayland_drag_dest_focus_in,
|
||||
meta_wayland_drag_dest_focus_out,
|
||||
meta_wayland_drag_dest_motion,
|
||||
meta_wayland_drag_dest_drop
|
||||
meta_wayland_drag_dest_drop,
|
||||
meta_wayland_drag_dest_update
|
||||
};
|
||||
|
||||
const MetaWaylandDragDestFuncs *
|
||||
@ -745,12 +1242,14 @@ meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
|
||||
return;
|
||||
|
||||
if (data_device->dnd_data_source)
|
||||
g_object_remove_weak_pointer (G_OBJECT (source),
|
||||
g_object_remove_weak_pointer (G_OBJECT (data_device->dnd_data_source),
|
||||
(gpointer *)&data_device->dnd_data_source);
|
||||
|
||||
data_device->dnd_data_source = source;
|
||||
g_object_add_weak_pointer (G_OBJECT (source),
|
||||
(gpointer *)&data_device->dnd_data_source);
|
||||
|
||||
if (source)
|
||||
g_object_add_weak_pointer (G_OBJECT (data_device->dnd_data_source),
|
||||
(gpointer *)&data_device->dnd_data_source);
|
||||
|
||||
wl_signal_emit (&data_device->dnd_ownership_signal, source);
|
||||
}
|
||||
@ -815,6 +1314,7 @@ data_device_set_selection (struct wl_client *client,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDataSourcePrivate *priv;
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
if (source_resource)
|
||||
@ -822,6 +1322,19 @@ data_device_set_selection (struct wl_client *client,
|
||||
else
|
||||
source = NULL;
|
||||
|
||||
if (source)
|
||||
{
|
||||
priv = meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (priv->actions_set)
|
||||
{
|
||||
wl_resource_post_error(source_resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_SOURCE,
|
||||
"cannot set drag-and-drop source as selection");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Store serial and check against incoming serial here. */
|
||||
meta_wayland_data_device_set_selection (data_device, source, serial);
|
||||
}
|
||||
@ -912,6 +1425,12 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard);
|
||||
|
||||
if (focus_client == data_device->focus_client)
|
||||
return;
|
||||
|
||||
data_device->focus_client = focus_client;
|
||||
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
@ -937,30 +1456,12 @@ meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
|
||||
data_device->current_grab->drag_surface == surface;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab;
|
||||
|
||||
if (!data_device->current_grab)
|
||||
return;
|
||||
|
||||
drag_grab = data_device->current_grab;
|
||||
|
||||
if (!drag_grab->feedback_actor || !drag_grab->drag_surface)
|
||||
return;
|
||||
|
||||
meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
|
||||
-drag_grab->drag_surface->offset_x,
|
||||
-drag_grab->drag_surface->offset_y);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
|
||||
const gchar *mime_type)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
meta_wayland_data_source_get_instance_private ((MetaWaylandDataSource *)source);
|
||||
gchar **p;
|
||||
|
||||
wl_array_for_each (p, &priv->mime_types)
|
||||
|
@ -45,6 +45,11 @@ struct _MetaWaylandDataSourceClass
|
||||
void (* target) (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type);
|
||||
void (* cancel) (MetaWaylandDataSource *source);
|
||||
|
||||
void (* action) (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
void (* drop_performed) (MetaWaylandDataSource *source);
|
||||
void (* drag_finished) (MetaWaylandDataSource *source);
|
||||
};
|
||||
|
||||
struct _MetaWaylandDataDevice
|
||||
@ -55,13 +60,12 @@ struct _MetaWaylandDataDevice
|
||||
struct wl_listener selection_data_source_listener;
|
||||
struct wl_list resource_list;
|
||||
MetaWaylandDragGrab *current_grab;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
struct wl_signal selection_ownership_signal;
|
||||
struct wl_signal dnd_ownership_signal;
|
||||
};
|
||||
|
||||
GType meta_wayland_data_source_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_data_device_init (MetaWaylandDataDevice *data_device);
|
||||
@ -70,7 +74,6 @@ void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_de
|
||||
|
||||
gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandSurface *surface);
|
||||
void meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device);
|
||||
|
||||
void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandDataSource *source);
|
||||
@ -96,6 +99,17 @@ void meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd);
|
||||
|
||||
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
|
||||
|
||||
uint32_t meta_wayland_data_source_get_actions (MetaWaylandDataSource *source);
|
||||
uint32_t meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
|
||||
uint32_t meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||
uint32_t dnd_actions);
|
||||
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
|
||||
const MetaWaylandDragDestFuncs *
|
||||
meta_wayland_data_device_get_drag_dest_funcs (void);
|
||||
|
||||
|
@ -56,13 +56,19 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard);
|
||||
static void notify_modifiers (MetaWaylandKeyboard *keyboard);
|
||||
static guint evdev_code (const ClutterKeyEvent *event);
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
@ -240,8 +246,10 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
notify_key (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t time, uint32_t key, uint32_t state)
|
||||
meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
@ -251,11 +259,12 @@ notify_key (MetaWaylandKeyboard *keyboard,
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (keyboard->focus_surface->resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
uint32_t serial = wl_display_next_serial (display);
|
||||
|
||||
keyboard->key_serial = wl_display_next_serial (display);
|
||||
|
||||
wl_resource_for_each (resource, l)
|
||||
{
|
||||
wl_keyboard_send_key (resource, serial, time, key, state);
|
||||
wl_keyboard_send_key (resource, keyboard->key_serial, time, key, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,8 +272,15 @@ notify_key (MetaWaylandKeyboard *keyboard,
|
||||
return (keyboard->focus_surface != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
notify_key (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return keyboard->grab->interface->key (keyboard->grab, event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_modifiers (MetaWaylandKeyboard *keyboard)
|
||||
meta_wayland_keyboard_broadcast_modifiers (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
struct xkb_state *state;
|
||||
struct wl_resource *resource;
|
||||
@ -289,6 +305,16 @@ notify_modifiers (MetaWaylandKeyboard *keyboard)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
notify_modifiers (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
struct xkb_state *state;
|
||||
|
||||
state = keyboard->xkb_info.state;
|
||||
keyboard->grab->interface->modifiers (keyboard->grab,
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
@ -368,6 +394,45 @@ settings_changed (GSettings *settings,
|
||||
notify_key_repeat (keyboard);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
default_grab_key (MetaWaylandKeyboardGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandKeyboard *keyboard = grab->keyboard;
|
||||
gboolean is_press = event->type == CLUTTER_KEY_PRESS;
|
||||
guint32 code;
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
#endif
|
||||
|
||||
/* Synthetic key events are for autorepeat. Ignore those, as
|
||||
* autorepeat in Wayland is done on the client side. */
|
||||
if (event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC)
|
||||
return FALSE;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
code = clutter_evdev_event_get_event_code (event);
|
||||
else
|
||||
#endif
|
||||
code = evdev_code (&event->key);
|
||||
|
||||
return meta_wayland_keyboard_broadcast_key (keyboard, event->key.time,
|
||||
code, is_press);
|
||||
}
|
||||
|
||||
static void
|
||||
default_grab_modifiers (MetaWaylandKeyboardGrab *grab,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
meta_wayland_keyboard_broadcast_modifiers (grab->keyboard);
|
||||
}
|
||||
|
||||
static const MetaWaylandKeyboardGrabInterface default_keyboard_grab_interface = {
|
||||
default_grab_key,
|
||||
default_grab_modifiers
|
||||
};
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display)
|
||||
@ -385,6 +450,10 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
keyboard->xkb_info.keymap_fd = -1;
|
||||
|
||||
keyboard->default_grab.interface = &default_keyboard_grab_interface;
|
||||
keyboard->default_grab.keyboard = keyboard;
|
||||
keyboard->grab = &keyboard->default_grab;
|
||||
|
||||
keyboard->settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
|
||||
g_signal_connect (keyboard->settings, "changed",
|
||||
G_CALLBACK (settings_changed), keyboard);
|
||||
@ -461,7 +530,7 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
is_press ? "press" : "release",
|
||||
event->hardware_keycode);
|
||||
|
||||
handled = notify_key (keyboard, event->time, evdev_code (event), is_press);
|
||||
handled = notify_key (keyboard, (const ClutterEvent *) event);
|
||||
|
||||
if (handled)
|
||||
meta_verbose ("Sent event to wayland client\n");
|
||||
@ -672,3 +741,25 @@ meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
|
||||
wl_list_insert (&keyboard->resource_list, wl_resource_get_link (cr));
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t serial)
|
||||
{
|
||||
return keyboard->key_serial == serial;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard,
|
||||
MetaWaylandKeyboardGrab *grab)
|
||||
{
|
||||
meta_wayland_keyboard_set_focus (keyboard, NULL);
|
||||
keyboard->grab = grab;
|
||||
grab->keyboard = keyboard;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
keyboard->grab = &keyboard->default_grab;
|
||||
}
|
||||
|
@ -49,6 +49,20 @@
|
||||
#include <wayland-server.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct _MetaWaylandKeyboardGrabInterface
|
||||
{
|
||||
gboolean (*key) (MetaWaylandKeyboardGrab *grab,
|
||||
const ClutterEvent *event);
|
||||
void (*modifiers) (MetaWaylandKeyboardGrab *grab,
|
||||
ClutterModifierType modifiers);
|
||||
};
|
||||
|
||||
struct _MetaWaylandKeyboardGrab
|
||||
{
|
||||
const MetaWaylandKeyboardGrabInterface *interface;
|
||||
MetaWaylandKeyboard *keyboard;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
@ -68,10 +82,14 @@ struct _MetaWaylandKeyboard
|
||||
MetaWaylandSurface *focus_surface;
|
||||
struct wl_listener focus_surface_listener;
|
||||
uint32_t focus_serial;
|
||||
uint32_t key_serial;
|
||||
|
||||
MetaWaylandXkbInfo xkb_info;
|
||||
enum xkb_state_component mods_changed;
|
||||
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
MetaWaylandKeyboardGrab default_grab;
|
||||
|
||||
GSettings *settings;
|
||||
};
|
||||
|
||||
@ -100,4 +118,11 @@ void meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t id);
|
||||
|
||||
gboolean meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t serial);
|
||||
|
||||
void meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard,
|
||||
MetaWaylandKeyboardGrab *grab);
|
||||
void meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard);
|
||||
|
||||
#endif /* META_WAYLAND_KEYBOARD_H */
|
||||
|
@ -99,7 +99,7 @@ bind_output (struct wl_client *client,
|
||||
mode_flags,
|
||||
(int)monitor_info->rect.width,
|
||||
(int)monitor_info->rect.height,
|
||||
(int)monitor_info->refresh_rate);
|
||||
(int)(monitor_info->refresh_rate * 1000));
|
||||
|
||||
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
||||
wl_output_send_scale (resource, output->scale);
|
||||
@ -160,7 +160,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
||||
mode_flags,
|
||||
(int)monitor_info->rect.width,
|
||||
(int)monitor_info->rect.height,
|
||||
(int)monitor_info->refresh_rate);
|
||||
(int)(monitor_info->refresh_rate * 1000));
|
||||
}
|
||||
|
||||
/* It's very important that we change the output pointer here, as
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "meta-wayland-pointer-gesture-pinch.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
#include "pointer-gestures-server-protocol.h"
|
||||
#include "pointer-gestures-unstable-v1-server-protocol.h"
|
||||
|
||||
static void
|
||||
handle_pinch_begin (MetaWaylandPointer *pointer,
|
||||
@ -45,10 +45,10 @@ handle_pinch_begin (MetaWaylandPointer *pointer,
|
||||
|
||||
wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
|
||||
{
|
||||
_wl_pointer_gesture_pinch_send_begin (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
pointer->focus_surface->resource,
|
||||
2);
|
||||
zwp_pointer_gesture_pinch_v1_send_begin (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
pointer->focus_surface->resource,
|
||||
2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,12 +67,12 @@ handle_pinch_update (MetaWaylandPointer *pointer,
|
||||
|
||||
wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
|
||||
{
|
||||
_wl_pointer_gesture_pinch_send_update (resource,
|
||||
clutter_event_get_time (event),
|
||||
wl_fixed_from_double (dx),
|
||||
wl_fixed_from_double (dy),
|
||||
wl_fixed_from_double (scale),
|
||||
wl_fixed_from_double (rotation));
|
||||
zwp_pointer_gesture_pinch_v1_send_update (resource,
|
||||
clutter_event_get_time (event),
|
||||
wl_fixed_from_double (dx),
|
||||
wl_fixed_from_double (dy),
|
||||
wl_fixed_from_double (scale),
|
||||
wl_fixed_from_double (rotation));
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,9 +93,9 @@ handle_pinch_end (MetaWaylandPointer *pointer,
|
||||
|
||||
wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
|
||||
{
|
||||
_wl_pointer_gesture_pinch_send_end (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
cancelled);
|
||||
zwp_pointer_gesture_pinch_v1_send_end (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
cancelled);
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ pointer_gesture_pinch_destroy (struct wl_client *client,
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct _wl_pointer_gesture_pinch_interface pointer_gesture_pinch_interface = {
|
||||
static const struct zwp_pointer_gesture_pinch_v1_interface pointer_gesture_pinch_interface = {
|
||||
pointer_gesture_pinch_destroy
|
||||
};
|
||||
|
||||
@ -151,7 +151,7 @@ meta_wayland_pointer_gesture_pinch_create_new_resource (MetaWaylandPointer *poin
|
||||
pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||
g_return_if_fail (pointer_client != NULL);
|
||||
|
||||
res = wl_resource_create (client, &_wl_pointer_gesture_pinch_interface,
|
||||
res = wl_resource_create (client, &zwp_pointer_gesture_pinch_v1_interface,
|
||||
wl_resource_get_version (gestures_resource), id);
|
||||
wl_resource_set_implementation (res, &pointer_gesture_pinch_interface, pointer,
|
||||
meta_wayland_pointer_unbind_pointer_client_resource);
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "meta-wayland-pointer-gesture-swipe.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
#include "pointer-gestures-server-protocol.h"
|
||||
#include "pointer-gestures-unstable-v1-server-protocol.h"
|
||||
|
||||
static void
|
||||
handle_swipe_begin (MetaWaylandPointer *pointer,
|
||||
@ -46,10 +46,10 @@ handle_swipe_begin (MetaWaylandPointer *pointer,
|
||||
|
||||
wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
|
||||
{
|
||||
_wl_pointer_gesture_swipe_send_begin (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
pointer->focus_surface->resource,
|
||||
fingers);
|
||||
zwp_pointer_gesture_swipe_v1_send_begin (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
pointer->focus_surface->resource,
|
||||
fingers);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,10 +66,10 @@ handle_swipe_update (MetaWaylandPointer *pointer,
|
||||
|
||||
wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
|
||||
{
|
||||
_wl_pointer_gesture_swipe_send_update (resource,
|
||||
clutter_event_get_time (event),
|
||||
wl_fixed_from_double (dx),
|
||||
wl_fixed_from_double (dy));
|
||||
zwp_pointer_gesture_swipe_v1_send_update (resource,
|
||||
clutter_event_get_time (event),
|
||||
wl_fixed_from_double (dx),
|
||||
wl_fixed_from_double (dy));
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,9 +90,9 @@ handle_swipe_end (MetaWaylandPointer *pointer,
|
||||
|
||||
wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
|
||||
{
|
||||
_wl_pointer_gesture_swipe_send_end (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
cancelled);
|
||||
zwp_pointer_gesture_swipe_v1_send_end (resource, serial,
|
||||
clutter_event_get_time (event),
|
||||
cancelled);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ pointer_gesture_swipe_release (struct wl_client *client,
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct _wl_pointer_gesture_swipe_interface pointer_gesture_swipe_interface = {
|
||||
static const struct zwp_pointer_gesture_swipe_v1_interface pointer_gesture_swipe_interface = {
|
||||
pointer_gesture_swipe_release
|
||||
};
|
||||
|
||||
@ -147,7 +147,7 @@ meta_wayland_pointer_gesture_swipe_create_new_resource (MetaWaylandPointer *poin
|
||||
pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||
g_return_if_fail (pointer_client != NULL);
|
||||
|
||||
res = wl_resource_create (client, &_wl_pointer_gesture_swipe_interface,
|
||||
res = wl_resource_create (client, &zwp_pointer_gesture_swipe_v1_interface,
|
||||
wl_resource_get_version (pointer_resource), id);
|
||||
wl_resource_set_implementation (res, &pointer_gesture_swipe_interface, pointer,
|
||||
meta_wayland_pointer_unbind_pointer_client_resource);
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include "meta-wayland-pointer-gestures.h"
|
||||
#include "pointer-gestures-server-protocol.h"
|
||||
#include "pointer-gestures-unstable-v1-server-protocol.h"
|
||||
#include "meta-wayland-versions.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
@ -53,7 +53,7 @@ gestures_get_pinch (struct wl_client *client,
|
||||
meta_wayland_pointer_gesture_pinch_create_new_resource (pointer, client, resource, id);
|
||||
}
|
||||
|
||||
static const struct _wl_pointer_gestures_interface pointer_gestures_interface = {
|
||||
static const struct zwp_pointer_gestures_v1_interface pointer_gestures_interface = {
|
||||
gestures_get_swipe,
|
||||
gestures_get_pinch
|
||||
};
|
||||
@ -66,16 +66,8 @@ bind_pointer_gestures (struct wl_client *client,
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &_wl_pointer_gestures_interface, version, id);
|
||||
|
||||
if (version != META__WL_POINTER_GESTURES_VERSION)
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
_WL_POINTER_GESTURES_ERROR_VERSION_MISMATCH,
|
||||
"The client bound a non-supported version");
|
||||
return;
|
||||
}
|
||||
|
||||
resource = wl_resource_create (client, &zwp_pointer_gestures_v1_interface,
|
||||
version, id);
|
||||
wl_resource_set_implementation (resource, &pointer_gestures_interface,
|
||||
NULL, NULL);
|
||||
}
|
||||
@ -84,7 +76,7 @@ void
|
||||
meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
wl_global_create (compositor->wayland_display,
|
||||
&_wl_pointer_gestures_interface,
|
||||
META__WL_POINTER_GESTURES_VERSION,
|
||||
&zwp_pointer_gestures_v1_interface,
|
||||
META_ZWP_POINTER_GESTURES_V1_VERSION,
|
||||
NULL, bind_pointer_gestures);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <linux/input.h>
|
||||
@ -53,6 +54,7 @@
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
#include "meta-wayland-buffer.h"
|
||||
#include "meta-xwayland.h"
|
||||
#include "meta-cursor.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
@ -61,6 +63,10 @@
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-cursor-renderer.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
|
||||
@ -74,7 +80,6 @@ struct _MetaWaylandSurfaceRoleCursor
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_cursor_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||
meta_wayland_surface_role_cursor,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -237,6 +242,28 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
|
||||
wl_pointer_send_frame (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_broadcast_frame (MetaWaylandPointer *pointer)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
if (!pointer->focus_client)
|
||||
return;
|
||||
|
||||
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
|
||||
{
|
||||
meta_wayland_pointer_send_frame (pointer, resource);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
|
||||
const ClutterEvent *event)
|
||||
@ -257,6 +284,8 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
|
||||
{
|
||||
wl_pointer_send_motion (resource, time, sx, sy);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_broadcast_frame (pointer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -277,26 +306,37 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
|
||||
uint32_t button;
|
||||
uint32_t serial;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
button = clutter_evdev_event_get_event_code (event);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
button = clutter_event_get_button (event);
|
||||
switch (button)
|
||||
{
|
||||
case 1:
|
||||
button = BTN_LEFT;
|
||||
break;
|
||||
|
||||
/* The evdev input right and middle button numbers are swapped
|
||||
relative to how Clutter numbers them */
|
||||
case 2:
|
||||
button = BTN_MIDDLE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
button = BTN_RIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
button = button + (BTN_LEFT - 1) + 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
time = clutter_event_get_time (event);
|
||||
|
||||
button = clutter_event_get_button (event);
|
||||
switch (button)
|
||||
{
|
||||
/* The evdev input right and middle button numbers are swapped
|
||||
relative to how Clutter numbers them */
|
||||
case 2:
|
||||
button = BTN_MIDDLE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
button = BTN_RIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
button = button + BTN_LEFT - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
|
||||
@ -305,6 +345,8 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
|
||||
time, button,
|
||||
event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_broadcast_frame (pointer);
|
||||
}
|
||||
|
||||
if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE)
|
||||
@ -494,26 +536,48 @@ handle_scroll_event (MetaWaylandPointer *pointer,
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
wl_fixed_t x_value = 0, y_value = 0;
|
||||
int x_discrete = 0, y_discrete = 0;
|
||||
enum wl_pointer_axis_source source = -1;
|
||||
|
||||
if (clutter_event_is_pointer_emulated (event))
|
||||
return;
|
||||
|
||||
switch (event->scroll.scroll_source)
|
||||
{
|
||||
case CLUTTER_SCROLL_SOURCE_WHEEL:
|
||||
source = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||
break;
|
||||
case CLUTTER_SCROLL_SOURCE_FINGER:
|
||||
source = WL_POINTER_AXIS_SOURCE_FINGER;
|
||||
break;
|
||||
case CLUTTER_SCROLL_SOURCE_CONTINUOUS:
|
||||
source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
|
||||
break;
|
||||
default:
|
||||
source = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (clutter_event_get_scroll_direction (event))
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
y_value = -DEFAULT_AXIS_STEP_DISTANCE;
|
||||
y_discrete = -1;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_DOWN:
|
||||
y_value = DEFAULT_AXIS_STEP_DISTANCE;
|
||||
y_discrete = 1;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_LEFT:
|
||||
x_value = -DEFAULT_AXIS_STEP_DISTANCE;
|
||||
x_discrete = -1;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_RIGHT:
|
||||
x_value = DEFAULT_AXIS_STEP_DISTANCE;
|
||||
x_discrete = 1;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_SMOOTH:
|
||||
@ -537,13 +601,44 @@ handle_scroll_event (MetaWaylandPointer *pointer,
|
||||
{
|
||||
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
|
||||
{
|
||||
if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
|
||||
wl_pointer_send_axis_source (resource, source);
|
||||
|
||||
/* X axis */
|
||||
if (x_discrete != 0 &&
|
||||
wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
|
||||
wl_pointer_send_axis_discrete (resource,
|
||||
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
|
||||
x_discrete);
|
||||
|
||||
if (x_value)
|
||||
wl_pointer_send_axis (resource, clutter_event_get_time (event),
|
||||
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
|
||||
|
||||
if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) &&
|
||||
wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
|
||||
wl_pointer_send_axis_stop (resource,
|
||||
clutter_event_get_time (event),
|
||||
WL_POINTER_AXIS_HORIZONTAL_SCROLL);
|
||||
/* Y axis */
|
||||
if (y_discrete != 0 &&
|
||||
wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
|
||||
wl_pointer_send_axis_discrete (resource,
|
||||
WL_POINTER_AXIS_VERTICAL_SCROLL,
|
||||
y_discrete);
|
||||
|
||||
if (y_value)
|
||||
wl_pointer_send_axis (resource, clutter_event_get_time (event),
|
||||
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
|
||||
|
||||
if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) &&
|
||||
wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
|
||||
wl_pointer_send_axis_stop (resource,
|
||||
clutter_event_get_time (event),
|
||||
WL_POINTER_AXIS_VERTICAL_SCROLL);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_broadcast_frame (pointer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,13 +677,57 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
|
||||
}
|
||||
|
||||
static void
|
||||
broadcast_focus (MetaWaylandPointer *pointer,
|
||||
struct wl_resource *resource)
|
||||
meta_wayland_pointer_send_enter (MetaWaylandPointer *pointer,
|
||||
struct wl_resource *pointer_resource,
|
||||
uint32_t serial,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy);
|
||||
wl_pointer_send_enter (resource, pointer->focus_serial, pointer->focus_surface->resource, sx, sy);
|
||||
meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy);
|
||||
wl_pointer_send_enter (pointer_resource,
|
||||
serial,
|
||||
surface->resource,
|
||||
sx, sy);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_send_leave (MetaWaylandPointer *pointer,
|
||||
struct wl_resource *pointer_resource,
|
||||
uint32_t serial,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
wl_pointer_send_leave (pointer_resource, serial, surface->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_broadcast_enter (MetaWaylandPointer *pointer,
|
||||
uint32_t serial,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
struct wl_resource *pointer_resource;
|
||||
|
||||
wl_resource_for_each (pointer_resource,
|
||||
&pointer->focus_client->pointer_resources)
|
||||
meta_wayland_pointer_send_enter (pointer, pointer_resource,
|
||||
serial, surface);
|
||||
|
||||
meta_wayland_pointer_broadcast_frame (pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer,
|
||||
uint32_t serial,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
struct wl_resource *pointer_resource;
|
||||
|
||||
wl_resource_for_each (pointer_resource,
|
||||
&pointer->focus_client->pointer_resources)
|
||||
meta_wayland_pointer_send_leave (pointer, pointer_resource,
|
||||
serial, surface);
|
||||
|
||||
meta_wayland_pointer_broadcast_frame (pointer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -607,18 +746,14 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
wl_resource_get_client (pointer->focus_surface->resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
uint32_t serial;
|
||||
struct wl_resource *resource;
|
||||
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
if (pointer->focus_client)
|
||||
{
|
||||
wl_resource_for_each (resource,
|
||||
&pointer->focus_client->pointer_resources)
|
||||
{
|
||||
wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_broadcast_leave (pointer,
|
||||
serial,
|
||||
pointer->focus_surface);
|
||||
pointer->focus_client = NULL;
|
||||
}
|
||||
|
||||
@ -630,7 +765,6 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (surface->resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
struct wl_resource *resource;
|
||||
ClutterPoint pos;
|
||||
|
||||
pointer->focus_surface = surface;
|
||||
@ -649,12 +783,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
if (pointer->focus_client)
|
||||
{
|
||||
pointer->focus_serial = wl_display_next_serial (display);
|
||||
|
||||
wl_resource_for_each (resource,
|
||||
&pointer->focus_client->pointer_resources)
|
||||
{
|
||||
broadcast_focus (pointer, resource);
|
||||
}
|
||||
meta_wayland_pointer_broadcast_enter (pointer,
|
||||
pointer->focus_serial,
|
||||
pointer->focus_surface);
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,9 +951,12 @@ cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
MetaScreen *screen = display->screen;
|
||||
const MetaMonitorInfo *monitor;
|
||||
|
||||
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
||||
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
||||
(float)monitor->scale / surface->scale);
|
||||
if (!meta_xwayland_is_xwayland_surface (surface))
|
||||
{
|
||||
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
||||
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
||||
(float)monitor->scale / surface->scale);
|
||||
}
|
||||
meta_wayland_surface_update_outputs (surface);
|
||||
}
|
||||
|
||||
@ -927,7 +1061,12 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
|
||||
wl_resource_get_link (cr));
|
||||
|
||||
if (pointer->focus_client == pointer_client)
|
||||
broadcast_focus (pointer, cr);
|
||||
{
|
||||
meta_wayland_pointer_send_enter (pointer, cr,
|
||||
pointer->focus_serial,
|
||||
pointer->focus_surface);
|
||||
meta_wayland_pointer_send_frame (pointer, cr);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -405,3 +405,12 @@ meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
||||
|
||||
return sequence || can_grab_surface;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
|
||||
uint32_t serial)
|
||||
{
|
||||
return (meta_wayland_pointer_can_popup (&seat->pointer, serial) ||
|
||||
meta_wayland_keyboard_can_popup (&seat->keyboard, serial) ||
|
||||
meta_wayland_touch_can_popup (&seat->touch, serial));
|
||||
}
|
||||
|
@ -64,5 +64,7 @@ gboolean meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
||||
uint32_t serial,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
gboolean meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
|
||||
uint32_t serial);
|
||||
|
||||
#endif /* META_WAYLAND_SEAT_H */
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include <wayland-server.h>
|
||||
#include "gtk-shell-server-protocol.h"
|
||||
#include "xdg-shell-server-protocol.h"
|
||||
#include "xdg-shell-unstable-v5-server-protocol.h"
|
||||
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-xwayland-private.h"
|
||||
@ -73,11 +73,8 @@ typedef struct
|
||||
struct wl_listener sibling_destroy_listener;
|
||||
} MetaWaylandSubsurfacePlacementOp;
|
||||
|
||||
GType meta_wayland_surface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
|
||||
|
||||
GType meta_wayland_surface_role_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
|
||||
meta_wayland_surface_role,
|
||||
G_TYPE_OBJECT);
|
||||
@ -87,7 +84,6 @@ struct _MetaWaylandSurfaceRoleSubsurface
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_subsurface_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleSubsurface,
|
||||
meta_wayland_surface_role_subsurface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -97,7 +93,6 @@ struct _MetaWaylandSurfaceRoleXdgSurface
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_xdg_surface_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXdgSurface,
|
||||
meta_wayland_surface_role_xdg_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -107,7 +102,6 @@ struct _MetaWaylandSurfaceRoleXdgPopup
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_xdg_popup_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXdgPopup,
|
||||
meta_wayland_surface_role_xdg_popup,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -117,7 +111,6 @@ struct _MetaWaylandSurfaceRoleWlShellSurface
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_wl_shell_surface_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleWlShellSurface,
|
||||
meta_wayland_surface_role_wl_shell_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -127,7 +120,6 @@ struct _MetaWaylandSurfaceRoleDND
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_dnd_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND,
|
||||
meta_wayland_surface_role_dnd,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -265,8 +257,6 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
|
||||
meta_wayland_data_device_update_dnd_surface (&surface->compositor->seat->data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -359,12 +349,6 @@ toplevel_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (META_IS_WAYLAND_SURFACE_ROLE_XDG_POPUP (surface->role))
|
||||
{
|
||||
/* Ignore commits if we couldn't grab the pointer */
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (surface->buffer == NULL)
|
||||
@ -377,10 +361,11 @@ toplevel_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
/* We resize X based surfaces according to X events */
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
/* Update the state of the MetaWindow if we still have one. We might not if
|
||||
* the window was unmanaged (for example popup destroyed, NULL buffer attached to
|
||||
* wl_shell_surface wl_surface, xdg_surface object was destroyed, etc).
|
||||
*/
|
||||
if (window && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
MetaRectangle geom = { 0 };
|
||||
|
||||
@ -936,7 +921,6 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
|
||||
|
||||
static void
|
||||
surface_handle_output_destroy (MetaWaylandOutput *wayland_output,
|
||||
GParamSpec *pspec,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
set_surface_is_on_output (surface, wayland_output, FALSE);
|
||||
@ -947,22 +931,26 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
|
||||
MetaWaylandOutput *wayland_output,
|
||||
gboolean is_on_output)
|
||||
{
|
||||
gboolean was_on_output = g_hash_table_contains (surface->outputs,
|
||||
wayland_output);
|
||||
gpointer orig_id;
|
||||
gboolean was_on_output = g_hash_table_lookup_extended (surface->outputs_to_destroy_notify_id,
|
||||
wayland_output,
|
||||
NULL, &orig_id);
|
||||
|
||||
if (!was_on_output && is_on_output)
|
||||
{
|
||||
g_signal_connect (wayland_output, "output-destroyed",
|
||||
G_CALLBACK (surface_handle_output_destroy),
|
||||
surface);
|
||||
g_hash_table_add (surface->outputs, wayland_output);
|
||||
gulong id;
|
||||
|
||||
id = g_signal_connect (wayland_output, "output-destroyed",
|
||||
G_CALLBACK (surface_handle_output_destroy),
|
||||
surface);
|
||||
g_hash_table_insert (surface->outputs_to_destroy_notify_id, wayland_output,
|
||||
GSIZE_TO_POINTER ((gsize)id));
|
||||
surface_entered_output (surface, wayland_output);
|
||||
}
|
||||
else if (was_on_output && !is_on_output)
|
||||
{
|
||||
g_hash_table_remove (surface->outputs, wayland_output);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
wayland_output, (gpointer)surface_handle_output_destroy, surface);
|
||||
g_hash_table_remove (surface->outputs_to_destroy_notify_id, wayland_output);
|
||||
g_signal_handler_disconnect (wayland_output, (gulong) GPOINTER_TO_SIZE (orig_id));
|
||||
surface_left_output (surface, wayland_output);
|
||||
}
|
||||
}
|
||||
@ -1000,6 +988,12 @@ update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
|
||||
set_surface_is_on_output (surface, wayland_output, is_on_output);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_output_disconnect_signal (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
g_signal_handler_disconnect (key, (gulong) GPOINTER_TO_SIZE (value));
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
|
||||
{
|
||||
@ -1050,7 +1044,8 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
|
||||
|
||||
g_hash_table_unref (surface->outputs);
|
||||
g_hash_table_foreach (surface->outputs_to_destroy_notify_id, surface_output_disconnect_signal, surface);
|
||||
g_hash_table_unref (surface->outputs_to_destroy_notify_id);
|
||||
|
||||
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
@ -1095,7 +1090,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||||
|
||||
sync_drag_dest_funcs (surface);
|
||||
|
||||
surface->outputs = g_hash_table_new (NULL, NULL);
|
||||
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
|
||||
|
||||
pending_state_init (&surface->pending);
|
||||
return surface;
|
||||
@ -1436,8 +1431,8 @@ handle_popup_parent_destroyed (struct wl_listener *listener, void *data)
|
||||
MetaWaylandSurface *surface =
|
||||
wl_container_of (listener, surface, popup.parent_destroy_listener);
|
||||
|
||||
wl_resource_post_error (surface->xdg_popup,
|
||||
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
wl_resource_post_error (surface->xdg_shell_resource,
|
||||
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"destroyed popup not top most popup");
|
||||
surface->popup.parent = NULL;
|
||||
|
||||
@ -1455,8 +1450,8 @@ handle_popup_destroyed (struct wl_listener *listener, void *data)
|
||||
top_popup = meta_wayland_popup_get_top_popup (popup);
|
||||
if (surface != top_popup)
|
||||
{
|
||||
wl_resource_post_error (surface->xdg_popup,
|
||||
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
wl_resource_post_error (surface->xdg_shell_resource,
|
||||
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"destroyed popup not top most popup");
|
||||
}
|
||||
|
||||
@ -1507,7 +1502,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
(parent_surf->xdg_popup == NULL && parent_surf->xdg_surface == NULL))
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
XDG_POPUP_ERROR_INVALID_PARENT,
|
||||
XDG_SHELL_ERROR_INVALID_POPUP_PARENT,
|
||||
"invalid parent surface");
|
||||
return;
|
||||
}
|
||||
@ -1517,7 +1512,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
(top_popup != NULL && parent_surf != top_popup))
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"parent not top most surface");
|
||||
return;
|
||||
}
|
||||
@ -1529,15 +1524,15 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
surface,
|
||||
xdg_popup_destructor);
|
||||
|
||||
if (!meta_wayland_pointer_can_popup (&seat->pointer, serial))
|
||||
surface->xdg_popup = popup_resource;
|
||||
surface->xdg_shell_resource = resource;
|
||||
|
||||
if (!meta_wayland_seat_can_popup (seat, serial))
|
||||
{
|
||||
xdg_popup_send_popup_done (popup_resource);
|
||||
return;
|
||||
}
|
||||
|
||||
surface->xdg_popup = popup_resource;
|
||||
surface->xdg_shell_resource = resource;
|
||||
|
||||
surface->popup.parent = parent_surf;
|
||||
surface->popup.parent_destroy_listener.notify = handle_popup_parent_destroyed;
|
||||
wl_resource_add_destroy_listener (parent_surf->resource,
|
||||
@ -1753,7 +1748,7 @@ wl_shell_surface_set_popup (struct wl_client *client,
|
||||
|
||||
wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
|
||||
|
||||
if (!meta_wayland_pointer_can_popup (&seat->pointer, serial))
|
||||
if (!meta_wayland_seat_can_popup (seat, serial))
|
||||
{
|
||||
wl_shell_surface_send_popup_done (resource);
|
||||
return;
|
||||
@ -2390,6 +2385,15 @@ meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface)
|
||||
surface->dnd.funcs->drop (data_device, surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
|
||||
|
||||
surface->dnd.funcs->update (data_device, surface);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
|
||||
{
|
||||
|
@ -128,6 +128,8 @@ struct _MetaWaylandDragDestFuncs
|
||||
const ClutterEvent *event);
|
||||
void (* drop) (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandSurface *surface);
|
||||
void (* update) (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandSurface *surface);
|
||||
};
|
||||
|
||||
struct _MetaWaylandSurface
|
||||
@ -147,7 +149,7 @@ struct _MetaWaylandSurface
|
||||
int scale;
|
||||
int32_t offset_x, offset_y;
|
||||
GList *subsurfaces;
|
||||
GHashTable *outputs;
|
||||
GHashTable *outputs_to_destroy_notify_id;
|
||||
|
||||
/* List of pending frame callbacks that needs to stay queued longer than one
|
||||
* commit sequence, such as when it has not yet been assigned a role.
|
||||
@ -240,6 +242,7 @@ void meta_wayland_surface_drag_dest_motion (MetaWaylandSurface
|
||||
const ClutterEvent *event);
|
||||
void meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_update_outputs (MetaWaylandSurface *surface);
|
||||
|
||||
|
@ -208,8 +208,8 @@ touch_get_relative_coordinates (MetaWaylandTouch *touch,
|
||||
&event_x, &event_y);
|
||||
}
|
||||
|
||||
*x = event_x;
|
||||
*y = event_y;
|
||||
*x = event_x / surface->scale;
|
||||
*y = event_y / surface->scale;
|
||||
}
|
||||
|
||||
|
||||
@ -575,6 +575,26 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_touch_can_popup (MetaWaylandTouch *touch,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
GHashTableIter iter;
|
||||
|
||||
if (!touch->touches)
|
||||
return FALSE;
|
||||
|
||||
g_hash_table_iter_init (&iter, touch->touches);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info))
|
||||
{
|
||||
if (touch_info->slot_serial == serial)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ClutterEventSequence *
|
||||
meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch,
|
||||
MetaWaylandSurface *surface,
|
||||
|
@ -70,4 +70,7 @@ gboolean meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
gboolean meta_wayland_touch_can_popup (MetaWaylandTouch *touch,
|
||||
uint32_t serial);
|
||||
|
||||
#endif /* META_WAYLAND_TOUCH_H */
|
||||
|
@ -29,6 +29,8 @@ typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface;
|
||||
typedef struct _MetaWaylandPopupGrab MetaWaylandPopupGrab;
|
||||
typedef struct _MetaWaylandPopup MetaWaylandPopup;
|
||||
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
|
||||
typedef struct _MetaWaylandKeyboardGrab MetaWaylandKeyboardGrab;
|
||||
typedef struct _MetaWaylandKeyboardGrabInterface MetaWaylandKeyboardGrabInterface;
|
||||
typedef struct _MetaWaylandTouch MetaWaylandTouch;
|
||||
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
|
||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
||||
|
@ -36,14 +36,14 @@
|
||||
|
||||
/* Global/master objects (version exported by wl_registry and negotiated through bind) */
|
||||
#define META_WL_COMPOSITOR_VERSION 3
|
||||
#define META_WL_DATA_DEVICE_MANAGER_VERSION 2
|
||||
#define META_WL_DATA_DEVICE_MANAGER_VERSION 3
|
||||
#define META_XDG_SHELL_VERSION 1
|
||||
#define META_WL_SHELL_VERSION 1
|
||||
#define META_WL_SEAT_VERSION 4
|
||||
#define META_WL_SEAT_VERSION 5
|
||||
#define META_WL_OUTPUT_VERSION 2
|
||||
#define META_XSERVER_VERSION 1
|
||||
#define META_GTK_SHELL_VERSION 2
|
||||
#define META_WL_SUBCOMPOSITOR_VERSION 1
|
||||
#define META__WL_POINTER_GESTURES_VERSION 1
|
||||
#define META_ZWP_POINTER_GESTURES_V1_VERSION 1
|
||||
|
||||
#endif
|
||||
|
@ -144,7 +144,7 @@ wl_compositor_create_region (struct wl_client *client,
|
||||
meta_wayland_region_create (compositor, client, resource, id);
|
||||
}
|
||||
|
||||
const static struct wl_compositor_interface meta_wayland_wl_compositor_interface = {
|
||||
static const struct wl_compositor_interface meta_wayland_wl_compositor_interface = {
|
||||
wl_compositor_create_surface,
|
||||
wl_compositor_create_region
|
||||
};
|
||||
@ -272,6 +272,8 @@ set_gnome_env (const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
static void meta_wayland_log_func (const char *, va_list) G_GNUC_PRINTF (1, 0);
|
||||
|
||||
static void
|
||||
meta_wayland_log_func (const char *fmt,
|
||||
va_list arg)
|
||||
@ -335,13 +337,13 @@ meta_wayland_init (void)
|
||||
meta_wayland_pointer_gestures_init (compositor);
|
||||
meta_wayland_seat_init (compositor);
|
||||
|
||||
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
||||
g_error ("Failed to start X Wayland");
|
||||
|
||||
compositor->display_name = wl_display_add_socket_auto (compositor->wayland_display);
|
||||
if (compositor->display_name == NULL)
|
||||
g_error ("Failed to create socket");
|
||||
|
||||
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
||||
g_error ("Failed to start X Wayland");
|
||||
|
||||
set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
|
||||
set_gnome_env ("WAYLAND_DISPLAY", meta_wayland_get_wayland_display_name (compositor));
|
||||
}
|
||||
|
@ -361,6 +361,8 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
||||
|
||||
/* Window size. */
|
||||
scale_rect_size (&window->rect, scale_factor);
|
||||
scale_rect_size (&window->unconstrained_rect, scale_factor);
|
||||
scale_rect_size (&window->saved_rect, scale_factor);
|
||||
|
||||
/* Window geometry offset (XXX: Need a better place, see
|
||||
* meta_window_wayland_move_resize). */
|
||||
|
@ -39,8 +39,6 @@
|
||||
#include "meta-xwayland-selection-private.h"
|
||||
#include "meta-wayland-data-device.h"
|
||||
|
||||
GType meta_wayland_data_source_xwayland_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#define INCR_CHUNK_SIZE (128 * 1024)
|
||||
#define XDND_VERSION 5
|
||||
|
||||
@ -88,6 +86,7 @@ struct _MetaWaylandDataSourceXWayland
|
||||
MetaWaylandDataSource parent;
|
||||
|
||||
MetaSelectionBridge *selection;
|
||||
guint has_utf8_string_atom : 1;
|
||||
};
|
||||
|
||||
struct _MetaXWaylandSelection {
|
||||
@ -109,6 +108,7 @@ enum {
|
||||
ATOM_DND_ACTION_MOVE,
|
||||
ATOM_DND_ACTION_COPY,
|
||||
ATOM_DND_ACTION_ASK,
|
||||
ATOM_DND_ACTION_PRIVATE,
|
||||
N_DND_ATOMS
|
||||
};
|
||||
|
||||
@ -127,6 +127,7 @@ const gchar *atom_names[] = {
|
||||
"XdndActionMove",
|
||||
"XdndActionCopy",
|
||||
"XdndActionAsk",
|
||||
"XdndActionPrivate",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -136,6 +137,33 @@ G_DEFINE_TYPE (MetaWaylandDataSourceXWayland, meta_wayland_data_source_xwayland,
|
||||
META_TYPE_WAYLAND_DATA_SOURCE);
|
||||
|
||||
/* XDND helpers */
|
||||
static Atom
|
||||
action_to_atom (uint32_t action)
|
||||
{
|
||||
if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||
return xdnd_atoms[ATOM_DND_ACTION_COPY];
|
||||
else if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
return xdnd_atoms[ATOM_DND_ACTION_MOVE];
|
||||
else if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
return xdnd_atoms[ATOM_DND_ACTION_ASK];
|
||||
else
|
||||
return None;
|
||||
}
|
||||
|
||||
static enum wl_data_device_manager_dnd_action
|
||||
atom_to_action (Atom atom)
|
||||
{
|
||||
if (atom == xdnd_atoms[ATOM_DND_ACTION_COPY] ||
|
||||
atom == xdnd_atoms[ATOM_DND_ACTION_PRIVATE])
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
else if (atom == xdnd_atoms[ATOM_DND_ACTION_MOVE])
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
else if (atom == xdnd_atoms[ATOM_DND_ACTION_ASK])
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
else
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
xdnd_send_enter (MetaXWaylandSelection *selection_data,
|
||||
Window dest)
|
||||
@ -162,7 +190,6 @@ xdnd_send_enter (MetaXWaylandSelection *selection_data,
|
||||
if (source_mime_types->size <= 3)
|
||||
{
|
||||
/* The mimetype atoms fit in this same message */
|
||||
gchar **p;
|
||||
gint i = 2;
|
||||
|
||||
wl_array_for_each (p, source_mime_types)
|
||||
@ -219,10 +246,21 @@ xdnd_send_position (MetaXWaylandSelection *selection_data,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaSelectionBridge *selection = &selection_data->dnd.selection;
|
||||
MetaWaylandDataSource *source = compositor->seat->data_device.dnd_data_source;
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
uint32_t action = 0, user_action, actions;
|
||||
XEvent xev = { 0 };
|
||||
|
||||
user_action = meta_wayland_data_source_get_user_action (source);
|
||||
actions = meta_wayland_data_source_get_actions (source);
|
||||
|
||||
if (user_action & actions)
|
||||
action = user_action;
|
||||
if (!action)
|
||||
action = actions;
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.message_type = xdnd_atoms[ATOM_DND_POSITION];
|
||||
xev.xclient.format = 32;
|
||||
@ -232,7 +270,7 @@ xdnd_send_position (MetaXWaylandSelection *selection_data,
|
||||
xev.xclient.data.l[1] = 0;
|
||||
xev.xclient.data.l[2] = (x << 16) | y;
|
||||
xev.xclient.data.l[3] = time;
|
||||
xev.xclient.data.l[4] = xdnd_atoms[ATOM_DND_ACTION_COPY];
|
||||
xev.xclient.data.l[4] = action_to_atom (action);
|
||||
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
}
|
||||
@ -264,6 +302,8 @@ xdnd_send_finished (MetaXWaylandSelection *selection_data,
|
||||
{
|
||||
MetaDndBridge *selection = &selection_data->dnd;
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
MetaWaylandDataSource *source = selection_data->dnd.selection.source;
|
||||
uint32_t action = 0;
|
||||
XEvent xev = { 0 };
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
@ -275,8 +315,9 @@ xdnd_send_finished (MetaXWaylandSelection *selection_data,
|
||||
|
||||
if (accepted)
|
||||
{
|
||||
action = meta_wayland_data_source_get_current_action (source);
|
||||
xev.xclient.data.l[1] = 1; /* Drop successful */
|
||||
xev.xclient.data.l[2] = xdnd_atoms[ATOM_DND_ACTION_COPY];
|
||||
xev.xclient.data.l[2] = action_to_atom (action);
|
||||
}
|
||||
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
@ -285,7 +326,7 @@ xdnd_send_finished (MetaXWaylandSelection *selection_data,
|
||||
static void
|
||||
xdnd_send_status (MetaXWaylandSelection *selection_data,
|
||||
Window dest,
|
||||
gboolean accepted)
|
||||
uint32_t action)
|
||||
{
|
||||
MetaDndBridge *selection = &selection_data->dnd;
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
@ -298,12 +339,10 @@ xdnd_send_status (MetaXWaylandSelection *selection_data,
|
||||
|
||||
xev.xclient.data.l[0] = selection->dnd_window;
|
||||
xev.xclient.data.l[1] = 1 << 1; /* Bit 2: dest wants XdndPosition messages */
|
||||
xev.xclient.data.l[4] = action_to_atom (action);
|
||||
|
||||
if (accepted)
|
||||
{
|
||||
xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */
|
||||
xev.xclient.data.l[4] = xdnd_atoms[ATOM_DND_ACTION_COPY];
|
||||
}
|
||||
if (xev.xclient.data.l[4])
|
||||
xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */
|
||||
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
}
|
||||
@ -389,6 +428,32 @@ x11_selection_data_free (X11SelectionData *data)
|
||||
g_slice_free (X11SelectionData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_selection_data_send_finished (MetaSelectionBridge *selection,
|
||||
gboolean success)
|
||||
{
|
||||
uint32_t action = meta_wayland_data_source_get_current_action (selection->source);
|
||||
|
||||
if (!selection->x11_selection)
|
||||
return;
|
||||
|
||||
if (success && action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
{
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
/* Request data deletion on the drag source */
|
||||
XConvertSelection (xdisplay,
|
||||
selection->selection_atom,
|
||||
gdk_x11_get_xatom_by_name ("DELETE"),
|
||||
gdk_x11_get_xatom_by_name ("_META_SELECTION"),
|
||||
selection->window,
|
||||
CurrentTime);
|
||||
}
|
||||
|
||||
xdnd_send_finished (selection->x11_selection->selection_data,
|
||||
selection->owner, success);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_selection_data_finish (MetaSelectionBridge *selection,
|
||||
gboolean success)
|
||||
@ -397,13 +462,18 @@ x11_selection_data_finish (MetaSelectionBridge *selection,
|
||||
return;
|
||||
|
||||
if (selection == &selection->x11_selection->selection_data->dnd.selection)
|
||||
xdnd_send_finished (selection->x11_selection->selection_data,
|
||||
selection->owner, success);
|
||||
x11_selection_data_send_finished (selection, success);
|
||||
|
||||
g_clear_pointer (&selection->x11_selection,
|
||||
(GDestroyNotify) x11_selection_data_free);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_selection_data_close (X11SelectionData *data)
|
||||
{
|
||||
g_output_stream_close (data->stream, data->cancellable, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_data_write_cb (GObject *object,
|
||||
GAsyncResult *res,
|
||||
@ -412,27 +482,34 @@ x11_data_write_cb (GObject *object,
|
||||
MetaSelectionBridge *selection = user_data;
|
||||
X11SelectionData *data = selection->x11_selection;
|
||||
GError *error = NULL;
|
||||
gboolean success = TRUE;
|
||||
|
||||
g_output_stream_write_finish (G_OUTPUT_STREAM (object), res, &error);
|
||||
|
||||
if (data->incr)
|
||||
if (error)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_warning ("Error writing from X11 selection: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (success && data->incr)
|
||||
{
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
XDeleteProperty (xdisplay, selection->window,
|
||||
gdk_x11_get_xatom_by_name ("_META_SELECTION"));
|
||||
}
|
||||
|
||||
if (error)
|
||||
else
|
||||
{
|
||||
if (error->domain != G_IO_ERROR ||
|
||||
error->code != G_IO_ERROR_CANCELLED)
|
||||
g_warning ("Error writing from X11 selection: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
x11_selection_data_close (selection->x11_selection);
|
||||
x11_selection_data_finish (selection, success);
|
||||
}
|
||||
|
||||
if (!data->incr)
|
||||
x11_selection_data_finish (selection, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -689,6 +766,7 @@ meta_xwayland_selection_get_incr_chunk (MetaWaylandCompositor *compositor,
|
||||
else
|
||||
{
|
||||
/* Transfer has completed */
|
||||
x11_selection_data_close (selection->x11_selection);
|
||||
x11_selection_data_finish (selection, TRUE);
|
||||
}
|
||||
|
||||
@ -707,7 +785,8 @@ meta_x11_source_send (MetaWaylandDataSource *source,
|
||||
MetaSelectionBridge *selection = source_xwayland->selection;
|
||||
Atom type_atom;
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
if (source_xwayland->has_utf8_string_atom &&
|
||||
strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
type_atom = gdk_x11_get_xatom_by_name ("UTF8_STRING");
|
||||
else
|
||||
type_atom = gdk_x11_get_xatom_by_name (mime_type);
|
||||
@ -736,11 +815,15 @@ meta_x11_source_target (MetaWaylandDataSource *source,
|
||||
MetaWaylandDataSourceXWayland *source_xwayland =
|
||||
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
|
||||
MetaSelectionBridge *selection = source_xwayland->selection;
|
||||
uint32_t action = 0;
|
||||
|
||||
if (selection->selection_atom == xdnd_atoms[ATOM_DND_SELECTION])
|
||||
{
|
||||
if (mime_type)
|
||||
action = meta_wayland_data_source_get_current_action (source);
|
||||
|
||||
xdnd_send_status (compositor->xwayland_manager.selection_data,
|
||||
selection->owner, mime_type != NULL);
|
||||
selection->owner, action);
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,10 +834,46 @@ meta_x11_source_cancel (MetaWaylandDataSource *source)
|
||||
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
|
||||
MetaSelectionBridge *selection = source_xwayland->selection;
|
||||
|
||||
x11_selection_data_send_finished (selection, FALSE);
|
||||
g_clear_pointer (&selection->x11_selection,
|
||||
(GDestroyNotify) x11_selection_data_free);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_x11_source_action (MetaWaylandDataSource *source,
|
||||
uint32_t action)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandDataSourceXWayland *source_xwayland =
|
||||
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
|
||||
MetaSelectionBridge *selection = source_xwayland->selection;
|
||||
|
||||
if (selection->selection_atom == xdnd_atoms[ATOM_DND_SELECTION])
|
||||
{
|
||||
if (!meta_wayland_data_source_has_target (source))
|
||||
action = 0;
|
||||
|
||||
xdnd_send_status (compositor->xwayland_manager.selection_data,
|
||||
selection->owner, action);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_x11_source_drop_performed (MetaWaylandDataSource *source)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_x11_source_drag_finished (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourceXWayland *source_xwayland =
|
||||
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
|
||||
MetaSelectionBridge *selection = source_xwayland->selection;
|
||||
|
||||
if (selection->x11_selection)
|
||||
x11_selection_data_send_finished (selection, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_xwayland_init (MetaWaylandDataSourceXWayland *source_xwayland)
|
||||
{
|
||||
@ -769,6 +888,9 @@ meta_wayland_data_source_xwayland_class_init (MetaWaylandDataSourceXWaylandClass
|
||||
data_source_class->send = meta_x11_source_send;
|
||||
data_source_class->target = meta_x11_source_target;
|
||||
data_source_class->cancel = meta_x11_source_cancel;
|
||||
data_source_class->action = meta_x11_source_action;
|
||||
data_source_class->drop_performed = meta_x11_source_drop_performed;
|
||||
data_source_class->drag_finished = meta_x11_source_drag_finished;
|
||||
}
|
||||
|
||||
static MetaWaylandDataSource *
|
||||
@ -832,11 +954,27 @@ meta_x11_drag_dest_drop (MetaWaylandDataDevice *data_device,
|
||||
meta_display_get_current_time_roundtrip (meta_get_display ()));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_x11_drag_dest_update (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandSeat *seat = compositor->seat;
|
||||
ClutterPoint pos;
|
||||
|
||||
clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
|
||||
xdnd_send_position (compositor->xwayland_manager.selection_data,
|
||||
compositor->xwayland_manager.selection_data->dnd.dnd_dest,
|
||||
clutter_get_current_event_time (),
|
||||
pos.x, pos.y);
|
||||
}
|
||||
|
||||
static const MetaWaylandDragDestFuncs meta_x11_drag_dest_funcs = {
|
||||
meta_x11_drag_dest_focus_in,
|
||||
meta_x11_drag_dest_focus_out,
|
||||
meta_x11_drag_dest_motion,
|
||||
meta_x11_drag_dest_drop
|
||||
meta_x11_drag_dest_drop,
|
||||
meta_x11_drag_dest_update
|
||||
};
|
||||
|
||||
const MetaWaylandDragDestFuncs *
|
||||
@ -850,6 +988,8 @@ meta_xwayland_data_source_fetch_mimetype_list (MetaWaylandDataSource *source,
|
||||
Window window,
|
||||
Atom prop)
|
||||
{
|
||||
MetaWaylandDataSourceXWayland *source_xwayland =
|
||||
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
gulong nitems_ret, bytes_after_ret, i;
|
||||
Atom *atoms, type_ret, utf8_string;
|
||||
@ -883,10 +1023,13 @@ meta_xwayland_data_source_fetch_mimetype_list (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type;
|
||||
|
||||
if (atoms[i] == utf8_string)
|
||||
mime_type = "text/plain;charset=utf-8";
|
||||
else
|
||||
mime_type = gdk_x11_get_xatom_name (atoms[i]);
|
||||
{
|
||||
meta_wayland_data_source_add_mime_type (source,
|
||||
"text/plain;charset=utf-8");
|
||||
source_xwayland->has_utf8_string_atom = TRUE;
|
||||
}
|
||||
|
||||
mime_type = gdk_x11_get_xatom_name (atoms[i]);
|
||||
meta_wayland_data_source_add_mime_type (source, mime_type);
|
||||
}
|
||||
|
||||
@ -1125,6 +1268,10 @@ meta_xwayland_selection_handle_selection_request (MetaWaylandCompositor *composi
|
||||
selection->timestamp);
|
||||
reply_selection_request (event, TRUE);
|
||||
}
|
||||
else if (data_source && event->target == gdk_x11_get_xatom_by_name ("DELETE"))
|
||||
{
|
||||
reply_selection_request (event, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data_source &&
|
||||
@ -1247,6 +1394,7 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
|
||||
if (event->window == dnd->selection.window)
|
||||
{
|
||||
MetaWaylandDataSource *data_source;
|
||||
uint32_t action = 0;
|
||||
|
||||
data_source = compositor->seat->data_device.dnd_data_source;
|
||||
|
||||
@ -1259,6 +1407,11 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
|
||||
meta_wayland_data_source_set_has_target (data_source,
|
||||
(event->data.l[1] & 1) != 0);
|
||||
|
||||
/* data.l[4] contains the action atom */
|
||||
if (event->data.l[4])
|
||||
action = atom_to_action ((Atom) event->data.l[4]);
|
||||
|
||||
meta_wayland_data_source_set_current_action (data_source, action);
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->message_type == xdnd_atoms[ATOM_DND_FINISHED])
|
||||
@ -1267,8 +1420,7 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
|
||||
if (compositor->seat->data_device.current_grab)
|
||||
return FALSE;
|
||||
|
||||
meta_wayland_data_device_set_dnd_source (&compositor->seat->data_device,
|
||||
NULL);
|
||||
meta_wayland_data_source_notify_finish (data_source);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -1280,6 +1432,10 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
|
||||
MetaWaylandDragGrab *drag_grab = compositor->seat->data_device.current_grab;
|
||||
MetaWaylandSurface *drag_focus = meta_wayland_drag_grab_get_focus (drag_grab);
|
||||
|
||||
if (!drag_focus &&
|
||||
event->message_type != xdnd_atoms[ATOM_DND_ENTER])
|
||||
return FALSE;
|
||||
|
||||
if (event->message_type == xdnd_atoms[ATOM_DND_ENTER])
|
||||
{
|
||||
/* Bit 1 in data.l[1] determines whether there's 3 or less mimetype
|
||||
@ -1325,6 +1481,7 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
|
||||
{
|
||||
ClutterEvent *motion;
|
||||
ClutterPoint pos;
|
||||
uint32_t action = 0;
|
||||
|
||||
motion = clutter_event_new (CLUTTER_MOTION);
|
||||
clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
|
||||
@ -1333,11 +1490,13 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
|
||||
clutter_event_set_source_device (motion, seat->pointer.device);
|
||||
clutter_event_set_time (motion, dnd->last_motion_time);
|
||||
|
||||
action = atom_to_action ((Atom) event->data.l[4]);
|
||||
meta_wayland_data_source_set_actions (dnd->selection.source, action);
|
||||
|
||||
meta_wayland_surface_drag_dest_motion (drag_focus, motion);
|
||||
xdnd_send_status (compositor->xwayland_manager.selection_data,
|
||||
(Window) event->data.l[0],
|
||||
meta_wayland_data_source_has_target (
|
||||
dnd->selection.source));
|
||||
meta_wayland_data_source_get_current_action (dnd->selection.source));
|
||||
|
||||
clutter_event_free (motion);
|
||||
return TRUE;
|
||||
|
@ -45,7 +45,6 @@ struct _MetaWaylandSurfaceRoleXWayland
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_xwayland_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
meta_wayland_surface_role_xwayland,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
@ -56,13 +55,6 @@ associate_window_with_surface (MetaWindow *window,
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
|
||||
/* If the window has an existing surface, like if we're
|
||||
* undecorating or decorating the window, then we need
|
||||
* to detach the window from its old surface.
|
||||
*/
|
||||
if (window->surface)
|
||||
window->surface->window = NULL;
|
||||
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND))
|
||||
{
|
||||
@ -89,6 +81,16 @@ associate_window_with_surface_id (MetaXWaylandManager *manager,
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
/* If the window has an existing surface, like if we're
|
||||
* undecorating or decorating the window, then we need
|
||||
* to detach the window from its old surface.
|
||||
*/
|
||||
if (window->surface)
|
||||
{
|
||||
meta_wayland_surface_set_window (window->surface, NULL);
|
||||
window->surface = NULL;
|
||||
}
|
||||
|
||||
resource = wl_client_get_object (manager->client, surface_id);
|
||||
if (resource)
|
||||
{
|
||||
@ -172,6 +174,15 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaXWaylandManager *manager = &compositor->xwayland_manager;
|
||||
|
||||
return wl_resource_get_client (surface->resource) == manager->client;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
try_display (int display,
|
||||
char **filename_out,
|
||||
|
@ -28,8 +28,13 @@
|
||||
#include <glib.h>
|
||||
#include <meta/types.h>
|
||||
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
void
|
||||
meta_xwayland_handle_wl_surface_id (MetaWindow *window,
|
||||
guint32 surface_id);
|
||||
|
||||
gboolean
|
||||
meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface);
|
||||
|
||||
#endif /* META_XWAYLAND_H */
|
||||
|
@ -1,176 +0,0 @@
|
||||
<protocol name="pointer_gestures">
|
||||
<interface name="_wl_pointer_gestures" version="1">
|
||||
<description summary="touchpad gestures">
|
||||
A global interface to provide semantic touchpad gestures for a given
|
||||
pointer.
|
||||
|
||||
Two gestures are currently supported: swipe and zoom/rotate.
|
||||
All gestures follow a three-stage cycle: begin, update, end and
|
||||
are identified by a unique id.
|
||||
|
||||
Warning! The protocol described in this file is experimental. Each
|
||||
version of this protocol should be considered incompatible with any
|
||||
other version, and a client binding to a version different to the one
|
||||
advertised will be terminated. Once the protocol is declared stable,
|
||||
compatibility is guaranteed, the '_' prefix will be removed from the
|
||||
name and the version will be reset to 1.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="version_mismatch" value="0"/>
|
||||
</enum>
|
||||
|
||||
<request name="get_swipe_gesture">
|
||||
<description summary="get swipe gesture">
|
||||
Create a swipe gesture object. See the
|
||||
wl_pointer_gesture_swipe interface for details.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="_wl_pointer_gesture_swipe"/>
|
||||
<arg name="pointer" type="object" interface="wl_pointer"/>
|
||||
</request>
|
||||
|
||||
<request name="get_pinch_gesture">
|
||||
<description summary="get pinch gesture">
|
||||
Create a pinch gesture object. See the
|
||||
wl_pointer_gesture_pinch interface for details.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="_wl_pointer_gesture_pinch"/>
|
||||
<arg name="pointer" type="object" interface="wl_pointer"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="_wl_pointer_gesture_swipe" version="1">
|
||||
<description summary="a swipe gesture object">
|
||||
A swipe gesture object notifies a client about a multi-finger swipe
|
||||
gesture detected on an indirect input device such as a touchpad.
|
||||
The gesture is usually initiated by multiple fingers moving in the
|
||||
same direction but once initiated the direction may change.
|
||||
The precise conditions of when such a gesture is detected are
|
||||
implementation-dependent.
|
||||
|
||||
A gesture consists of three stages: begin, update (optional) and end.
|
||||
There cannot be multiple simultaneous pinch or swipe gestures on a
|
||||
same pointer/seat, how compositors prevent these situations is
|
||||
implementation-dependent.
|
||||
|
||||
A gesture may be cancelled by the compositor or the hardware.
|
||||
Clients should not consider performing permanent or irreversible
|
||||
actions until the end of a gesture has been received.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the pointer swipe gesture object"/>
|
||||
</request>
|
||||
|
||||
<event name="begin">
|
||||
<description summary="multi-finger swipe begin">
|
||||
This event is sent when a multi-finger swipe gesture is detected
|
||||
on the device.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="fingers" type="uint" summary="number of fingers"/>
|
||||
</event>
|
||||
|
||||
<event name="update">
|
||||
<description summary="multi-finger swipe motion">
|
||||
This event is sent when a multi-finger swipe gesture changes the
|
||||
position of the logical center.
|
||||
|
||||
The dx and dy coordinates are relative coordinates of the logical
|
||||
center of the gesture compared to the previous event.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/>
|
||||
<arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/>
|
||||
</event>
|
||||
|
||||
<event name="end">
|
||||
<description summary="multi-finger swipe end">
|
||||
This event is sent when a multi-finger swipe gesture ceases to
|
||||
be valid. This may happen when one or more finger is lifted or
|
||||
the gesture is cancelled.
|
||||
|
||||
When a gesture is cancelled, the client should undo state changes
|
||||
caused by this gesture. What causes a gesture to be cancelled is
|
||||
implementation-dependent.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="_wl_pointer_gesture_pinch" version="1">
|
||||
<description summary="a pinch gesture object">
|
||||
A pinch gesture object notifies a client about a multi-finger pinch
|
||||
gesture detected on an indirect input device such as a touchpad.
|
||||
The gesture is usually initiated by multiple fingers moving towards
|
||||
each other or away from each other, or by two or more fingers rotating
|
||||
around a logical center of gravity. The precise conditions of when
|
||||
such a gesture is detected are implementation-dependent.
|
||||
|
||||
A gesture consists of three stages: begin, update (optional) and end.
|
||||
There cannot be multiple simultaneous pinch or swipe gestures on a
|
||||
same pointer/seat, how compositors prevent these situations is
|
||||
implementation-dependent.
|
||||
|
||||
A gesture may be cancelled by the compositor or the hardware.
|
||||
Clients should not consider performing permanent or irreversible
|
||||
actions until the end of a gesture has been received.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the pinch gesture object"/>
|
||||
</request>
|
||||
|
||||
<event name="begin">
|
||||
<description summary="multi-finger pinch begin">
|
||||
This event is sent when a multi-finger pinch gesture is detected
|
||||
on the device.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="fingers" type="uint" summary="number of fingers"/>
|
||||
</event>
|
||||
|
||||
<event name="update">
|
||||
<description summary="multi-finger pinch motion">
|
||||
This event is sent when a multi-finger pinch gesture changes the
|
||||
position of the logical center, the rotation or the relative scale.
|
||||
|
||||
The dx and dy coordinates are relative coordinates in the
|
||||
surface coordinate space of the logical center of the gesture.
|
||||
|
||||
The scale factor is an absolute scale compared to the
|
||||
pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers
|
||||
are now twice as far apart as on pointer_gesture_pinch.begin.
|
||||
|
||||
The rotation is the relative angle in degrees clockwise compared to the previous
|
||||
pointer_gesture_pinch.begin or pointer_gesture_pinch.update event.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/>
|
||||
<arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/>
|
||||
<arg name="scale" type="fixed" summary="scale relative to the initial finger position"/>
|
||||
<arg name="rotation" type="fixed" summary="angle in degrees cw relative to the previous event"/>
|
||||
</event>
|
||||
|
||||
<event name="end">
|
||||
<description summary="multi-finger pinch end">
|
||||
This event is sent when a multi-finger pinch gesture ceases to
|
||||
be valid. This may happen when one or more finger is lifted or
|
||||
the gesture is cancelled.
|
||||
|
||||
When a gesture is cancelled, the client should undo state changes
|
||||
caused by this gesture. What causes a gesture to be cancelled is
|
||||
implementation-dependent.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
@ -1,485 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_shell">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2008-2013 Kristian Høgsberg
|
||||
Copyright © 2013 Rafael Antognolli
|
||||
Copyright © 2013 Jasper St. Pierre
|
||||
Copyright © 2010-2013 Intel Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="xdg_shell" version="1">
|
||||
<description summary="create desktop-style surfaces">
|
||||
xdg_shell allows clients to turn a wl_surface into a "real window"
|
||||
which can be dragged, resized, stacked, and moved around by the
|
||||
user. Everything about this interface is suited towards traditional
|
||||
desktop environments.
|
||||
</description>
|
||||
|
||||
<enum name="version">
|
||||
<description summary="latest protocol version">
|
||||
The 'current' member of this enum gives the version of the
|
||||
protocol. Implementations can compare this to the version
|
||||
they implement using static_assert to ensure the protocol and
|
||||
implementation versions match.
|
||||
</description>
|
||||
<entry name="current" value="5" summary="Always the latest version"/>
|
||||
</enum>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="role" value="0" summary="given wl_surface has another role"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy xdg_shell">
|
||||
Destroy this xdg_shell object.
|
||||
|
||||
Destroying a bound xdg_shell object while there are surfaces
|
||||
still alive with roles from this interface is illegal and will
|
||||
result in a protocol error. Make sure to destroy all surfaces
|
||||
before destroying this object.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="use_unstable_version">
|
||||
<description summary="enable use of this unstable version">
|
||||
Negotiate the unstable version of the interface. This
|
||||
mechanism is in place to ensure client and server agree on the
|
||||
unstable versions of the protocol that they speak or exit
|
||||
cleanly if they don't agree. This request will go away once
|
||||
the xdg-shell protocol is stable.
|
||||
</description>
|
||||
<arg name="version" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="get_xdg_surface">
|
||||
<description summary="create a shell surface from a surface">
|
||||
This creates an xdg_surface for the given surface and gives it the
|
||||
xdg_surface role. See the documentation of xdg_surface for more details.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_surface"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
</request>
|
||||
|
||||
<request name="get_xdg_popup">
|
||||
<description summary="create a popup for a surface">
|
||||
This creates an xdg_popup for the given surface and gives it the
|
||||
xdg_popup role. See the documentation of xdg_popup for more details.
|
||||
|
||||
This request must be used in response to some sort of user action
|
||||
like a button press, key press, or touch down event.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_popup"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="parent" type="object" interface="wl_surface"/>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
||||
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
</request>
|
||||
|
||||
<event name="ping">
|
||||
<description summary="check if the client is alive">
|
||||
The ping event asks the client if it's still alive. Pass the
|
||||
serial specified in the event back to the compositor by sending
|
||||
a "pong" request back with the specified serial.
|
||||
|
||||
Compositors can use this to determine if the client is still
|
||||
alive. It's unspecified what will happen if the client doesn't
|
||||
respond to the ping request, or in what timeframe. Clients should
|
||||
try to respond in a reasonable amount of time.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="pass this to the pong request"/>
|
||||
</event>
|
||||
|
||||
<request name="pong">
|
||||
<description summary="respond to a ping event">
|
||||
A client must respond to a ping event with a pong request or
|
||||
the client may be deemed unresponsive.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial of the ping event"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_surface" version="1">
|
||||
<description summary="A desktop window">
|
||||
An interface that may be implemented by a wl_surface, for
|
||||
implementations that provide a desktop-style user interface.
|
||||
|
||||
It provides requests to treat surfaces like windows, allowing to set
|
||||
properties like maximized, fullscreen, minimized, and to move and resize
|
||||
them, and associate metadata like title and app id.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="Destroy the xdg_surface">
|
||||
Unmap and destroy the window. The window will be effectively
|
||||
hidden from the user's point of view, and all state like
|
||||
maximization, fullscreen, and so on, will be lost.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_parent">
|
||||
<description summary="set the parent of this surface">
|
||||
Set the "parent" of this surface. This window should be stacked
|
||||
above a parent. The parent surface must be mapped as long as this
|
||||
surface is mapped.
|
||||
|
||||
Parent windows should be set on dialogs, toolboxes, or other
|
||||
"auxilliary" surfaces, so that the parent is raised when the dialog
|
||||
is raised.
|
||||
</description>
|
||||
<arg name="parent" type="object" interface="xdg_surface" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<request name="set_title">
|
||||
<description summary="set surface title">
|
||||
Set a short title for the surface.
|
||||
|
||||
This string may be used to identify the surface in a task bar,
|
||||
window list, or other user interface elements provided by the
|
||||
compositor.
|
||||
|
||||
The string must be encoded in UTF-8.
|
||||
</description>
|
||||
<arg name="title" type="string"/>
|
||||
</request>
|
||||
|
||||
<request name="set_app_id">
|
||||
<description summary="set application ID">
|
||||
Set an application identifier for the surface.
|
||||
|
||||
The app ID identifies the general class of applications to which
|
||||
the surface belongs. The compositor can use this to group multiple
|
||||
applications together, or to determine how to launch a new
|
||||
application.
|
||||
|
||||
See the desktop-entry specification [0] for more details on
|
||||
application identifiers and how they relate to well-known DBus
|
||||
names and .desktop files.
|
||||
|
||||
[0] http://standards.freedesktop.org/desktop-entry-spec/
|
||||
</description>
|
||||
<arg name="app_id" type="string"/>
|
||||
</request>
|
||||
|
||||
<request name="show_window_menu">
|
||||
<description summary="show the window menu">
|
||||
Clients implementing client-side decorations might want to show
|
||||
a context menu when right-clicking on the decorations, giving the
|
||||
user a menu that they can use to maximize or minimize the window.
|
||||
|
||||
This request asks the compositor to pop up such a window menu at
|
||||
the given position, relative to the local surface coordinates of
|
||||
the parent surface. There are no guarantees as to what menu items
|
||||
the window menu contains.
|
||||
|
||||
This request must be used in response to some sort of user action
|
||||
like a button press, key press, or touch down event.
|
||||
</description>
|
||||
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
||||
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
||||
<arg name="x" type="int" summary="the x position to pop up the window menu at"/>
|
||||
<arg name="y" type="int" summary="the y position to pop up the window menu at"/>
|
||||
</request>
|
||||
|
||||
<request name="move">
|
||||
<description summary="start an interactive move">
|
||||
Start an interactive, user-driven move of the surface.
|
||||
|
||||
This request must be used in response to some sort of user action
|
||||
like a button press, key press, or touch down event.
|
||||
|
||||
The server may ignore move requests depending on the state of
|
||||
the surface (e.g. fullscreen or maximized).
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
||||
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
||||
</request>
|
||||
|
||||
<enum name="resize_edge">
|
||||
<description summary="edge values for resizing">
|
||||
These values are used to indicate which edge of a surface
|
||||
is being dragged in a resize operation. The server may
|
||||
use this information to adapt its behavior, e.g. choose
|
||||
an appropriate cursor image.
|
||||
</description>
|
||||
<entry name="none" value="0"/>
|
||||
<entry name="top" value="1"/>
|
||||
<entry name="bottom" value="2"/>
|
||||
<entry name="left" value="4"/>
|
||||
<entry name="top_left" value="5"/>
|
||||
<entry name="bottom_left" value="6"/>
|
||||
<entry name="right" value="8"/>
|
||||
<entry name="top_right" value="9"/>
|
||||
<entry name="bottom_right" value="10"/>
|
||||
</enum>
|
||||
|
||||
<request name="resize">
|
||||
<description summary="start an interactive resize">
|
||||
Start a user-driven, interactive resize of the surface.
|
||||
|
||||
This request must be used in response to some sort of user action
|
||||
like a button press, key press, or touch down event.
|
||||
|
||||
The server may ignore resize requests depending on the state of
|
||||
the surface (e.g. fullscreen or maximized).
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
||||
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
||||
<arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
|
||||
</request>
|
||||
|
||||
<enum name="state">
|
||||
<description summary="types of state on the surface">
|
||||
The different state values used on the surface. This is designed for
|
||||
state values like maximized, fullscreen. It is paired with the
|
||||
configure event to ensure that both the client and the compositor
|
||||
setting the state can be synchronized.
|
||||
|
||||
States set in this way are double-buffered. They will get applied on
|
||||
the next commit.
|
||||
|
||||
Desktop environments may extend this enum by taking up a range of
|
||||
values and documenting the range they chose in this description.
|
||||
They are not required to document the values for the range that they
|
||||
chose. Ideally, any good extensions from a desktop environment should
|
||||
make its way into standardization into this enum.
|
||||
|
||||
The current reserved ranges are:
|
||||
|
||||
0x0000 - 0x0FFF: xdg-shell core values, documented below.
|
||||
0x1000 - 0x1FFF: GNOME
|
||||
</description>
|
||||
<entry name="maximized" value="1" summary="the surface is maximized">
|
||||
The surface is maximized. The window geometry specified in the configure
|
||||
event must be obeyed by the client.
|
||||
</entry>
|
||||
<entry name="fullscreen" value="2" summary="the surface is fullscreen">
|
||||
The surface is fullscreen. The window geometry specified in the configure
|
||||
event must be obeyed by the client.
|
||||
</entry>
|
||||
<entry name="resizing" value="3">
|
||||
The surface is being resized. The window geometry specified in the
|
||||
configure event is a maximum; the client cannot resize beyond it.
|
||||
Clients that have aspect ratio or cell sizing configuration can use
|
||||
a smaller size, however.
|
||||
</entry>
|
||||
<entry name="activated" value="4">
|
||||
Client window decorations should be painted as if the window is
|
||||
active. Do not assume this means that the window actually has
|
||||
keyboard or pointer focus.
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
The configure event asks the client to resize its surface or to
|
||||
change its state.
|
||||
|
||||
The width and height arguments specify a hint to the window
|
||||
about how its surface should be resized in window geometry
|
||||
coordinates.
|
||||
|
||||
The states listed in the event specify how the width/height
|
||||
arguments should be interpreted, and possibly how it should be
|
||||
drawn.
|
||||
|
||||
Clients should arrange their surface for the new size and
|
||||
states, and then send a ack_configure request with the serial
|
||||
sent in this configure event at some point before committing
|
||||
the new surface.
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it is free to discard all but the last
|
||||
event it received.
|
||||
</description>
|
||||
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
<arg name="states" type="array"/>
|
||||
<arg name="serial" type="uint"/>
|
||||
</event>
|
||||
|
||||
<request name="ack_configure">
|
||||
<description summary="ack a configure event">
|
||||
When a configure event is received, if a client commits the
|
||||
surface in response to the configure event, then the client
|
||||
must make a ack_configure request before the commit request,
|
||||
passing along the serial of the configure event.
|
||||
|
||||
The compositor might use this information to move a surface
|
||||
to the top left only when the client has drawn itself for
|
||||
the maximized or fullscreen state.
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it only has to ack the last configure event.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||
</request>
|
||||
|
||||
<request name="set_window_geometry">
|
||||
<description summary="set the new window geometry">
|
||||
The window geometry of a window is its "visible bounds" from the
|
||||
user's perspective. Client-side decorations often have invisible
|
||||
portions like drop-shadows which should be ignored for the
|
||||
purposes of aligning, placing and constraining windows.
|
||||
|
||||
Once the window geometry of the surface is set once, it is not
|
||||
possible to unset it, and it will remain the same until
|
||||
set_window_geometry is called again, even if a new subsurface or
|
||||
buffer is attached.
|
||||
|
||||
If never set, the value is the full bounds of the surface,
|
||||
including any subsurfaces. This updates dynamically on every
|
||||
commit. This unset mode is meant for extremely simple clients.
|
||||
|
||||
If responding to a configure event, the window geometry in here
|
||||
must respect the sizing negotiations specified by the states in
|
||||
the configure event.
|
||||
|
||||
The width and height must be greater than zero.
|
||||
</description>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_maximized" />
|
||||
<request name="unset_maximized" />
|
||||
|
||||
<request name="set_fullscreen">
|
||||
<description summary="set the window as fullscreen on a monitor">
|
||||
Make the surface fullscreen.
|
||||
|
||||
You can specify an output that you would prefer to be fullscreen.
|
||||
If this value is NULL, it's up to the compositor to choose which
|
||||
display will be used to map this surface.
|
||||
</description>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
</request>
|
||||
<request name="unset_fullscreen" />
|
||||
|
||||
<request name="set_minimized">
|
||||
<description summary="set the window as minimized">
|
||||
Request that the compositor minimize your surface. There is no
|
||||
way to know if the surface is currently minimized, nor is there
|
||||
any way to unset minimization on this surface.
|
||||
|
||||
If you are looking to throttle redrawing when minimized, please
|
||||
instead use the wl_surface.frame event for this, as this will
|
||||
also work with live previews on windows in Alt-Tab, Expose or
|
||||
similar compositor features.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="close">
|
||||
<description summary="surface wants to be closed">
|
||||
The close event is sent by the compositor when the user
|
||||
wants the surface to be closed. This should be equivalent to
|
||||
the user clicking the close button in client-side decorations,
|
||||
if your application has any...
|
||||
|
||||
This is only a request that the user intends to close your
|
||||
window. The client may choose to ignore this request, or show
|
||||
a dialog to ask the user to save their data...
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_popup" version="1">
|
||||
<description summary="short-lived, popup surfaces for menus">
|
||||
A popup surface is a short-lived, temporary surface that can be
|
||||
used to implement menus. It takes an explicit grab on the surface
|
||||
that will be dismissed when the user dismisses the popup. This can
|
||||
be done by the user clicking outside the surface, using the keyboard,
|
||||
or even locking the screen through closing the lid or a timeout.
|
||||
|
||||
When the popup is dismissed, a popup_done event will be sent out,
|
||||
and at the same time the surface will be unmapped. The xdg_popup
|
||||
object is now inert and cannot be reactivated, so clients should
|
||||
destroy it. Explicitly destroying the xdg_popup object will also
|
||||
dismiss the popup and unmap the surface.
|
||||
|
||||
Clients will receive events for all their surfaces during this
|
||||
grab (which is an "owner-events" grab in X11 parlance). This is
|
||||
done so that users can navigate through submenus and other
|
||||
"nested" popup windows without having to dismiss the topmost
|
||||
popup.
|
||||
|
||||
Clients that want to dismiss the popup when another surface of
|
||||
their own is clicked should dismiss the popup using the destroy
|
||||
request.
|
||||
|
||||
The parent surface must have either an xdg_surface or xdg_popup
|
||||
role.
|
||||
|
||||
Specifying an xdg_popup for the parent means that the popups are
|
||||
nested, with this popup now being the topmost popup. Nested
|
||||
popups must be destroyed in the reverse order they were created
|
||||
in, e.g. the only popup you are allowed to destroy at all times
|
||||
is the topmost one.
|
||||
|
||||
If there is an existing popup when creating a new popup, the
|
||||
parent must be the current topmost popup.
|
||||
|
||||
A parent surface must be mapped before the new popup is mapped.
|
||||
|
||||
When compositors choose to dismiss a popup, they will likely
|
||||
dismiss every nested popup as well.
|
||||
|
||||
The x and y arguments specify where the top left of the popup
|
||||
should be placed, relative to the local surface coordinates of the
|
||||
parent surface.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<description summary="xdg_popup error values">
|
||||
These errors can be emitted in response to xdg_popup requests.
|
||||
</description>
|
||||
<entry name="not_the_topmost_popup" value="0" summary="The client tried to map or destroy a non-toplevel popup"/>
|
||||
<entry name="invalid_parent" value="1" summary="The client specified an invalid parent surface"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="remove xdg_popup interface">
|
||||
This destroys the popup. Explicitly destroying the xdg_popup
|
||||
object will also dismiss the popup, and unmap the surface.
|
||||
|
||||
If this xdg_popup is not the "topmost" popup, a protocol error
|
||||
will be sent.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="popup_done">
|
||||
<description summary="popup interaction is done">
|
||||
The popup_done event is sent out when a popup is dismissed
|
||||
by the compositor.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
@ -691,7 +691,8 @@ meta_spew_event_print (MetaDisplay *display,
|
||||
static gboolean
|
||||
handle_window_focus_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XIEnterEvent *event)
|
||||
XIEnterEvent *event,
|
||||
unsigned long serial)
|
||||
{
|
||||
MetaWindow *focus_window;
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
@ -726,7 +727,7 @@ handle_window_focus_event (MetaDisplay *display,
|
||||
event->event, window_type,
|
||||
meta_event_mode_to_string (event->mode),
|
||||
meta_event_detail_to_string (event->mode),
|
||||
event->serial);
|
||||
serial);
|
||||
#endif
|
||||
|
||||
/* FIXME our pointer tracking is broken; see how
|
||||
@ -770,7 +771,7 @@ handle_window_focus_event (MetaDisplay *display,
|
||||
if (event->evtype == XI_FocusIn)
|
||||
{
|
||||
display->server_focus_window = event->event;
|
||||
display->server_focus_serial = event->serial;
|
||||
display->server_focus_serial = serial;
|
||||
focus_window = window;
|
||||
}
|
||||
else if (event->evtype == XI_FocusOut)
|
||||
@ -784,7 +785,7 @@ handle_window_focus_event (MetaDisplay *display,
|
||||
}
|
||||
|
||||
display->server_focus_window = None;
|
||||
display->server_focus_serial = event->serial;
|
||||
display->server_focus_serial = serial;
|
||||
focus_window = NULL;
|
||||
}
|
||||
else
|
||||
@ -829,8 +830,9 @@ crossing_serial_is_ignored (MetaDisplay *display,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_input_xevent (MetaDisplay *display,
|
||||
XIEvent *input_event)
|
||||
handle_input_xevent (MetaDisplay *display,
|
||||
XIEvent *input_event,
|
||||
unsigned long serial)
|
||||
{
|
||||
XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
|
||||
Window modified;
|
||||
@ -867,7 +869,7 @@ handle_input_xevent (MetaDisplay *display,
|
||||
/* Check if we've entered a window; do this even if window->has_focus to
|
||||
* avoid races.
|
||||
*/
|
||||
if (window && !crossing_serial_is_ignored (display, input_event->serial) &&
|
||||
if (window && !crossing_serial_is_ignored (display, serial) &&
|
||||
enter_event->mode != XINotifyGrab &&
|
||||
enter_event->mode != XINotifyUngrab &&
|
||||
enter_event->detail != XINotifyInferior &&
|
||||
@ -892,7 +894,7 @@ handle_input_xevent (MetaDisplay *display,
|
||||
break;
|
||||
case XI_FocusIn:
|
||||
case XI_FocusOut:
|
||||
if (handle_window_focus_event (display, window, enter_event) &&
|
||||
if (handle_window_focus_event (display, window, enter_event, serial) &&
|
||||
enter_event->event == enter_event->root)
|
||||
{
|
||||
if (enter_event->evtype == XI_FocusIn &&
|
||||
@ -1736,7 +1738,7 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
}
|
||||
#endif /* HAVE_XI23 */
|
||||
|
||||
if (handle_input_xevent (display, input_event))
|
||||
if (handle_input_xevent (display, input_event, event->xany.serial))
|
||||
{
|
||||
bypass_gtk = bypass_compositor = TRUE;
|
||||
goto out;
|
||||
|
@ -182,6 +182,8 @@ argbdata_to_surface (gulong *argb_data, int w, int h)
|
||||
}
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty (surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
@ -312,8 +312,8 @@ meta_session_init (const char *previous_client_id,
|
||||
|
||||
prgname = g_get_prgname ();
|
||||
|
||||
prop1.name = SmProgram;
|
||||
prop1.type = SmARRAY8;
|
||||
prop1.name = (char *)SmProgram;
|
||||
prop1.type = (char *)SmARRAY8;
|
||||
prop1.num_vals = 1;
|
||||
prop1.vals = &prop1val;
|
||||
prop1val.value = (char *)prgname;
|
||||
@ -322,38 +322,38 @@ meta_session_init (const char *previous_client_id,
|
||||
/* twm sets getuid() for this, but the SM spec plainly
|
||||
* says pw_name, twm is on crack
|
||||
*/
|
||||
prop2.name = SmUserID;
|
||||
prop2.type = SmARRAY8;
|
||||
prop2.name = (char *)SmUserID;
|
||||
prop2.type = (char *)SmARRAY8;
|
||||
prop2.num_vals = 1;
|
||||
prop2.vals = &prop2val;
|
||||
prop2val.value = (char*) g_get_user_name ();
|
||||
prop2val.length = strlen (prop2val.value);
|
||||
|
||||
prop3.name = SmRestartStyleHint;
|
||||
prop3.type = SmCARD8;
|
||||
prop3.name = (char *)SmRestartStyleHint;
|
||||
prop3.type = (char *)SmCARD8;
|
||||
prop3.num_vals = 1;
|
||||
prop3.vals = &prop3val;
|
||||
prop3val.value = &hint;
|
||||
prop3val.length = 1;
|
||||
|
||||
sprintf (pid, "%d", getpid ());
|
||||
prop4.name = SmProcessID;
|
||||
prop4.type = SmARRAY8;
|
||||
prop4.name = (char *)SmProcessID;
|
||||
prop4.type = (char *)SmARRAY8;
|
||||
prop4.num_vals = 1;
|
||||
prop4.vals = &prop4val;
|
||||
prop4val.value = pid;
|
||||
prop4val.length = strlen (prop4val.value);
|
||||
|
||||
/* Always start in home directory */
|
||||
prop5.name = SmCurrentDirectory;
|
||||
prop5.type = SmARRAY8;
|
||||
prop5.name = (char *)SmCurrentDirectory;
|
||||
prop5.type = (char *)SmARRAY8;
|
||||
prop5.num_vals = 1;
|
||||
prop5.vals = &prop5val;
|
||||
prop5val.value = (char*) g_get_home_dir ();
|
||||
prop5val.length = strlen (prop5val.value);
|
||||
|
||||
prop6.name = "_GSM_Priority";
|
||||
prop6.type = SmCARD8;
|
||||
prop6.name = (char *)"_GSM_Priority";
|
||||
prop6.type = (char *)SmCARD8;
|
||||
prop6.num_vals = 1;
|
||||
prop6.vals = &prop6val;
|
||||
prop6val.value = &priority;
|
||||
@ -588,15 +588,15 @@ set_clone_restart_commands (void)
|
||||
|
||||
/* Restart (use same client ID) */
|
||||
|
||||
prop1.name = SmRestartCommand;
|
||||
prop1.type = SmLISTofARRAY8;
|
||||
prop1.name = (char *)SmRestartCommand;
|
||||
prop1.type = (char *)SmLISTofARRAY8;
|
||||
|
||||
g_return_if_fail (client_id);
|
||||
|
||||
i = 0;
|
||||
restartv[i] = (char *)prgname;
|
||||
++i;
|
||||
restartv[i] = "--sm-client-id";
|
||||
restartv[i] = (char *)"--sm-client-id";
|
||||
++i;
|
||||
restartv[i] = client_id;
|
||||
++i;
|
||||
@ -619,8 +619,8 @@ set_clone_restart_commands (void)
|
||||
++i;
|
||||
clonev[i] = NULL;
|
||||
|
||||
prop2.name = SmCloneCommand;
|
||||
prop2.type = SmLISTofARRAY8;
|
||||
prop2.name = (char *)SmCloneCommand;
|
||||
prop2.type = (char *)SmLISTofARRAY8;
|
||||
|
||||
prop2.vals = g_new (SmPropValue, i);
|
||||
i = 0;
|
||||
@ -635,16 +635,16 @@ set_clone_restart_commands (void)
|
||||
/* Discard */
|
||||
|
||||
i = 0;
|
||||
discardv[i] = "rm";
|
||||
discardv[i] = (char *)"rm";
|
||||
++i;
|
||||
discardv[i] = "-f";
|
||||
discardv[i] = (char *)"-f";
|
||||
++i;
|
||||
discardv[i] = (char*) full_save_file ();
|
||||
++i;
|
||||
discardv[i] = NULL;
|
||||
|
||||
prop3.name = SmDiscardCommand;
|
||||
prop3.type = SmLISTofARRAY8;
|
||||
prop3.name = (char *)SmDiscardCommand;
|
||||
prop3.type = (char *)SmLISTofARRAY8;
|
||||
|
||||
prop3.vals = g_new (SmPropValue, i);
|
||||
i = 0;
|
||||
@ -946,7 +946,15 @@ save_state (void)
|
||||
|
||||
/* Sticky */
|
||||
if (window->on_all_workspaces_requested)
|
||||
fputs (" <sticky/>\n", outfile);
|
||||
{
|
||||
fputs (" <sticky/>\n", outfile);
|
||||
} else {
|
||||
int n;
|
||||
n = meta_workspace_index (window->workspace);
|
||||
fprintf (outfile,
|
||||
" <workspace index=\"%d\"/>\n", n);
|
||||
}
|
||||
|
||||
|
||||
/* Minimized */
|
||||
if (window->minimized)
|
||||
@ -963,14 +971,6 @@ save_state (void)
|
||||
window->saved_rect.height);
|
||||
}
|
||||
|
||||
/* Workspaces we're on */
|
||||
{
|
||||
int n;
|
||||
n = meta_workspace_index (window->workspace);
|
||||
fprintf (outfile,
|
||||
" <workspace index=\"%d\"/>\n", n);
|
||||
}
|
||||
|
||||
/* Gravity */
|
||||
{
|
||||
int x, y, w, h;
|
||||
@ -1792,8 +1792,8 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
||||
return;
|
||||
}
|
||||
|
||||
columns = g_slist_prepend (columns, "Window");
|
||||
columns = g_slist_prepend (columns, "Class");
|
||||
columns = g_slist_prepend (columns, (gpointer)"Window");
|
||||
columns = g_slist_prepend (columns, (gpointer)"Class");
|
||||
|
||||
lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
|
||||
|
||||
@ -1803,7 +1803,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
lame_details = g_slist_prepend (lame_details,
|
||||
w->res_class ? w->res_class : "");
|
||||
w->res_class ? w->res_class : (gpointer)"");
|
||||
lame_details = g_slist_prepend (lame_details,
|
||||
w->title);
|
||||
|
||||
|
@ -1843,7 +1843,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_window_type, LOAD_INIT | INCLUDE_OR | FORCE_INIT },
|
||||
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, NONE },
|
||||
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, NONE },
|
||||
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, NONE },
|
||||
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, LOAD_INIT | INCLUDE_OR },
|
||||
{ 0 },
|
||||
};
|
||||
|
@ -389,7 +389,7 @@ meta_window_apply_session_info (MetaWindow *window,
|
||||
"Restoring minimized state %d for window %s\n",
|
||||
info->minimized, window->desc);
|
||||
|
||||
if (window->has_minimize_func && info->minimized)
|
||||
if (info->minimized)
|
||||
meta_window_minimize (window);
|
||||
}
|
||||
|
||||
@ -542,13 +542,10 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
* For normal windows, do a full ConfigureRequest based on the
|
||||
* window hints, as that's what the ICCCM says to do.
|
||||
*/
|
||||
priv->client_rect = window->rect;
|
||||
window->buffer_rect = window->rect;
|
||||
|
||||
if (window->override_redirect)
|
||||
{
|
||||
priv->client_rect = window->rect;
|
||||
window->buffer_rect = window->rect;
|
||||
}
|
||||
else
|
||||
if (!window->override_redirect)
|
||||
{
|
||||
MetaRectangle rect;
|
||||
MetaMoveResizeFlags flags;
|
||||
@ -863,7 +860,7 @@ meta_window_x11_grab_op_began (MetaWindow *window,
|
||||
if (window->sync_request_counter != None)
|
||||
meta_window_x11_create_sync_request_alarm (window);
|
||||
|
||||
if (window->size_hints.width_inc > 1 || window->size_hints.height_inc > 1)
|
||||
if (window->size_hints.width_inc > 2 || window->size_hints.height_inc > 2)
|
||||
{
|
||||
priv->showing_resize_popup = TRUE;
|
||||
meta_window_refresh_resize_popup (window);
|
||||
@ -1850,6 +1847,12 @@ meta_window_x11_update_shape_region (MetaWindow *window)
|
||||
* this is simply the client area.
|
||||
*/
|
||||
cairo_region_intersect_rectangle (region, &client_area);
|
||||
|
||||
/* Some applications might explicitly set their bounding region
|
||||
* to the client area. Detect these cases, and throw out the
|
||||
* bounding region in this case. */
|
||||
if (cairo_region_contains_rectangle (region, &client_area) == CAIRO_REGION_OVERLAP_IN)
|
||||
g_clear_pointer (®ion, cairo_region_destroy);
|
||||
}
|
||||
|
||||
meta_window_set_shape_region (window, region);
|
||||
@ -2441,8 +2444,7 @@ meta_window_x11_client_message (MetaWindow *window,
|
||||
{
|
||||
meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
|
||||
event->xclient.data.l[0]);
|
||||
if (event->xclient.data.l[0] == IconicState &&
|
||||
window->has_minimize_func)
|
||||
if (event->xclient.data.l[0] == IconicState)
|
||||
meta_window_minimize (window);
|
||||
|
||||
return TRUE;
|
||||
|
@ -194,6 +194,7 @@ async_get_property_finish (xcb_connection_t *xcb_conn,
|
||||
{
|
||||
xcb_get_property_reply_t *reply;
|
||||
xcb_generic_error_t *error;
|
||||
int length;
|
||||
|
||||
reply = xcb_get_property_reply (xcb_conn, cookie, &error);
|
||||
if (error)
|
||||
@ -209,8 +210,15 @@ async_get_property_finish (xcb_connection_t *xcb_conn,
|
||||
results->prop = NULL;
|
||||
|
||||
if (results->type != None)
|
||||
results->prop = g_memdup (xcb_get_property_value (reply),
|
||||
xcb_get_property_value_length (reply));
|
||||
{
|
||||
length = xcb_get_property_value_length (reply);
|
||||
/* Leave room for a trailing '\0' since xcb doesn't return null-terminated
|
||||
* strings
|
||||
*/
|
||||
results->prop = g_malloc (length + 1);
|
||||
memcpy (results->prop, xcb_get_property_value (reply), length);
|
||||
results->prop[length] = '\0';
|
||||
}
|
||||
|
||||
free (reply);
|
||||
return (results->prop != NULL);
|
||||
@ -507,7 +515,7 @@ window_from_results (GetPropertyResults *results,
|
||||
if (!validate_or_free_results (results, 32, XA_WINDOW, TRUE))
|
||||
return FALSE;
|
||||
|
||||
*window_p = *(Window*) results->prop;
|
||||
*window_p = *(uint32_t *) results->prop;
|
||||
g_free (results->prop);
|
||||
results->prop = NULL;
|
||||
|
||||
@ -523,7 +531,7 @@ counter_from_results (GetPropertyResults *results,
|
||||
TRUE))
|
||||
return FALSE;
|
||||
|
||||
*counter_p = *(XSyncCounter*) results->prop;
|
||||
*counter_p = *(uint32_t *) results->prop;
|
||||
g_free (results->prop);
|
||||
results->prop = NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user