Compare commits
100 Commits
3.17.90
...
gnome-3-18
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b1b46f196c | ||
![]() |
3082504d1b | ||
![]() |
8a529123be | ||
![]() |
54a680266c | ||
![]() |
e6d414edfc | ||
![]() |
70f20c90bd | ||
![]() |
b5f7005b88 | ||
![]() |
f0e2e238f3 | ||
![]() |
0c48a2633f | ||
![]() |
26a18e8312 | ||
![]() |
2ea121a186 | ||
![]() |
958cdd5117 | ||
![]() |
58d2bd0581 | ||
![]() |
e5067368f5 | ||
![]() |
c89918a339 | ||
![]() |
15b5e6717f | ||
![]() |
3b977f18b3 | ||
![]() |
233c148c16 | ||
![]() |
8c561a9075 | ||
![]() |
eb1df05570 | ||
![]() |
ffa8c0039d | ||
![]() |
379044c069 | ||
![]() |
c5f40f7481 | ||
![]() |
c9b0d04503 | ||
![]() |
0d41399fed | ||
![]() |
5d695c674e | ||
![]() |
7717725270 | ||
![]() |
6542ef2970 | ||
![]() |
83d19c8ae2 | ||
![]() |
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 | ||
![]() |
35729e8659 | ||
![]() |
dc7e665de9 | ||
![]() |
2e3bfd1a11 | ||
![]() |
b7aca07844 | ||
![]() |
dc780d2c44 | ||
![]() |
c49b284643 | ||
![]() |
0373b854c1 | ||
![]() |
5d837a5c85 | ||
![]() |
79c86ae890 | ||
![]() |
7c7cf91c32 | ||
![]() |
e407f5bbae | ||
![]() |
8900bd2f5c | ||
![]() |
83c17134f1 | ||
![]() |
8e5fb03611 | ||
![]() |
dece49b53d | ||
![]() |
443d579d40 | ||
![]() |
5066eaf691 | ||
![]() |
6ea7fa9973 | ||
![]() |
79f755bf0f | ||
![]() |
1845bfe1b6 | ||
![]() |
8e22bf5bc9 | ||
![]() |
c13ddafdb8 | ||
![]() |
94513726de | ||
![]() |
0aa4c4d43e | ||
![]() |
e3db4ab16a | ||
![]() |
614d6bd0f8 | ||
![]() |
1d56d50fcd | ||
![]() |
0ffd4254d9 | ||
![]() |
36eee04a21 | ||
![]() |
d3fdaa3232 | ||
![]() |
165050f8f9 | ||
![]() |
68279e8a08 | ||
![]() |
cd1ce2cb0a | ||
![]() |
b01f95cfdd | ||
![]() |
4b667d1e09 | ||
![]() |
fe8454d13f | ||
![]() |
53a6d16891 | ||
![]() |
e76c3ecb00 |
83
NEWS
83
NEWS
@@ -1,3 +1,86 @@
|
||||
3.18.4
|
||||
======
|
||||
* Fix mouse cursor disappearing in some multi-monitor setups [Rui; #763159]
|
||||
* Do not assert on non-fatal runtime errors [Florian; #765058]
|
||||
|
||||
Contributors:
|
||||
Rui Matos, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Cédric Valmary [oc]
|
||||
|
||||
3.18.3
|
||||
======
|
||||
* Fix initialization of bypass compositor hint [Rui; #758544]
|
||||
* 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 crash during XWayland initialization [Marek; #751845]
|
||||
* Ensure to send a ConfigureNotify to just mapped windows [Rui; #759492]
|
||||
|
||||
Contributors:
|
||||
Marek Chalupa, Rui Matos, Jasper St. Pierre
|
||||
|
||||
3.18.2
|
||||
======
|
||||
* Misc. crash fixes [Jonas, Rui; #756675, #756660, #757148, #756796]
|
||||
* Fix modifiers-only input source switching on Ubuntu [Alberts; #756543]
|
||||
* Exit cleanly on initialization errors [Owen; #757311]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Rui Matos, Alberts Muktupāvels, Florian Müllner, Owen W. Taylor
|
||||
|
||||
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]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Rūdolfs Mazurs [lv]
|
||||
|
||||
3.17.92
|
||||
=======
|
||||
* Don't omit the background color for backgrounds that don't fill the screen
|
||||
[Ray; #754476]
|
||||
* Fix up key state on FocusIn when running nested [Owen; #753948]
|
||||
* Find the right DRM device instead of hardcoding card0 [Marek; #753434]
|
||||
* Scale cursor on HiDPI screens [Jonas; #744932]
|
||||
* Misc. fixes and cleanups [Lan, Jonas, Javier, Olivier; #754545, #754215,
|
||||
#754621, #754715]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Marek Chalupa, Olivier Fourdan, Javier Jardón, Ting-Wei Lan,
|
||||
Ray Strode, Owen W. Taylor
|
||||
|
||||
3.17.91
|
||||
=======
|
||||
* Send error on pointer-gesture protocol version mismatch [Jonas; #753855]
|
||||
* Misc. cleanups [Jonas; #744932]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl
|
||||
|
||||
Translations:
|
||||
Chao-Hsiung Liao [zh_TW], Piotr Drąg [pl]
|
||||
|
||||
3.17.90
|
||||
=======
|
||||
* Fix glitch with some fullscreen apps [Rui; #753020]
|
||||
|
@@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [17])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
m4_define([mutter_minor_version], [18])
|
||||
m4_define([mutter_micro_version], [4])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
|
51
po/pl.po
51
po/pl.po
@@ -15,8 +15,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-03-05 00:23+0100\n"
|
||||
"PO-Revision-Date: 2015-03-05 00:24+0100\n"
|
||||
"POT-Creation-Date: 2015-08-26 18:49+0200\n"
|
||||
"PO-Revision-Date: 2015-08-26 18:50+0200\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Polish <gnomepl@aviary.pl>\n"
|
||||
"Language: pl\n"
|
||||
@@ -285,9 +285,9 @@ msgid ""
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
msgstr ""
|
||||
"Ten klawisz inicjuje tryb \"overlay\", który jest połączeniem podglądu okien "
|
||||
"i systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania "
|
||||
"z klawiszem \"Windows\" na komputerach typu PC. Ustawienie tego powiązania "
|
||||
"Ten klawisz inicjuje tryb „overlay”, który jest połączeniem podglądu okien i "
|
||||
"systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania z "
|
||||
"klawiszem „Windows” na komputerach typu PC. Ustawienie tego powiązania "
|
||||
"powinno być domyślne lub puste."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
|
||||
@@ -300,9 +300,9 @@ msgid ""
|
||||
"attached to the titlebar of the parent window and are moved together with "
|
||||
"the parent window."
|
||||
msgstr ""
|
||||
"Jeśli wynosi \"true\", to modalne okna dialogowe pojawiają się dołączone do "
|
||||
"paska tytułowego okna nadrzędnego zamiast posiadać oddzielne paski tytułowe "
|
||||
"i są przenoszone razem z nim."
|
||||
"Jeśli wynosi wartość „true”, to modalne okna dialogowe pojawiają się "
|
||||
"dołączone do paska tytułowego okna nadrzędnego zamiast posiadać oddzielne "
|
||||
"paski tytułowe i są przenoszone razem z nim."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
|
||||
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||
@@ -332,7 +332,7 @@ msgid ""
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
"Określa, czy obszary robocze są zarządzane dynamicznie, czy istnieje "
|
||||
"statyczna liczba obszarów (określona przez klucz \"num-workspaces\" w org."
|
||||
"statyczna liczba obszarów (określona przez klucz „num-workspaces” w org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
|
||||
@@ -369,9 +369,9 @@ msgid ""
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
msgstr ""
|
||||
"Jeśli jest ustawione na wartość \"true\", a tryb aktywności to \"sloppy\" "
|
||||
"lub \"mouse\", to aktywność nie będzie zmieniana od razu po przejściu do "
|
||||
"okna, ale dopiero po zatrzymaniu ruchu kursora."
|
||||
"Jeśli jest ustawione na wartość „true”, a tryb aktywności to „sloppy” lub "
|
||||
"„mouse”, to aktywność nie będzie zmieniana od razu po przejściu do okna, ale "
|
||||
"dopiero po zatrzymaniu ruchu kursora."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
|
||||
msgid "Draggable border width"
|
||||
@@ -409,7 +409,7 @@ msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
msgstr ""
|
||||
"Jeśli wynosi \"true\", to nowe okna będą zawsze umieszczane na środku "
|
||||
"Jeśli wynosi wartość „true”, to nowe okna będą zawsze umieszczane na środku "
|
||||
"aktywnego ekranu monitora."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
|
||||
@@ -468,22 +468,22 @@ msgstr "Przełączenie na 11. konsolę wirtualną"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Przełączenie na 12. konsolę wirtualną"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
#: ../src/backends/meta-monitor-manager.c:500
|
||||
msgid "Built-in display"
|
||||
msgstr "Wbudowany ekran"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
#: ../src/backends/meta-monitor-manager.c:526
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznany"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
#: ../src/backends/meta-monitor-manager.c:528
|
||||
msgid "Unknown Display"
|
||||
msgstr "Nieznany ekran"
|
||||
|
||||
#. 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:536
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
@@ -496,7 +496,7 @@ msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr ""
|
||||
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu \"%s\"."
|
||||
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu „%s”."
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
@@ -505,7 +505,7 @@ msgstr "Zdarzenie sygnału dźwiękowego"
|
||||
#: ../src/core/delete.c:127
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "Okno \"%s\" nie odpowiada."
|
||||
msgstr "Okno „%s” nie odpowiada."
|
||||
|
||||
#: ../src/core/delete.c:129
|
||||
msgid "Application is not responding."
|
||||
@@ -525,11 +525,10 @@ msgstr "_Czekaj"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Zakończ"
|
||||
|
||||
#: ../src/core/display.c:562
|
||||
#: ../src/core/display.c:563
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr ""
|
||||
"Otwarcie połączenia z ekranem \"%s\" systemu X Window się nie powiodło\n"
|
||||
msgstr "Otwarcie połączenia z ekranem „%s” systemu X Window się nie powiodło\n"
|
||||
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
@@ -573,7 +572,7 @@ msgid ""
|
||||
"PARTICULAR PURPOSE.\n"
|
||||
msgstr ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., oraz inni\n"
|
||||
"Copyright (C) 2001—%d Havoc Pennington, Red Hat, Inc., oraz inni\n"
|
||||
"Niniejszy program jest wolnym oprogramowaniem, aby poznać warunki, pod\n"
|
||||
"jakimi dopuszczalne jest kopiowanie programu, zajrzyj do jego źródeł.\n"
|
||||
"Na program nie udziela się ŻADNYCH GWARANCJI, nawet domyślnej gwarancji\n"
|
||||
@@ -598,13 +597,13 @@ msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
msgstr ""
|
||||
"Na ekranie \"%s\" działa już menedżer okien. Aby zastąpić działającego "
|
||||
"Na ekranie „%s” działa już menedżer okien. Aby zastąpić działającego "
|
||||
"menedżera okien, proszę spróbować użyć opcji --replace."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Podekran %d ekranu \"%s\" jest nieprawidłowy\n"
|
||||
msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
@@ -616,7 +615,7 @@ msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"Te okna nie obsługują opcji zapisu obecnego stanu (\"save current setup\"), "
|
||||
"Te okna nie obsługują opcji zapisu obecnego stanu („save current setup”), "
|
||||
"więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
|
||||
|
||||
#: ../src/x11/window-props.c:549
|
||||
|
1155
po/zh_CN.po
1155
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
20
po/zh_TW.po
20
po/zh_TW.po
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: metacity 3.3.4\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-20 23:22+0000\n"
|
||||
"POT-Creation-Date: 2015-07-21 10:52+0000\n"
|
||||
"PO-Revision-Date: 2015-02-21 16:33+0800\n"
|
||||
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
|
||||
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
|
||||
@@ -439,22 +439,22 @@ msgstr "切換至 VT 11"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "切換至 VT 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
#: ../src/backends/meta-monitor-manager.c:500
|
||||
msgid "Built-in display"
|
||||
msgstr "內建顯示"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
#: ../src/backends/meta-monitor-manager.c:526
|
||||
msgid "Unknown"
|
||||
msgstr "不明"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
#: ../src/backends/meta-monitor-manager.c:528
|
||||
msgid "Unknown Display"
|
||||
msgstr "不明的顯示器"
|
||||
|
||||
#. 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:536
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
@@ -462,7 +462,7 @@ msgstr "%s %s"
|
||||
# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#: ../src/compositor/compositor.c:451
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -496,14 +496,14 @@ msgstr "等待(_W)"
|
||||
msgid "_Force Quit"
|
||||
msgstr "強制結束(_F)"
|
||||
|
||||
#: ../src/core/display.c:562
|
||||
#: ../src/core/display.c:563
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "無法開啟 X Window 畫面‘%s’\n"
|
||||
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "停用到作業階段管理程式的連線"
|
||||
msgstr "停用到作業階段管理員的連線"
|
||||
|
||||
#: ../src/core/main.c:182
|
||||
msgid "Replace the running window manager"
|
||||
@@ -1053,9 +1053,9 @@ msgstr "%s(在 %s)"
|
||||
#~ msgid ""
|
||||
#~ "\"%s\" found in configuration database is not a valid value for mouse "
|
||||
#~ "button modifier\n"
|
||||
#~ msgstr "組態資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n"
|
||||
#~ msgstr "設定資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"%s\" found in configuration database is not a valid value for "
|
||||
#~ "keybinding \"%s\"\n"
|
||||
#~ msgstr "組態資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n"
|
||||
#~ msgstr "設定資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n"
|
||||
|
@@ -68,7 +68,6 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-barrier-private.h \
|
||||
backends/meta-cursor.c \
|
||||
backends/meta-cursor.h \
|
||||
backends/meta-cursor-private.h \
|
||||
backends/meta-cursor-tracker.c \
|
||||
backends/meta-cursor-tracker-private.h \
|
||||
backends/meta-cursor-renderer.c \
|
||||
@@ -97,6 +96,8 @@ libmutter_la_SOURCES = \
|
||||
backends/x11/meta-barrier-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
backends/x11/meta-cursor-renderer-x11.h \
|
||||
backends/x11/nested/meta-cursor-renderer-x11-nested.c \
|
||||
backends/x11/nested/meta-cursor-renderer-x11-nested.h \
|
||||
backends/x11/meta-idle-monitor-xsync.c \
|
||||
backends/x11/meta-idle-monitor-xsync.h \
|
||||
backends/x11/meta-input-settings-x11.c \
|
||||
|
@@ -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
|
||||
|
@@ -1,66 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Giovanni Campagna <gcampagn@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef META_CURSOR_PRIVATE_H
|
||||
#define META_CURSOR_PRIVATE_H
|
||||
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include <gbm.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
int hot_x, hot_y;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *bo;
|
||||
#endif
|
||||
} MetaCursorImage;
|
||||
|
||||
struct _MetaCursorReference {
|
||||
int ref_count;
|
||||
|
||||
int current_frame;
|
||||
XcursorImages *xcursor_images;
|
||||
MetaCursor cursor;
|
||||
MetaCursorImage image;
|
||||
};
|
||||
|
||||
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
#endif
|
||||
|
||||
gboolean meta_cursor_reference_is_animated (MetaCursorReference *self);
|
||||
void meta_cursor_reference_tick_frame (MetaCursorReference *self);
|
||||
guint meta_cursor_reference_get_current_frame_time (MetaCursorReference *self);
|
||||
|
||||
#endif /* META_CURSOR_PRIVATE_H */
|
@@ -25,7 +25,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-cursor-private.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
@@ -38,9 +37,8 @@
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
int current_x, current_y;
|
||||
MetaRectangle current_rect;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
MetaCursorSprite *displayed_cursor;
|
||||
gboolean handled_by_backend;
|
||||
};
|
||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
@@ -48,27 +46,33 @@ typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
queue_redraw (MetaCursorRenderer *renderer)
|
||||
queue_redraw (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
CoglTexture *texture;
|
||||
MetaRectangle rect = { 0 };
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
|
||||
/* During early initialization, we can have no stage */
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
if (priv->displayed_cursor && !priv->handled_by_backend)
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
|
||||
if (cursor_sprite && !priv->handled_by_backend)
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
else
|
||||
texture = NULL;
|
||||
|
||||
meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect);
|
||||
meta_stage_set_cursor (META_STAGE (stage), texture, &rect);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
|
||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -84,34 +88,50 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
|
||||
{
|
||||
}
|
||||
|
||||
MetaRectangle
|
||||
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
CoglTexture *texture;
|
||||
int hot_x, hot_y;
|
||||
int width, height;
|
||||
float texture_scale;
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
if (!texture)
|
||||
return (MetaRectangle) { 0 };
|
||||
|
||||
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
|
||||
texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
return (MetaRectangle) {
|
||||
.x = (int)roundf (priv->current_x - (hot_x * texture_scale)),
|
||||
.y = (int)roundf (priv->current_y - (hot_y * texture_scale)),
|
||||
.width = (int)roundf (width * texture_scale),
|
||||
.height = (int)roundf (height * texture_scale),
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (MetaCursorRenderer *renderer)
|
||||
update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
gboolean handled_by_backend;
|
||||
gboolean should_redraw = FALSE;
|
||||
|
||||
if (priv->displayed_cursor)
|
||||
{
|
||||
CoglTexture *texture;
|
||||
int hot_x, hot_y;
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_prepare_at (cursor_sprite,
|
||||
priv->current_x,
|
||||
priv->current_y);
|
||||
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
|
||||
|
||||
priv->current_rect.x = priv->current_x - hot_x;
|
||||
priv->current_rect.y = priv->current_y - hot_y;
|
||||
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
|
||||
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->current_rect.x = 0;
|
||||
priv->current_rect.y = 0;
|
||||
priv->current_rect.width = 0;
|
||||
priv->current_rect.height = 0;
|
||||
}
|
||||
|
||||
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
handled_by_backend =
|
||||
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
|
||||
cursor_sprite);
|
||||
if (handled_by_backend != priv->handled_by_backend)
|
||||
{
|
||||
priv->handled_by_backend = handled_by_backend;
|
||||
@@ -122,7 +142,7 @@ update_cursor (MetaCursorRenderer *renderer)
|
||||
should_redraw = TRUE;
|
||||
|
||||
if (should_redraw)
|
||||
queue_redraw (renderer);
|
||||
queue_redraw (renderer, cursor_sprite);
|
||||
}
|
||||
|
||||
MetaCursorRenderer *
|
||||
@@ -132,23 +152,25 @@ meta_cursor_renderer_new (void)
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorReference *cursor)
|
||||
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
if (priv->displayed_cursor == cursor)
|
||||
if (priv->displayed_cursor == cursor_sprite)
|
||||
return;
|
||||
priv->displayed_cursor = cursor_sprite;
|
||||
|
||||
priv->displayed_cursor = cursor;
|
||||
update_cursor (renderer);
|
||||
update_cursor (renderer, cursor_sprite);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
|
||||
{
|
||||
update_cursor (renderer);
|
||||
queue_redraw (renderer);
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
update_cursor (renderer, priv->displayed_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -162,10 +184,10 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||
priv->current_x = x;
|
||||
priv->current_y = y;
|
||||
|
||||
update_cursor (renderer);
|
||||
update_cursor (renderer, priv->displayed_cursor);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
MetaCursorSprite *
|
||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
@@ -173,10 +195,27 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||
return priv->displayed_cursor;
|
||||
}
|
||||
|
||||
const MetaRectangle *
|
||||
meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
|
||||
#ifdef HAVE_WAYLAND
|
||||
void
|
||||
meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
return &priv->current_rect;
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
|
||||
|
||||
if (renderer_class->realize_cursor_from_wl_buffer)
|
||||
renderer_class->realize_cursor_from_wl_buffer (renderer, cursor_sprite, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
|
||||
|
||||
if (renderer_class->realize_cursor_from_xcursor)
|
||||
renderer_class->realize_cursor_from_xcursor (renderer, cursor_sprite, xc_image);
|
||||
}
|
||||
|
@@ -26,6 +26,10 @@
|
||||
#define META_CURSOR_RENDERER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <wayland-server.h>
|
||||
#endif
|
||||
|
||||
#include <meta/screen.h>
|
||||
#include "meta-cursor.h"
|
||||
@@ -38,21 +42,40 @@ struct _MetaCursorRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
|
||||
gboolean (* update_cursor) (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
#ifdef HAVE_WAYLAND
|
||||
void (* realize_cursor_from_wl_buffer) (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer);
|
||||
#endif
|
||||
void (* realize_cursor_from_xcursor) (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
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,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
||||
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||
int x, int y);
|
||||
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
|
||||
|
||||
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
|
||||
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||
|
||||
MetaRectangle meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer);
|
||||
#endif
|
||||
|
||||
void meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image);
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_H */
|
||||
|
@@ -34,7 +34,7 @@ struct _MetaCursorTracker {
|
||||
|
||||
gboolean is_showing;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
MetaCursorSprite *displayed_cursor;
|
||||
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
* explicitly, which means that we shouldn't display anything.
|
||||
@@ -42,12 +42,12 @@ struct _MetaCursorTracker {
|
||||
* determine an unset window cursor; we need an extra boolean.
|
||||
*/
|
||||
gboolean has_window_cursor;
|
||||
MetaCursorReference *window_cursor;
|
||||
MetaCursorSprite *window_cursor;
|
||||
|
||||
MetaCursorReference *root_cursor;
|
||||
MetaCursorSprite *root_cursor;
|
||||
|
||||
/* The cursor from the X11 server. */
|
||||
MetaCursorReference *xfixes_cursor;
|
||||
MetaCursorSprite *xfixes_cursor;
|
||||
};
|
||||
|
||||
struct _MetaCursorTrackerClass {
|
||||
@@ -57,16 +57,16 @@ struct _MetaCursorTrackerClass {
|
||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent);
|
||||
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
||||
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
int new_y);
|
||||
|
||||
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
|
||||
MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
|
||||
|
||||
#endif
|
||||
|
@@ -43,7 +43,6 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-cursor-private.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
@@ -54,7 +53,7 @@ enum {
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static MetaCursorReference *
|
||||
static MetaCursorSprite *
|
||||
get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
@@ -80,14 +79,14 @@ update_displayed_cursor (MetaCursorTracker *tracker)
|
||||
static void
|
||||
sync_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
|
||||
MetaCursorSprite *displayed_cursor = get_displayed_cursor (tracker);
|
||||
|
||||
if (tracker->displayed_cursor == displayed_cursor)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
|
||||
g_clear_object (&tracker->displayed_cursor);
|
||||
if (displayed_cursor)
|
||||
tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
|
||||
tracker->displayed_cursor = g_object_ref (displayed_cursor);
|
||||
|
||||
update_displayed_cursor (tracker);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
@@ -108,9 +107,9 @@ meta_cursor_tracker_finalize (GObject *object)
|
||||
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
|
||||
|
||||
if (self->displayed_cursor)
|
||||
meta_cursor_reference_unref (self->displayed_cursor);
|
||||
g_object_unref (self->displayed_cursor);
|
||||
if (self->root_cursor)
|
||||
meta_cursor_reference_unref (self->root_cursor);
|
||||
g_object_unref (self->root_cursor);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -156,13 +155,13 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
|
||||
}
|
||||
|
||||
static void
|
||||
set_window_cursor (MetaCursorTracker *tracker,
|
||||
gboolean has_cursor,
|
||||
MetaCursorReference *cursor)
|
||||
set_window_cursor (MetaCursorTracker *tracker,
|
||||
gboolean has_cursor,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->window_cursor = meta_cursor_reference_ref (cursor);
|
||||
g_clear_object (&tracker->window_cursor);
|
||||
if (cursor_sprite)
|
||||
tracker->window_cursor = g_object_ref (cursor_sprite);
|
||||
tracker->has_window_cursor = has_cursor;
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
@@ -184,28 +183,12 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
if (notify_event->subtype != XFixesDisplayCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
|
||||
g_clear_object (&tracker->xfixes_cursor);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_take_texture (CoglTexture2D *texture,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->image.texture = texture;
|
||||
self->image.hot_x = hot_x;
|
||||
self->image.hot_y = hot_y;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
@@ -215,6 +198,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
guint8 *cursor_data;
|
||||
gboolean free_cursor_data;
|
||||
CoglContext *ctx;
|
||||
CoglError *error = NULL;
|
||||
|
||||
if (tracker->xfixes_cursor)
|
||||
return;
|
||||
@@ -256,17 +240,26 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
cursor_image->width * 4, /* stride */
|
||||
cursor_data,
|
||||
NULL);
|
||||
&error);
|
||||
|
||||
if (free_cursor_data)
|
||||
g_free (cursor_data);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
meta_warning ("Failed to allocate cursor sprite texture: %s\n", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
|
||||
if (sprite != NULL)
|
||||
{
|
||||
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
|
||||
cursor_image->xhot,
|
||||
cursor_image->yhot);
|
||||
tracker->xfixes_cursor = cursor;
|
||||
MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
|
||||
meta_cursor_sprite_set_texture (cursor_sprite,
|
||||
sprite,
|
||||
cursor_image->xhot,
|
||||
cursor_image->yhot);
|
||||
cogl_object_unref (sprite);
|
||||
tracker->xfixes_cursor = cursor_sprite;
|
||||
}
|
||||
XFree (cursor_image);
|
||||
}
|
||||
@@ -279,22 +272,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
CoglTexture *
|
||||
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
|
||||
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
cursor_sprite = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
cursor_sprite = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (cursor)
|
||||
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
|
||||
if (cursor_sprite)
|
||||
return meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -311,22 +304,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
|
||||
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
cursor_sprite = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
cursor_sprite = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (cursor)
|
||||
meta_cursor_reference_get_cogl_texture (cursor, x, y);
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_get_hotspot (cursor_sprite, x, y);
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
@@ -337,10 +330,10 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
set_window_cursor (tracker, TRUE, cursor);
|
||||
set_window_cursor (tracker, TRUE, cursor_sprite);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -350,12 +343,12 @@ meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->root_cursor = meta_cursor_reference_ref (cursor);
|
||||
g_clear_object (&tracker->root_cursor);
|
||||
if (cursor_sprite)
|
||||
tracker->root_cursor = g_object_ref (cursor_sprite);
|
||||
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
@@ -438,7 +431,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
MetaCursorSprite *
|
||||
meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
return tracker->displayed_cursor;
|
||||
|
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <meta/errors.h>
|
||||
|
||||
@@ -29,58 +29,38 @@
|
||||
#include "screen-private.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#endif
|
||||
enum {
|
||||
PREPARE_AT,
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaCursorSprite
|
||||
{
|
||||
g_assert (self->ref_count > 0);
|
||||
self->ref_count++;
|
||||
GObject parent;
|
||||
|
||||
return self;
|
||||
}
|
||||
MetaCursor cursor;
|
||||
|
||||
static void
|
||||
meta_cursor_image_free (MetaCursorImage *image)
|
||||
{
|
||||
if (image->texture)
|
||||
cogl_object_unref (image->texture);
|
||||
CoglTexture2D *texture;
|
||||
float texture_scale;
|
||||
int hot_x, hot_y;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (image->bo)
|
||||
gbm_bo_destroy (image->bo);
|
||||
#endif
|
||||
}
|
||||
int current_frame;
|
||||
XcursorImages *xcursor_images;
|
||||
|
||||
static void
|
||||
meta_cursor_reference_free (MetaCursorReference *self)
|
||||
{
|
||||
if (self->xcursor_images)
|
||||
XcursorImagesDestroy (self->xcursor_images);
|
||||
meta_cursor_image_free (&self->image);
|
||||
g_slice_free (MetaCursorReference, self);
|
||||
}
|
||||
int theme_scale;
|
||||
gboolean theme_dirty;
|
||||
};
|
||||
|
||||
void
|
||||
meta_cursor_reference_unref (MetaCursorReference *self)
|
||||
{
|
||||
self->ref_count--;
|
||||
|
||||
if (self->ref_count == 0)
|
||||
meta_cursor_reference_free (self);
|
||||
}
|
||||
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
|
||||
|
||||
static const char *
|
||||
translate_meta_cursor (MetaCursor cursor)
|
||||
@@ -138,92 +118,27 @@ meta_cursor_create_x_cursor (Display *xdisplay,
|
||||
}
|
||||
|
||||
static XcursorImages *
|
||||
load_cursor_on_client (MetaCursor cursor)
|
||||
load_cursor_on_client (MetaCursor cursor, int scale)
|
||||
{
|
||||
return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
|
||||
meta_prefs_get_cursor_theme (),
|
||||
meta_prefs_get_cursor_size ());
|
||||
meta_prefs_get_cursor_size () * scale);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
|
||||
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
{
|
||||
meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||
MetaCursorImage *image,
|
||||
uint8_t *pixels,
|
||||
uint width,
|
||||
uint height,
|
||||
int rowstride,
|
||||
uint32_t gbm_format)
|
||||
{
|
||||
uint64_t cursor_width, cursor_height;
|
||||
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||
|
||||
if (width > cursor_width || height > cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
|
||||
(unsigned int)cursor_width, (unsigned int)cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
||||
{
|
||||
uint8_t buf[4 * cursor_width * cursor_height];
|
||||
uint i;
|
||||
|
||||
image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
|
||||
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
|
||||
|
||||
gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static struct gbm_device *
|
||||
get_gbm_device (void)
|
||||
{
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
uint width, height, rowstride;
|
||||
CoglPixelFormat cogl_format;
|
||||
ClutterBackend *clutter_backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglTexture *texture;
|
||||
CoglError *error = NULL;
|
||||
|
||||
g_assert (self->texture == NULL);
|
||||
|
||||
width = xc_image->width;
|
||||
height = xc_image->height;
|
||||
@@ -235,41 +150,42 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
#endif
|
||||
|
||||
image->hot_x = xc_image->xhot;
|
||||
image->hot_y = xc_image->yhot;
|
||||
|
||||
clutter_backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
image->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
NULL);
|
||||
texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
&error);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
if (gbm)
|
||||
meta_cursor_image_load_gbm_buffer (gbm,
|
||||
image,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
width, height, rowstride,
|
||||
GBM_FORMAT_ARGB8888);
|
||||
#endif
|
||||
if (error)
|
||||
{
|
||||
meta_warning ("Failed to allocate cursor texture: %s\n", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
|
||||
meta_cursor_sprite_set_texture (self, texture,
|
||||
xc_image->xhot, xc_image->yhot);
|
||||
|
||||
if (texture)
|
||||
cogl_object_unref (texture);
|
||||
|
||||
meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
|
||||
}
|
||||
|
||||
static XcursorImage *
|
||||
meta_cursor_reference_get_current_frame_image (MetaCursorReference *self)
|
||||
meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *self)
|
||||
{
|
||||
return self->xcursor_images->images[self->current_frame];
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_reference_tick_frame (MetaCursorReference *self)
|
||||
meta_cursor_sprite_tick_frame (MetaCursorSprite *self)
|
||||
{
|
||||
XcursorImage *image;
|
||||
|
||||
if (!meta_cursor_reference_is_animated (self))
|
||||
if (!meta_cursor_sprite_is_animated (self))
|
||||
return;
|
||||
|
||||
self->current_frame++;
|
||||
@@ -277,198 +193,176 @@ meta_cursor_reference_tick_frame (MetaCursorReference *self)
|
||||
if (self->current_frame >= self->xcursor_images->nimage)
|
||||
self->current_frame = 0;
|
||||
|
||||
meta_cursor_image_free (&self->image);
|
||||
image = meta_cursor_reference_get_current_frame_image (self);
|
||||
meta_cursor_image_load_from_xcursor_image (&self->image, image);
|
||||
image = meta_cursor_sprite_get_current_frame_image (self);
|
||||
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
meta_cursor_sprite_load_from_xcursor_image (self, image);
|
||||
}
|
||||
|
||||
guint
|
||||
meta_cursor_reference_get_current_frame_time (MetaCursorReference *self)
|
||||
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self)
|
||||
{
|
||||
if (!meta_cursor_reference_is_animated (self))
|
||||
if (!meta_cursor_sprite_is_animated (self))
|
||||
return 0;
|
||||
|
||||
return self->xcursor_images->images[self->current_frame]->delay;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_cursor_reference_is_animated (MetaCursorReference *self)
|
||||
meta_cursor_sprite_is_animated (MetaCursorSprite *self)
|
||||
{
|
||||
return (self->xcursor_images &&
|
||||
self->xcursor_images->nimage > 1);
|
||||
}
|
||||
|
||||
MetaCursorSprite *
|
||||
meta_cursor_sprite_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_SPRITE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor_image (MetaCursorReference *cursor)
|
||||
meta_cursor_sprite_load_from_theme (MetaCursorSprite *self)
|
||||
{
|
||||
XcursorImage *image;
|
||||
|
||||
/* Either cursors are loaded from X cursors or buffers. Since
|
||||
* buffers are converted over immediately, we can make sure to
|
||||
* load this directly. */
|
||||
g_assert (cursor->cursor != META_CURSOR_NONE);
|
||||
g_assert (self->cursor != META_CURSOR_NONE);
|
||||
|
||||
if (!cursor->xcursor_images)
|
||||
/* We might be reloading with a different scale. If so clear the old data. */
|
||||
if (self->xcursor_images)
|
||||
{
|
||||
cursor->current_frame = 0;
|
||||
cursor->xcursor_images = load_cursor_on_client (cursor->cursor);
|
||||
if (!cursor->xcursor_images)
|
||||
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
XcursorImagesDestroy (self->xcursor_images);
|
||||
}
|
||||
|
||||
image = meta_cursor_reference_get_current_frame_image (cursor);
|
||||
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
|
||||
self->current_frame = 0;
|
||||
self->xcursor_images = load_cursor_on_client (self->cursor,
|
||||
self->theme_scale);
|
||||
if (!self->xcursor_images)
|
||||
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
|
||||
|
||||
image = meta_cursor_sprite_get_current_frame_image (self);
|
||||
meta_cursor_sprite_load_from_xcursor_image (self, image);
|
||||
|
||||
self->theme_dirty = FALSE;
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_from_theme (MetaCursor cursor)
|
||||
MetaCursorSprite *
|
||||
meta_cursor_sprite_from_theme (MetaCursor cursor)
|
||||
{
|
||||
MetaCursorReference *self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
MetaCursorSprite *self;
|
||||
|
||||
self = meta_cursor_sprite_new ();
|
||||
|
||||
self->cursor = cursor;
|
||||
return self;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
|
||||
image->hot_x = hot_x;
|
||||
image->hot_y = hot_y;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
if (gbm)
|
||||
{
|
||||
uint32_t gbm_format;
|
||||
uint64_t cursor_width, cursor_height;
|
||||
uint width, height;
|
||||
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
|
||||
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#else
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
meta_cursor_image_load_gbm_buffer (gbm,
|
||||
image,
|
||||
(uint8_t *) wl_shm_buffer_get_data (shm_buffer),
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
|
||||
size, so themed cursors must be padded with transparent pixels to fill the
|
||||
overlay. This is trivial if we have CPU access to the data, but it's not
|
||||
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
||||
don't get the right size, we fallback to GL.
|
||||
*/
|
||||
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||
|
||||
if (width != cursor_width || height != cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return;
|
||||
}
|
||||
|
||||
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
|
||||
if (!image->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y);
|
||||
self->theme_dirty = TRUE;
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_cursor_sprite_set_texture (MetaCursorSprite *self,
|
||||
CoglTexture *texture,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
if (texture)
|
||||
self->texture = cogl_object_ref (texture);
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
|
||||
float scale)
|
||||
{
|
||||
self->texture_scale = scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
|
||||
int theme_scale)
|
||||
{
|
||||
if (self->theme_scale != theme_scale)
|
||||
self->theme_dirty = TRUE;
|
||||
self->theme_scale = theme_scale;
|
||||
}
|
||||
|
||||
CoglTexture *
|
||||
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self)
|
||||
{
|
||||
if (!cursor->image.texture)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
|
||||
return COGL_TEXTURE (cursor->image.texture);
|
||||
return COGL_TEXTURE (self->texture);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *
|
||||
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
if (!cursor->image.bo)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
return cursor->image.bo;
|
||||
}
|
||||
#endif
|
||||
|
||||
MetaCursor
|
||||
meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor)
|
||||
meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
|
||||
{
|
||||
return cursor->cursor;
|
||||
return self->cursor;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
*hot_x = self->hot_x;
|
||||
*hot_y = self->hot_y;
|
||||
}
|
||||
|
||||
float
|
||||
meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self)
|
||||
{
|
||||
return self->texture_scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
g_signal_emit (self, signals[PREPARE_AT], 0, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_realize_texture (MetaCursorSprite *self)
|
||||
{
|
||||
if (self->theme_dirty)
|
||||
meta_cursor_sprite_load_from_theme (self);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_sprite_init (MetaCursorSprite *self)
|
||||
{
|
||||
self->texture_scale = 1.0f;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_sprite_finalize (GObject *object)
|
||||
{
|
||||
MetaCursorSprite *self = META_CURSOR_SPRITE (object);
|
||||
|
||||
if (self->xcursor_images)
|
||||
XcursorImagesDestroy (self->xcursor_images);
|
||||
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_cursor_sprite_finalize;
|
||||
|
||||
signals[PREPARE_AT] = g_signal_new ("prepare-at",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
}
|
||||
|
@@ -22,25 +22,54 @@
|
||||
#ifndef META_CURSOR_H
|
||||
#define META_CURSOR_H
|
||||
|
||||
typedef struct _MetaCursorReference MetaCursorReference;
|
||||
|
||||
MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
|
||||
void meta_cursor_reference_unref (MetaCursorReference *cursor);
|
||||
|
||||
#include <meta/common.h>
|
||||
#include <meta/boxes.h>
|
||||
|
||||
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
|
||||
typedef struct _MetaCursorSprite MetaCursorSprite;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <wayland-server.h>
|
||||
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
#endif
|
||||
#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCursorSprite,
|
||||
meta_cursor_sprite,
|
||||
META, CURSOR_SPRITE,
|
||||
GObject);
|
||||
|
||||
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
|
||||
MetaCursorSprite * meta_cursor_sprite_new (void);
|
||||
|
||||
MetaCursorSprite * meta_cursor_sprite_from_theme (MetaCursor cursor);
|
||||
|
||||
|
||||
void meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
|
||||
int scale);
|
||||
|
||||
MetaCursor meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self);
|
||||
|
||||
Cursor meta_cursor_create_x_cursor (Display *xdisplay,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_cursor_sprite_realize_texture (MetaCursorSprite *self);
|
||||
|
||||
void meta_cursor_sprite_set_texture (MetaCursorSprite *self,
|
||||
CoglTexture *texture,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
|
||||
void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
|
||||
float scale);
|
||||
|
||||
CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self);
|
||||
|
||||
void meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
|
||||
float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self);
|
||||
|
||||
gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *self);
|
||||
void meta_cursor_sprite_tick_frame (MetaCursorSprite *self);
|
||||
guint meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self);
|
||||
|
||||
#endif /* META_CURSOR_H */
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -174,7 +174,8 @@ struct _MetaCRTC
|
||||
/* Used when changing configuration */
|
||||
gboolean is_dirty;
|
||||
|
||||
MetaCursorReference *cursor;
|
||||
/* Used by cursor renderer backend */
|
||||
void *cursor_renderer_private;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
@@ -413,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,
|
||||
|
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
|
@@ -37,6 +37,8 @@
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
#include "meta-launcher.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct _MetaBackendNativePrivate
|
||||
{
|
||||
MetaLauncher *launcher;
|
||||
@@ -327,9 +329,14 @@ static void
|
||||
meta_backend_native_init (MetaBackendNative *native)
|
||||
{
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
GError *error = NULL;
|
||||
|
||||
/* We're a display server, so start talking to weston-launch. */
|
||||
priv->launcher = meta_launcher_new ();
|
||||
priv->launcher = meta_launcher_new (&error);
|
||||
if (priv->launcher == NULL)
|
||||
{
|
||||
g_warning ("Can't initialize KMS backend: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
priv->barrier_manager = meta_barrier_manager_native_new ();
|
||||
|
||||
|
@@ -26,11 +26,16 @@
|
||||
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gbm.h>
|
||||
#include <xf86drm.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <meta/util.h>
|
||||
#include <meta/meta-backend.h>
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
#include "meta/boxes.h"
|
||||
|
||||
#ifndef DRM_CAP_CURSOR_WIDTH
|
||||
#define DRM_CAP_CURSOR_WIDTH 0x8
|
||||
@@ -39,11 +44,26 @@
|
||||
#define DRM_CAP_CURSOR_HEIGHT 0x9
|
||||
#endif
|
||||
|
||||
/* When animating a cursor, we usually call drmModeSetCursor2 once per frame.
|
||||
* Though, testing shows that we need to triple buffer the cursor buffer in
|
||||
* order to avoid glitches when animating the cursor, at least when running on
|
||||
* Intel. The reason for this might be (but is not confirmed to be) due to
|
||||
* the user space gbm_bo cache, making us reuse and overwrite the kernel side
|
||||
* buffer content before it was scanned out. To avoid this, we keep a user space
|
||||
* reference to each buffer we set until at least one frame after it was drawn.
|
||||
* In effect, this means we three active cursor gbm_bo's: one that that just has
|
||||
* been set, one that was previously set and may or may not have been scanned
|
||||
* out, and one pending that will be replaced if the cursor sprite changes.
|
||||
*/
|
||||
#define HW_CURSOR_BUFFER_COUNT 3
|
||||
|
||||
static GQuark quark_cursor_sprite = 0;
|
||||
|
||||
struct _MetaCursorRendererNativePrivate
|
||||
{
|
||||
gboolean has_hw_cursor;
|
||||
|
||||
MetaCursorReference *last_cursor;
|
||||
MetaCursorSprite *last_cursor;
|
||||
guint animation_timeout_id;
|
||||
|
||||
int drm_fd;
|
||||
@@ -54,8 +74,25 @@ struct _MetaCursorRendererNativePrivate
|
||||
};
|
||||
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
|
||||
|
||||
typedef enum _MetaCursorGbmBoState
|
||||
{
|
||||
META_CURSOR_GBM_BO_STATE_NONE,
|
||||
META_CURSOR_GBM_BO_STATE_SET,
|
||||
META_CURSOR_GBM_BO_STATE_INVALIDATED,
|
||||
} MetaCursorGbmBoState;
|
||||
|
||||
typedef struct _MetaCursorNativePrivate
|
||||
{
|
||||
guint active_bo;
|
||||
MetaCursorGbmBoState pending_bo_state;
|
||||
struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT];
|
||||
} MetaCursorNativePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static MetaCursorNativePrivate *
|
||||
ensure_cursor_priv (MetaCursorSprite *cursor_sprite);
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_finalize (GObject *object)
|
||||
{
|
||||
@@ -71,63 +108,136 @@ meta_cursor_renderer_native_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static guint
|
||||
get_pending_cursor_sprite_gbm_bo_index (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
return (cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
|
||||
}
|
||||
|
||||
static struct gbm_bo *
|
||||
get_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
guint pending_bo;
|
||||
|
||||
if (!cursor_priv)
|
||||
return NULL;
|
||||
|
||||
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
|
||||
return cursor_priv->bos[pending_bo];
|
||||
}
|
||||
|
||||
static struct gbm_bo *
|
||||
get_active_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 NULL;
|
||||
|
||||
return cursor_priv->bos[cursor_priv->active_bo];
|
||||
}
|
||||
|
||||
static void
|
||||
set_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite,
|
||||
struct gbm_bo *bo)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv;
|
||||
guint pending_bo;
|
||||
|
||||
cursor_priv = ensure_cursor_priv (cursor_sprite);
|
||||
|
||||
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
|
||||
cursor_priv->bos[pending_bo] = bo;
|
||||
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_SET;
|
||||
}
|
||||
|
||||
static void
|
||||
set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
MetaCRTC *crtc,
|
||||
MetaCursorReference *cursor,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
gboolean force)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
if (crtc->cursor == cursor && !force)
|
||||
return;
|
||||
|
||||
crtc->cursor = cursor;
|
||||
|
||||
if (cursor)
|
||||
if (cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
struct gbm_bo *bo;
|
||||
union gbm_bo_handle handle;
|
||||
int hot_x, hot_y;
|
||||
|
||||
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
|
||||
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
|
||||
bo = get_pending_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
else
|
||||
bo = get_active_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
|
||||
if (!force && bo == crtc->cursor_renderer_private)
|
||||
return;
|
||||
|
||||
crtc->cursor_renderer_private = bo;
|
||||
|
||||
handle = gbm_bo_get_handle (bo);
|
||||
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
|
||||
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
|
||||
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
|
||||
|
||||
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
|
||||
{
|
||||
cursor_priv->active_bo =
|
||||
(cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
|
||||
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
|
||||
if (force || crtc->cursor_renderer_private != NULL)
|
||||
{
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
|
||||
crtc->cursor_renderer_private = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_hw_cursor (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
gboolean force)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
const MetaRectangle *cursor_rect = meta_cursor_renderer_get_rect (renderer);
|
||||
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
|
||||
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);
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
else
|
||||
rect = (MetaRectangle) { 0 };
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
gboolean crtc_should_have_cursor;
|
||||
MetaCursorReference *crtc_cursor;
|
||||
gboolean crtc_should_use_cursor;
|
||||
MetaCursorSprite *crtc_cursor;
|
||||
MetaRectangle *crtc_rect;
|
||||
|
||||
crtc_rect = &crtcs[i].rect;
|
||||
|
||||
crtc_should_have_cursor = (priv->has_hw_cursor && meta_rectangle_overlap (cursor_rect, crtc_rect));
|
||||
if (crtc_should_have_cursor)
|
||||
crtc_cursor = cursor;
|
||||
crtc_should_use_cursor = (priv->has_hw_cursor &&
|
||||
meta_rectangle_overlap (&rect, crtc_rect));
|
||||
if (crtc_should_use_cursor)
|
||||
crtc_cursor = cursor_sprite;
|
||||
else
|
||||
crtc_cursor = NULL;
|
||||
|
||||
@@ -136,49 +246,79 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
if (crtc_cursor)
|
||||
{
|
||||
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
|
||||
cursor_rect->x - crtc_rect->x,
|
||||
cursor_rect->y - crtc_rect->y);
|
||||
rect.x - crtc_rect->x,
|
||||
rect.y - crtc_rect->y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_have_hw_cursor (MetaCursorRenderer *renderer)
|
||||
has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
if (cursor)
|
||||
return (meta_cursor_reference_get_gbm_bo (cursor, NULL, NULL) != NULL);
|
||||
else
|
||||
switch (cursor_priv->pending_bo_state)
|
||||
{
|
||||
case META_CURSOR_GBM_BO_STATE_NONE:
|
||||
return get_active_cursor_sprite_gbm_bo (cursor_sprite) != NULL;
|
||||
case META_CURSOR_GBM_BO_STATE_SET:
|
||||
return TRUE;
|
||||
case META_CURSOR_GBM_BO_STATE_INVALIDATED:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_have_hw_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
CoglTexture *texture;
|
||||
|
||||
if (!cursor_sprite)
|
||||
return FALSE;
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
if (meta_cursor_sprite_get_texture_scale (cursor_sprite) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (!has_valid_cursor_sprite_gbm_bo (cursor_sprite))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCursorReference *cursor;
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
|
||||
|
||||
priv->animation_timeout_id = 0;
|
||||
cursor = meta_cursor_renderer_get_cursor (META_CURSOR_RENDERER (native));
|
||||
meta_cursor_reference_tick_frame (cursor);
|
||||
meta_cursor_renderer_force_update (META_CURSOR_RENDERER (native));
|
||||
meta_cursor_renderer_native_force_update (native);
|
||||
meta_cursor_sprite_tick_frame (cursor_sprite);
|
||||
meta_cursor_renderer_force_update (renderer);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native)
|
||||
meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCursorReference *cursor;
|
||||
gboolean cursor_change;
|
||||
guint delay;
|
||||
|
||||
cursor = meta_cursor_renderer_get_cursor (META_CURSOR_RENDERER (native));
|
||||
cursor_change = cursor != priv->last_cursor;
|
||||
priv->last_cursor = cursor;
|
||||
cursor_change = cursor_sprite != priv->last_cursor;
|
||||
priv->last_cursor = cursor_sprite;
|
||||
|
||||
if (!cursor_change && priv->animation_timeout_id)
|
||||
return;
|
||||
@@ -189,9 +329,9 @@ meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native)
|
||||
priv->animation_timeout_id = 0;
|
||||
}
|
||||
|
||||
if (cursor && meta_cursor_reference_is_animated (cursor))
|
||||
if (cursor_sprite && meta_cursor_sprite_is_animated (cursor_sprite))
|
||||
{
|
||||
delay = meta_cursor_reference_get_current_frame_time (cursor);
|
||||
delay = meta_cursor_sprite_get_current_frame_time (cursor_sprite);
|
||||
|
||||
if (delay == 0)
|
||||
return;
|
||||
@@ -206,18 +346,250 @@ meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
|
||||
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
meta_cursor_renderer_native_trigger_frame (native);
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
|
||||
priv->has_hw_cursor = should_have_hw_cursor (renderer);
|
||||
update_hw_cursor (native, FALSE);
|
||||
meta_cursor_renderer_native_trigger_frame (native, cursor_sprite);
|
||||
|
||||
priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite);
|
||||
update_hw_cursor (native, cursor_sprite, FALSE);
|
||||
return priv->has_hw_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
get_hardware_cursor_size (MetaCursorRendererNative *native,
|
||||
uint64_t *width, uint64_t *height)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
*width = priv->cursor_width;
|
||||
*height = priv->cursor_height;
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_priv_free (gpointer data)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv = data;
|
||||
guint i;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
|
||||
g_clear_pointer (&cursor_priv->bos[0], (GDestroyNotify) gbm_bo_destroy);
|
||||
g_slice_free (MetaCursorNativePrivate, cursor_priv);
|
||||
}
|
||||
|
||||
static MetaCursorNativePrivate *
|
||||
ensure_cursor_priv (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
if (!cursor_priv)
|
||||
{
|
||||
cursor_priv = g_slice_new0 (MetaCursorNativePrivate);
|
||||
g_object_set_qdata_full (G_OBJECT (cursor_sprite),
|
||||
quark_cursor_sprite,
|
||||
cursor_priv,
|
||||
cursor_priv_free);
|
||||
}
|
||||
|
||||
return cursor_priv;
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor_sprite_gbm_buffer (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
uint8_t *pixels,
|
||||
uint width,
|
||||
uint height,
|
||||
int rowstride,
|
||||
uint32_t gbm_format)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
uint64_t cursor_width, cursor_height;
|
||||
|
||||
get_hardware_cursor_size (native, &cursor_width, &cursor_height);
|
||||
|
||||
if (width > cursor_width || height > cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
|
||||
(unsigned int)cursor_width, (unsigned int)cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (priv->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
||||
{
|
||||
struct gbm_bo *bo;
|
||||
uint8_t buf[4 * cursor_width * cursor_height];
|
||||
uint i;
|
||||
|
||||
bo = gbm_bo_create (priv->gbm, cursor_width, cursor_height,
|
||||
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||
if (!bo)
|
||||
{
|
||||
meta_warning ("Failed to allocate HW cursor buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
|
||||
if (gbm_bo_write (bo, buf, cursor_width * cursor_height * 4) != 0)
|
||||
{
|
||||
meta_warning ("Failed to write cursors buffer data: %s",
|
||||
g_strerror (errno));
|
||||
gbm_bo_destroy (bo);
|
||||
return;
|
||||
}
|
||||
|
||||
set_pending_cursor_sprite_gbm_bo (cursor_sprite, bo);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
guint pending_bo;
|
||||
|
||||
if (!cursor_priv)
|
||||
return;
|
||||
|
||||
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
|
||||
g_clear_pointer (&cursor_priv->bos[pending_bo],
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
meta_cursor_renderer_native_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
uint32_t gbm_format;
|
||||
uint64_t cursor_width, cursor_height;
|
||||
CoglTexture *texture;
|
||||
uint width, height;
|
||||
|
||||
/* Destroy any previous pending cursor buffer; we'll always either fail (which
|
||||
* should unset, or succeed, which will set new buffer.
|
||||
*/
|
||||
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
uint8_t *buffer_data;
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#else
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
buffer_data = wl_shm_buffer_get_data (shm_buffer);
|
||||
load_cursor_sprite_gbm_buffer (native,
|
||||
cursor_sprite,
|
||||
buffer_data,
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct gbm_bo *bo;
|
||||
|
||||
/* HW cursors have a predefined size (at least 64x64), which usually is
|
||||
* bigger than cursor theme size, so themed cursors must be padded with
|
||||
* transparent pixels to fill the overlay. This is trivial if we have CPU
|
||||
* access to the data, but it's not possible if the buffer is in GPU
|
||||
* memory (and possibly tiled too), so if we don't get the right size, we
|
||||
* fallback to GL. */
|
||||
get_hardware_cursor_size (native, &cursor_width, &cursor_height);
|
||||
|
||||
if (width != cursor_width || height != cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bo = gbm_bo_import (priv->gbm,
|
||||
GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer,
|
||||
GBM_BO_USE_CURSOR);
|
||||
if (!bo)
|
||||
{
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
set_pending_cursor_sprite_gbm_bo (cursor_sprite, bo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
|
||||
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
|
||||
load_cursor_sprite_gbm_buffer (native,
|
||||
cursor_sprite,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
xc_image->width,
|
||||
xc_image->height,
|
||||
xc_image->width * 4,
|
||||
GBM_FORMAT_ARGB8888);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
|
||||
{
|
||||
@@ -226,6 +598,22 @@ meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
|
||||
|
||||
object_class->finalize = meta_cursor_renderer_native_finalize;
|
||||
renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
|
||||
#ifdef HAVE_WAYLAND
|
||||
renderer_class->realize_cursor_from_wl_buffer =
|
||||
meta_cursor_renderer_native_realize_cursor_from_wl_buffer;
|
||||
#endif
|
||||
renderer_class->realize_cursor_from_xcursor =
|
||||
meta_cursor_renderer_native_realize_cursor_from_xcursor;
|
||||
|
||||
quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
|
||||
}
|
||||
|
||||
static void
|
||||
force_update_hw_cursor (MetaCursorRendererNative *native)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
|
||||
update_hw_cursor (native, meta_cursor_renderer_get_cursor (renderer), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -233,7 +621,7 @@ on_monitors_changed (MetaMonitorManager *monitors,
|
||||
MetaCursorRendererNative *native)
|
||||
{
|
||||
/* Our tracking is all messed up, so force an update. */
|
||||
update_hw_cursor (native, TRUE);
|
||||
force_update_hw_cursor (native);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -278,18 +666,8 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
|
||||
return priv->gbm;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
|
||||
uint64_t *width, uint64_t *height)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
*width = priv->cursor_width;
|
||||
*height = priv->cursor_height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
|
||||
{
|
||||
update_hw_cursor (native, TRUE);
|
||||
force_update_hw_cursor (native);
|
||||
}
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
#include <gudev/gudev.h>
|
||||
|
||||
#include "dbus-utils.h"
|
||||
#include "meta-dbus-login1.h"
|
||||
@@ -54,14 +55,21 @@ struct _MetaLauncher
|
||||
};
|
||||
|
||||
static Login1Session *
|
||||
get_session_proxy (GCancellable *cancellable)
|
||||
get_session_proxy (GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
char *proxy_path;
|
||||
char *session_id;
|
||||
Login1Session *session_proxy;
|
||||
|
||||
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);
|
||||
|
||||
@@ -69,31 +77,39 @@ get_session_proxy (GCancellable *cancellable)
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
proxy_path,
|
||||
cancellable, NULL);
|
||||
cancellable, error);
|
||||
if (!session_proxy)
|
||||
g_prefix_error(error, "Could not get session proxy: ");
|
||||
|
||||
free (proxy_path);
|
||||
|
||||
return session_proxy;
|
||||
}
|
||||
|
||||
static Login1Seat *
|
||||
get_seat_proxy (GCancellable *cancellable)
|
||||
get_seat_proxy (GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return 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, 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);
|
||||
if (!seat)
|
||||
g_prefix_error(error, "Could not get seat proxy: ");
|
||||
|
||||
return seat;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -262,25 +278,108 @@ on_active_changed (Login1Session *session,
|
||||
sync_active (self);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_primary_gpu_path (const gchar *seat_name)
|
||||
{
|
||||
const gchar *subsystems[] = {"drm", NULL};
|
||||
gchar *path = NULL;
|
||||
GList *devices, *tmp;
|
||||
|
||||
GUdevClient *gudev_client = g_udev_client_new (subsystems);
|
||||
GUdevEnumerator *enumerator = g_udev_enumerator_new (gudev_client);
|
||||
|
||||
g_udev_enumerator_add_match_name (enumerator, "card*");
|
||||
g_udev_enumerator_add_match_tag (enumerator, "seat");
|
||||
|
||||
devices = g_udev_enumerator_execute (enumerator);
|
||||
if (!devices)
|
||||
goto out;
|
||||
|
||||
for (tmp = devices; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
GUdevDevice *pci_device;
|
||||
GUdevDevice *dev = tmp->data;
|
||||
gint boot_vga;
|
||||
const gchar *device_seat;
|
||||
|
||||
/* filter out devices that are not character device, like card0-VGA-1 */
|
||||
if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
|
||||
continue;
|
||||
|
||||
device_seat = g_udev_device_get_property (dev, "ID_SEAT");
|
||||
if (!device_seat)
|
||||
{
|
||||
/* when ID_SEAT is not set, it means seat0 */
|
||||
device_seat = "seat0";
|
||||
}
|
||||
else if (g_strcmp0 (device_seat, "seat0") != 0)
|
||||
{
|
||||
/* if the device has been explicitly assigned other seat
|
||||
* than seat0, it is probably the right device to use */
|
||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip devices that do not belong to our seat */
|
||||
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)
|
||||
{
|
||||
/* found the boot_vga device */
|
||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
out:
|
||||
g_object_unref (enumerator);
|
||||
g_object_unref (gudev_client);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_kms_fd (Login1Session *session_proxy,
|
||||
int *fd_out)
|
||||
const gchar *seat_id,
|
||||
int *fd_out,
|
||||
GError **error)
|
||||
{
|
||||
int major, minor;
|
||||
int fd;
|
||||
GError *error = NULL;
|
||||
|
||||
/* XXX -- use udev to find the DRM master device */
|
||||
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
|
||||
g_autofree gchar *path = get_primary_gpu_path (seat_id);
|
||||
if (!path)
|
||||
{
|
||||
g_warning ("Could not stat /dev/dri/card0: %m");
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"could not find drm kms device");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
|
||||
if (!get_device_info_from_path (path, &major, &minor))
|
||||
{
|
||||
g_warning ("Could not open DRM device: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get device info for path %s: %m", path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, error))
|
||||
{
|
||||
g_prefix_error (error, "Could not open DRM device: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -289,28 +388,75 @@ get_kms_fd (Login1Session *session_proxy,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaLauncher *
|
||||
meta_launcher_new (void)
|
||||
static gchar *
|
||||
get_seat_id (GError **error)
|
||||
{
|
||||
MetaLauncher *self = NULL;
|
||||
Login1Session *session_proxy;
|
||||
GError *error = NULL;
|
||||
int kms_fd;
|
||||
char *session_id, *seat_id;
|
||||
int r;
|
||||
|
||||
session_proxy = get_session_proxy (NULL);
|
||||
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
|
||||
r = sd_pid_get_session (0, &session_id);
|
||||
if (r < 0)
|
||||
{
|
||||
g_warning ("Could not take control: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get session for PID: %s", g_strerror (-r));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!get_kms_fd (session_proxy, &kms_fd))
|
||||
goto out;
|
||||
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 (GError **error)
|
||||
{
|
||||
MetaLauncher *self = 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, error);
|
||||
if (!session_proxy)
|
||||
goto fail;
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
free (seat_id);
|
||||
|
||||
self = g_slice_new0 (MetaLauncher);
|
||||
self->session_proxy = g_object_ref (session_proxy);
|
||||
self->seat_proxy = get_seat_proxy (NULL);
|
||||
self->session_proxy = session_proxy;
|
||||
self->seat_proxy = seat_proxy;
|
||||
|
||||
self->session_active = TRUE;
|
||||
|
||||
@@ -320,11 +466,16 @@ meta_launcher_new (void)
|
||||
self);
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
out:
|
||||
g_object_unref (session_proxy);
|
||||
|
||||
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,
|
||||
|
@@ -40,7 +40,11 @@
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "meta-monitor-manager-xrandr.h"
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland.h"
|
||||
#endif
|
||||
|
||||
#include <meta/util.h>
|
||||
#include "display-private.h"
|
||||
@@ -78,6 +82,7 @@ struct _MetaBackendX11Private
|
||||
gchar *keymap_layouts;
|
||||
gchar *keymap_variants;
|
||||
gchar *keymap_options;
|
||||
int locked_group;
|
||||
};
|
||||
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||
|
||||
@@ -269,20 +274,47 @@ handle_host_xevent (MetaBackend *backend,
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
Window xwin = meta_backend_x11_get_xwindow(x11);
|
||||
XEvent xev;
|
||||
|
||||
if (event->xfocus.window == xwin)
|
||||
{
|
||||
/* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
|
||||
* by a KeymapNotify event */
|
||||
XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
|
||||
}
|
||||
#else
|
||||
g_assert_not_reached ();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||
handle_alarm_notify (backend, event);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -418,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 ();
|
||||
|
||||
@@ -427,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)
|
||||
@@ -499,7 +528,20 @@ meta_backend_x11_create_monitor_manager (MetaBackend *backend)
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
switch (priv->mode)
|
||||
{
|
||||
case META_BACKEND_X11_MODE_COMPOSITOR:
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
break;
|
||||
case META_BACKEND_X11_MODE_NESTED:
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -727,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);
|
||||
}
|
||||
|
||||
@@ -740,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);
|
||||
}
|
||||
|
||||
@@ -759,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);
|
||||
}
|
||||
@@ -800,6 +844,20 @@ meta_backend_x11_select_stage_events (MetaBackend *backend)
|
||||
}
|
||||
|
||||
XISelectEvents (priv->xdisplay, xwin, &mask, 1);
|
||||
|
||||
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
|
||||
{
|
||||
/* We have no way of tracking key changes when the stage doesn't have
|
||||
* focus, so we select for KeymapStateMask so that we get a complete
|
||||
* dump of the keyboard state in a KeymapNotify event that immediately
|
||||
* follows each FocusIn (and EnterNotify, but we ignore that.)
|
||||
*/
|
||||
XWindowAttributes xwa;
|
||||
|
||||
XGetWindowAttributes(priv->xdisplay, xwin, &xwa);
|
||||
XSelectInput(priv->xdisplay, xwin,
|
||||
xwa.your_event_mask | FocusChangeMask | KeymapStateMask);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -40,25 +40,29 @@ typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
|
||||
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
|
||||
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
|
||||
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Window xwindow = meta_backend_x11_get_xwindow (backend);
|
||||
|
||||
if (xwindow == None)
|
||||
return FALSE;
|
||||
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
|
||||
if (xwindow == None)
|
||||
{
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean has_server_cursor = FALSE;
|
||||
|
||||
if (cursor_ref)
|
||||
if (cursor_sprite)
|
||||
{
|
||||
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
|
||||
MetaCursor cursor = meta_cursor_sprite_get_meta_cursor (cursor_sprite);
|
||||
|
||||
if (cursor != META_CURSOR_NONE)
|
||||
{
|
||||
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
|
||||
@@ -80,6 +84,9 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
|
||||
priv->server_cursor_visible = has_server_cursor;
|
||||
}
|
||||
|
||||
if (!priv->server_cursor_visible && cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
|
||||
return priv->server_cursor_visible;
|
||||
}
|
||||
|
||||
|
@@ -637,6 +637,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 +837,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 +862,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 +887,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 +1166,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 +1184,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 +1194,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)
|
||||
{
|
||||
|
89
src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
Normal file
89
src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
struct _MetaCursorRendererX11Nested
|
||||
{
|
||||
MetaCursorRenderer parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorRendererX11Nested, meta_cursor_renderer_x11_nested,
|
||||
META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_x11_nested_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Cursor
|
||||
create_empty_cursor (Display *xdisplay)
|
||||
{
|
||||
XcursorImage *image;
|
||||
XcursorPixel *pixels;
|
||||
Cursor xcursor;
|
||||
|
||||
image = XcursorImageCreate (1, 1);
|
||||
if (image == NULL)
|
||||
return None;
|
||||
|
||||
image->xhot = 0;
|
||||
image->yhot = 0;
|
||||
|
||||
pixels = image->pixels;
|
||||
pixels[0] = 0;
|
||||
|
||||
xcursor = XcursorImageLoadCursor (xdisplay, image);
|
||||
XcursorImageDestroy (image);
|
||||
|
||||
return xcursor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_nested_init (MetaCursorRendererX11Nested *x11_nested)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Window xwindow = meta_backend_x11_get_xwindow (backend);
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
Cursor empty_xcursor = create_empty_cursor (xdisplay);
|
||||
XDefineCursor (xdisplay, xwindow, empty_xcursor);
|
||||
XFreeCursor (xdisplay, empty_xcursor);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_nested_class_init (MetaCursorRendererX11NestedClass *klass)
|
||||
{
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->update_cursor = meta_cursor_renderer_x11_nested_update_cursor;
|
||||
}
|
38
src/backends/x11/nested/meta-cursor-renderer-x11-nested.h
Normal file
38
src/backends/x11/nested/meta-cursor-renderer-x11-nested.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_CURSOR_RENDERER_X11_NESTED_NESTED_H
|
||||
#define META_CURSOR_RENDERER_X11_NESTED_NESTED_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/meta-cursor-renderer.h"
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER_X11_NESTED (meta_cursor_renderer_x11_nested_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCursorRendererX11Nested,
|
||||
meta_cursor_renderer_x11_nested,
|
||||
META, CURSOR_RENDERER_X11_NESTED,
|
||||
MetaCursorRenderer);
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_X11_NESTED_NESTED_H */
|
@@ -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
|
||||
|
@@ -152,6 +152,7 @@ file_loaded (GObject *source_object,
|
||||
{
|
||||
MetaBackgroundImage *image = META_BACKGROUND_IMAGE (source_object);
|
||||
GError *error = NULL;
|
||||
CoglError *catch_error = NULL;
|
||||
GTask *task;
|
||||
CoglTexture *texture;
|
||||
GdkPixbuf *pixbuf;
|
||||
@@ -186,9 +187,10 @@ file_loaded (GObject *source_object,
|
||||
has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
|
||||
row_stride,
|
||||
pixels, 0,
|
||||
NULL))
|
||||
&catch_error))
|
||||
{
|
||||
g_warning ("Failed to create texture for background");
|
||||
cogl_error_free (catch_error);
|
||||
cogl_object_unref (texture);
|
||||
}
|
||||
|
||||
|
@@ -17,11 +17,14 @@
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <meta/util.h>
|
||||
#include <meta/meta-background.h>
|
||||
#include <meta/meta-background-image.h>
|
||||
#include "meta-background-private.h"
|
||||
#include "cogl-utils.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
enum
|
||||
{
|
||||
CHANGED,
|
||||
@@ -71,6 +74,8 @@ enum
|
||||
|
||||
G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT)
|
||||
|
||||
static gboolean texture_has_alpha (CoglTexture *texture);
|
||||
|
||||
static GSList *all_backgrounds = NULL;
|
||||
|
||||
static void
|
||||
@@ -474,7 +479,7 @@ get_texture_area (MetaBackground *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
draw_texture (MetaBackground *self,
|
||||
CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -483,6 +488,7 @@ draw_texture (MetaBackground *self,
|
||||
{
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
cairo_rectangle_int_t texture_area;
|
||||
gboolean bare_region_visible;
|
||||
|
||||
get_texture_area (self, monitor_area, texture, &texture_area);
|
||||
|
||||
@@ -503,6 +509,9 @@ draw_texture (MetaBackground *self,
|
||||
- texture_area.y / (float)texture_area.height,
|
||||
(monitor_area->width - texture_area.x) / (float)texture_area.width,
|
||||
(monitor_area->height - texture_area.y) / (float)texture_area.height);
|
||||
|
||||
bare_region_visible = texture_has_alpha (texture);
|
||||
|
||||
/* Draw just the texture */
|
||||
break;
|
||||
case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
|
||||
@@ -513,11 +522,16 @@ draw_texture (MetaBackground *self,
|
||||
texture_area.x + texture_area.width,
|
||||
texture_area.y + texture_area.height,
|
||||
0, 0, 1.0, 1.0);
|
||||
bare_region_visible = texture_has_alpha (texture) || memcmp (&texture_area, monitor_area, sizeof (cairo_rectangle_int_t)) != 0;
|
||||
break;
|
||||
case G_DESKTOP_BACKGROUND_STYLE_NONE:
|
||||
bare_region_visible = TRUE;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached();
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
return bare_region_visible;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -529,6 +543,7 @@ ensure_color_texture (MetaBackground *self)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
CoglError *error = NULL;
|
||||
uint8_t pixels[6];
|
||||
int width, height;
|
||||
|
||||
@@ -569,7 +584,13 @@ ensure_color_texture (MetaBackground *self)
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
width * 3,
|
||||
pixels,
|
||||
NULL));
|
||||
&error));
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
meta_warning ("Failed to allocate color texture: %s\n", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,6 +769,7 @@ meta_background_get_texture (MetaBackground *self,
|
||||
if (monitor->dirty)
|
||||
{
|
||||
CoglError *catch_error = NULL;
|
||||
gboolean bare_region_visible = FALSE;
|
||||
|
||||
if (monitor->texture == NULL)
|
||||
{
|
||||
@@ -783,9 +805,9 @@ meta_background_get_texture (MetaBackground *self,
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, texture2);
|
||||
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (priv->style));
|
||||
|
||||
draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture2, &monitor_area);
|
||||
bare_region_visible = draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture2, &monitor_area);
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
@@ -796,8 +818,7 @@ meta_background_get_texture (MetaBackground *self,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if (texture1 != NULL &&
|
||||
!(texture2 != NULL && priv->blend_factor == 1.0 && !texture_has_alpha (texture2)))
|
||||
if (texture1 != NULL && priv->blend_factor != 1.0)
|
||||
{
|
||||
CoglPipeline *pipeline = create_pipeline (PIPELINE_ADD);
|
||||
cogl_pipeline_set_color4f (pipeline,
|
||||
@@ -808,15 +829,14 @@ meta_background_get_texture (MetaBackground *self,
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, texture1);
|
||||
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (priv->style));
|
||||
|
||||
draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture1, &monitor_area);
|
||||
bare_region_visible = bare_region_visible || draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture1, &monitor_area);
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
|
||||
if (!((texture2 != NULL && priv->blend_factor == 1.0 && !texture_has_alpha (texture2)) ||
|
||||
(texture1 != NULL && !texture_has_alpha (texture1))))
|
||||
if (bare_region_visible)
|
||||
{
|
||||
CoglPipeline *pipeline = create_pipeline (PIPELINE_OVER_REVERSE);
|
||||
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <meta/meta-shadow-factory.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include "cogl-utils.h"
|
||||
#include "region-utils.h"
|
||||
@@ -707,6 +708,7 @@ make_shadow (MetaShadow *shadow,
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
CoglError *error = NULL;
|
||||
int d = get_box_filter_size (shadow->key.radius);
|
||||
int spread = get_shadow_spread (shadow->key.radius);
|
||||
cairo_rectangle_int_t extents;
|
||||
@@ -804,7 +806,13 @@ make_shadow (MetaShadow *shadow,
|
||||
(buffer +
|
||||
(y_offset - shadow->outer_border_top) * buffer_width +
|
||||
(x_offset - shadow->outer_border_left)),
|
||||
NULL));
|
||||
&error));
|
||||
|
||||
if (error)
|
||||
{
|
||||
meta_warning ("Failed to allocate shadow texture: %s\n", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
|
||||
cairo_region_destroy (row_convolve_region);
|
||||
cairo_region_destroy (column_convolve_region);
|
||||
|
@@ -293,8 +293,12 @@ static MetaWindow *
|
||||
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (META_SURFACE_ACTOR_WAYLAND (actor));
|
||||
MetaWaylandSurface *surface = priv->surface;
|
||||
|
||||
return priv->surface->window;
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
return surface->window;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -102,8 +102,7 @@ detach_pixmap (MetaSurfaceActorX11 *self)
|
||||
priv->pixmap = None;
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
cogl_object_unref (priv->texture);
|
||||
priv->texture = NULL;
|
||||
g_clear_pointer (&priv->texture, cogl_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -114,14 +113,20 @@ set_pixmap (MetaSurfaceActorX11 *self,
|
||||
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
CoglError *error = NULL;
|
||||
CoglTexture *texture;
|
||||
|
||||
g_assert (priv->pixmap == None);
|
||||
priv->pixmap = pixmap;
|
||||
|
||||
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, NULL));
|
||||
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, &error));
|
||||
|
||||
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
|
||||
if (error != NULL)
|
||||
{
|
||||
g_warning ("Failed to allocate stex texture: %s", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
|
||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||
|
||||
priv->texture = texture;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1750,9 +1752,17 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
CoglError *error = NULL;
|
||||
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
stride, mask_data, NULL));
|
||||
stride, mask_data, &error));
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Failed to allocate mask texture: %s", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
meta_shaped_texture_set_mask_texture (stex, mask_texture);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -206,8 +206,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;
|
||||
}
|
||||
|
||||
|
@@ -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 },
|
||||
|
@@ -44,7 +44,7 @@ print_version (const gchar *option_name,
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static gchar *plugin = "default";
|
||||
static const char *plugin = "default";
|
||||
|
||||
GOptionEntry mutter_options[] = {
|
||||
{
|
||||
|
@@ -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;
|
||||
|
@@ -152,6 +152,10 @@ const MetaMonitorInfo* meta_screen_get_monitor_for_rect (MetaScreen *screen
|
||||
const MetaMonitorInfo* meta_screen_calculate_monitor_for_window (MetaScreen *screen,
|
||||
MetaWindow *window);
|
||||
|
||||
const MetaMonitorInfo* meta_screen_get_monitor_for_point (MetaScreen *screen,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
|
||||
const MetaMonitorInfo* meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
|
@@ -43,6 +43,7 @@
|
||||
#include <meta/meta-enum-types.h>
|
||||
#include "core.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "boxes-private.h"
|
||||
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
@@ -1255,18 +1256,48 @@ update_num_workspaces (MetaScreen *screen,
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
static void
|
||||
root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
int x,
|
||||
int y,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
const MetaMonitorInfo *monitor;
|
||||
|
||||
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
||||
|
||||
/* Reload the cursor texture if the scale has changed. */
|
||||
if (monitor)
|
||||
meta_cursor_sprite_set_theme_scale (cursor_sprite, monitor->scale);
|
||||
}
|
||||
|
||||
static void
|
||||
manage_root_cursor_sprite_scale (MetaScreen *screen,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
g_signal_connect_object (cursor_sprite,
|
||||
"prepare-at",
|
||||
G_CALLBACK (root_cursor_prepare_at),
|
||||
screen,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_update_cursor (MetaScreen *screen)
|
||||
{
|
||||
MetaDisplay *display = screen->display;
|
||||
MetaCursor cursor = screen->current_cursor;
|
||||
Cursor xcursor;
|
||||
MetaCursorReference *cursor_ref;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (screen);
|
||||
|
||||
cursor_ref = meta_cursor_reference_from_theme (cursor);
|
||||
meta_cursor_tracker_set_root_cursor (tracker, cursor_ref);
|
||||
meta_cursor_reference_unref (cursor_ref);
|
||||
cursor_sprite = meta_cursor_sprite_from_theme (cursor);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
manage_root_cursor_sprite_scale (screen, cursor_sprite);
|
||||
|
||||
meta_cursor_tracker_set_root_cursor (tracker, cursor_sprite);
|
||||
g_object_unref (cursor_sprite);
|
||||
|
||||
/* Set a cursor for X11 applications that don't specify their own */
|
||||
xcursor = meta_display_create_x_cursor (display, cursor);
|
||||
@@ -1454,6 +1485,25 @@ meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
|
||||
return monitor->number;
|
||||
}
|
||||
|
||||
const MetaMonitorInfo *
|
||||
meta_screen_get_monitor_for_point (MetaScreen *screen,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (screen->n_monitor_infos == 1)
|
||||
return &screen->monitor_infos[0];
|
||||
|
||||
for (i = 0; i < screen->n_monitor_infos; i++)
|
||||
{
|
||||
if (POINT_IN_RECT (x, y, screen->monitor_infos[i].rect))
|
||||
return &screen->monitor_infos[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const MetaMonitorInfo*
|
||||
meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
@@ -2051,7 +2101,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
|
||||
@@ -3183,12 +3195,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 +3222,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 +3231,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 +3247,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 +3534,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 +4341,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 +4356,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6272,7 +6301,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 +7039,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)
|
||||
|
@@ -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)
|
||||
|
@@ -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"/>
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -1094,7 +1094,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 +1119,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;
|
||||
|
@@ -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:
|
||||
|
@@ -138,12 +138,19 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
CoglError *error = NULL;
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
cogl_wayland_texture_set_region_from_shm_buffer (buffer->texture,
|
||||
rect.x, rect.y, rect.width, rect.height,
|
||||
shm_buffer,
|
||||
rect.x, rect.y, 0, NULL);
|
||||
rect.x, rect.y, 0, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
meta_warning ("Failed to set texture region: %s\n", error->message);
|
||||
cogl_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
|
@@ -57,8 +57,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,
|
||||
@@ -114,7 +112,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;
|
||||
}
|
||||
@@ -405,8 +403,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 +413,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
|
||||
@@ -537,11 +535,14 @@ data_device_start_drag (struct wl_client *client,
|
||||
drag_source = wl_resource_get_user_data (source_resource);
|
||||
|
||||
if (icon_resource &&
|
||||
meta_wayland_surface_set_role (icon_surface,
|
||||
META_WAYLAND_SURFACE_ROLE_DND,
|
||||
resource,
|
||||
WL_DATA_DEVICE_ERROR_ROLE) != 0)
|
||||
return;
|
||||
!meta_wayland_surface_assign_role (icon_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_DND))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_DATA_DEVICE_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (icon_resource));
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_pointer_set_focus (&seat->pointer, NULL);
|
||||
meta_wayland_data_device_start_drag (data_device, client,
|
||||
@@ -742,12 +743,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);
|
||||
}
|
||||
@@ -909,6 +912,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;
|
||||
|
||||
@@ -957,7 +966,7 @@ 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)
|
||||
|
@@ -55,13 +55,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);
|
||||
|
@@ -477,6 +477,34 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
return handled;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_update_key_state (MetaWaylandKeyboard *keyboard,
|
||||
char *key_vector,
|
||||
int key_vector_len,
|
||||
int offset)
|
||||
{
|
||||
gboolean mods_changed = FALSE;
|
||||
|
||||
int i;
|
||||
for (i = offset; i < key_vector_len * 8; i++)
|
||||
{
|
||||
gboolean set = (key_vector[i/8] & (1 << (i % 8))) != 0;
|
||||
|
||||
/* The 'offset' parameter allows the caller to have the indices
|
||||
* into key_vector to either be X-style (base 8) or evdev (base 0), or
|
||||
* something else (unlikely). We subtract 'offset' to convert to evdev
|
||||
* style, then add 8 to convert the "evdev" style keycode back to
|
||||
* the X-style that xkbcommon expects.
|
||||
*/
|
||||
mods_changed |= xkb_state_update_key (keyboard->xkb_info.state,
|
||||
i - offset + 8,
|
||||
set ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
}
|
||||
|
||||
if (mods_changed)
|
||||
notify_modifiers (keyboard);
|
||||
}
|
||||
|
||||
static void
|
||||
move_resources (struct wl_list *destination, struct wl_list *source)
|
||||
{
|
||||
|
@@ -85,6 +85,10 @@ void meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
gboolean meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event);
|
||||
void meta_wayland_keyboard_update_key_state (MetaWaylandKeyboard *compositor,
|
||||
char *key_vector,
|
||||
int key_vector_len,
|
||||
int offset);
|
||||
|
||||
void meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
MetaWaylandSurface *surface);
|
||||
|
@@ -67,6 +67,15 @@ 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;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation (resource, &pointer_gestures_interface,
|
||||
NULL, NULL);
|
||||
}
|
||||
@@ -76,6 +85,6 @@ meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
wl_global_create (compositor->wayland_display,
|
||||
&_wl_pointer_gestures_interface,
|
||||
META_WL_POINTER_GESTURES_VERSION,
|
||||
META__WL_POINTER_GESTURES_VERSION,
|
||||
NULL, bind_pointer_gestures);
|
||||
}
|
||||
|
@@ -44,20 +44,44 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-popup.h"
|
||||
#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"
|
||||
#include "meta/meta-cursor-tracker.h"
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-cursor-renderer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
|
||||
|
||||
struct _MetaWaylandSurfaceRoleCursor
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
|
||||
int hot_x;
|
||||
int hot_y;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||
meta_wayland_surface_role_cursor,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer);
|
||||
|
||||
static MetaWaylandPointerClient *
|
||||
meta_wayland_pointer_client_new (void)
|
||||
{
|
||||
@@ -205,32 +229,6 @@ sync_focus_surface (MetaWaylandPointer *pointer)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
set_cursor_surface (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
if (pointer->cursor_surface == surface)
|
||||
return;
|
||||
|
||||
if (pointer->cursor_surface)
|
||||
wl_list_remove (&pointer->cursor_surface_destroy_listener.link);
|
||||
|
||||
pointer->cursor_surface = surface;
|
||||
|
||||
if (pointer->cursor_surface)
|
||||
wl_resource_add_destroy_listener (pointer->cursor_surface->resource,
|
||||
&pointer->cursor_surface_destroy_listener);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_cursor_surface_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, cursor_surface_destroy_listener);
|
||||
|
||||
set_cursor_surface (pointer, NULL);
|
||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -349,10 +347,19 @@ static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
|
||||
default_grab_button
|
||||
};
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_on_cursor_changed (MetaCursorTracker *cursor_tracker,
|
||||
MetaWaylandPointer *pointer)
|
||||
{
|
||||
if (pointer->cursor_surface)
|
||||
meta_wayland_surface_update_outputs (pointer->cursor_surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
struct wl_display *display)
|
||||
{
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
ClutterDeviceManager *manager;
|
||||
|
||||
memset (pointer, 0, sizeof *pointer);
|
||||
@@ -366,7 +373,6 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy;
|
||||
|
||||
pointer->cursor_surface = NULL;
|
||||
pointer->cursor_surface_destroy_listener.notify = pointer_handle_cursor_surface_destroy;
|
||||
|
||||
pointer->default_grab.interface = &default_pointer_grab_interface;
|
||||
pointer->default_grab.pointer = pointer;
|
||||
@@ -375,17 +381,26 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
manager = clutter_device_manager_get_default ();
|
||||
pointer->device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
pointer->cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
g_signal_connect (cursor_tracker,
|
||||
"cursor-changed",
|
||||
G_CALLBACK (meta_wayland_pointer_on_cursor_changed),
|
||||
pointer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_release (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (cursor_tracker,
|
||||
(gpointer) meta_wayland_pointer_on_cursor_changed,
|
||||
pointer);
|
||||
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
set_cursor_surface (pointer, NULL);
|
||||
|
||||
g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
|
||||
pointer->display = NULL;
|
||||
pointer->cursor_surface = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -727,34 +742,108 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
*sy = wl_fixed_from_double (yf) / surface->scale;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
|
||||
{
|
||||
if (pointer->cursor_tracker == NULL)
|
||||
return;
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
|
||||
if (pointer->current)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
MetaCursorSprite *cursor_sprite = NULL;
|
||||
|
||||
if (pointer->cursor_surface && pointer->cursor_surface->buffer)
|
||||
if (pointer->cursor_surface)
|
||||
{
|
||||
struct wl_resource *buffer = pointer->cursor_surface->buffer->resource;
|
||||
cursor = meta_cursor_reference_from_buffer (buffer,
|
||||
pointer->hotspot_x,
|
||||
pointer->hotspot_y);
|
||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR (pointer->cursor_surface->role);
|
||||
|
||||
cursor_sprite = cursor_role->cursor_sprite;
|
||||
}
|
||||
else
|
||||
cursor = NULL;
|
||||
|
||||
meta_cursor_tracker_set_window_cursor (pointer->cursor_tracker, cursor);
|
||||
|
||||
if (cursor)
|
||||
meta_cursor_reference_unref (cursor);
|
||||
meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_cursor_tracker_unset_window_cursor (pointer->cursor_tracker);
|
||||
meta_cursor_tracker_unset_window_cursor (cursor_tracker);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor_sprite_texture (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaCursorRenderer *cursor_renderer =
|
||||
meta_backend_get_cursor_renderer (meta_get_backend ());
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
||||
MetaCursorSprite *cursor_sprite = cursor_role->cursor_sprite;
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
CoglContext *cogl_context =
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
CoglTexture *texture;
|
||||
|
||||
if (surface->buffer)
|
||||
{
|
||||
struct wl_resource *buffer;
|
||||
|
||||
buffer = surface->buffer->resource;
|
||||
texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context,
|
||||
buffer,
|
||||
NULL);
|
||||
|
||||
meta_cursor_sprite_set_texture (cursor_sprite,
|
||||
texture,
|
||||
cursor_role->hot_x * surface->scale,
|
||||
cursor_role->hot_y * surface->scale);
|
||||
meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_renderer,
|
||||
cursor_sprite,
|
||||
buffer);
|
||||
cogl_object_unref (texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0);
|
||||
}
|
||||
|
||||
if (cursor_sprite == meta_cursor_tracker_get_displayed_cursor (cursor_tracker))
|
||||
meta_cursor_renderer_force_update (cursor_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
int x,
|
||||
int y,
|
||||
MetaWaylandSurfaceRoleCursor *cursor_role)
|
||||
{
|
||||
MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
|
||||
MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaScreen *screen = display->screen;
|
||||
const MetaMonitorInfo *monitor;
|
||||
|
||||
if (!meta_xwayland_is_xwayland_surface (surface))
|
||||
{
|
||||
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
||||
if (monitor)
|
||||
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
||||
(float)monitor->scale / surface->scale);
|
||||
}
|
||||
meta_wayland_surface_update_outputs (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_set_cursor_surface (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *cursor_surface)
|
||||
{
|
||||
MetaWaylandSurface *prev_cursor_surface;
|
||||
|
||||
prev_cursor_surface = pointer->cursor_surface;
|
||||
pointer->cursor_surface = cursor_surface;
|
||||
|
||||
if (prev_cursor_surface != cursor_surface)
|
||||
{
|
||||
if (prev_cursor_surface)
|
||||
meta_wayland_surface_update_outputs (prev_cursor_surface);
|
||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,7 +852,7 @@ pointer_set_cursor (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
struct wl_resource *surface_resource,
|
||||
int32_t x, int32_t y)
|
||||
int32_t hot_x, int32_t hot_y)
|
||||
{
|
||||
MetaWaylandPointer *pointer = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface;
|
||||
@@ -777,19 +866,38 @@ pointer_set_cursor (struct wl_client *client,
|
||||
if (pointer->focus_serial - serial > G_MAXUINT32 / 2)
|
||||
return;
|
||||
|
||||
if (surface)
|
||||
if (surface &&
|
||||
!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR))
|
||||
{
|
||||
if (meta_wayland_surface_set_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR,
|
||||
resource,
|
||||
WL_POINTER_ERROR_ROLE) != 0)
|
||||
return;
|
||||
wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface_resource));
|
||||
return;
|
||||
}
|
||||
|
||||
pointer->hotspot_x = x;
|
||||
pointer->hotspot_y = y;
|
||||
set_cursor_surface (pointer, surface);
|
||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||
if (surface)
|
||||
{
|
||||
MetaWaylandSurfaceRoleCursor *cursor_role;
|
||||
|
||||
cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
||||
if (!cursor_role->cursor_sprite)
|
||||
{
|
||||
cursor_role->cursor_sprite = meta_cursor_sprite_new ();
|
||||
g_signal_connect_object (cursor_role->cursor_sprite,
|
||||
"prepare-at",
|
||||
G_CALLBACK (cursor_sprite_prepare_at),
|
||||
cursor_role,
|
||||
0);
|
||||
}
|
||||
|
||||
cursor_role->hot_x = hot_x;
|
||||
cursor_role->hot_y = hot_y;
|
||||
|
||||
update_cursor_sprite_texture (surface);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_set_cursor_surface (pointer, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -853,3 +961,99 @@ meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer)
|
||||
grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
return meta_wayland_popup_grab_get_top_popup(grab);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_frame_callbacks (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
|
||||
if (pending->newly_attached)
|
||||
update_cursor_sprite_texture (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cursor_surface_role_is_on_output (MetaWaylandSurfaceRole *role,
|
||||
MetaMonitorInfo *monitor)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (role);
|
||||
MetaWaylandPointer *pointer = &surface->compositor->seat->pointer;
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
MetaCursorRenderer *cursor_renderer =
|
||||
meta_backend_get_cursor_renderer (meta_get_backend ());
|
||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
||||
MetaCursorSprite *displayed_cursor_sprite;
|
||||
MetaRectangle rect;
|
||||
|
||||
if (surface != pointer->cursor_surface)
|
||||
return FALSE;
|
||||
|
||||
displayed_cursor_sprite =
|
||||
meta_cursor_tracker_get_displayed_cursor (cursor_tracker);
|
||||
if (!displayed_cursor_sprite)
|
||||
return FALSE;
|
||||
|
||||
if (cursor_role->cursor_sprite != displayed_cursor_sprite)
|
||||
return FALSE;
|
||||
|
||||
rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
|
||||
cursor_role->cursor_sprite);
|
||||
return meta_rectangle_overlap (&rect, &monitor->rect);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_surface_role_dispose (GObject *object)
|
||||
{
|
||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR (object);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandPointer *pointer = &compositor->seat->pointer;
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (cursor_tracker,
|
||||
(gpointer) cursor_sprite_prepare_at,
|
||||
cursor_role);
|
||||
|
||||
if (pointer->cursor_surface == surface)
|
||||
pointer->cursor_surface = NULL;
|
||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||
|
||||
g_clear_object (&cursor_role->cursor_sprite);
|
||||
|
||||
G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = cursor_surface_role_assigned;
|
||||
surface_role_class->commit = cursor_surface_role_commit;
|
||||
surface_role_class->is_on_output = cursor_surface_role_is_on_output;
|
||||
|
||||
object_class->dispose = cursor_surface_role_dispose;
|
||||
}
|
||||
|
@@ -27,9 +27,16 @@
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-wayland-pointer-gesture-swipe.h"
|
||||
#include "meta-wayland-pointer-gesture-pinch.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||
meta_wayland_surface_role_cursor,
|
||||
META, WAYLAND_SURFACE_ROLE_CURSOR,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
struct _MetaWaylandPointerGrabInterface
|
||||
{
|
||||
void (*focus) (MetaWaylandPointerGrab *grab,
|
||||
@@ -65,10 +72,7 @@ struct _MetaWaylandPointer
|
||||
guint32 focus_serial;
|
||||
guint32 click_serial;
|
||||
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
MetaWaylandSurface *cursor_surface;
|
||||
struct wl_listener cursor_surface_destroy_listener;
|
||||
int hotspot_x, hotspot_y;
|
||||
|
||||
MetaWaylandPointerGrab *grab;
|
||||
MetaWaylandPointerGrab default_grab;
|
||||
@@ -120,8 +124,6 @@ void meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
wl_fixed_t *x,
|
||||
wl_fixed_t *y);
|
||||
|
||||
void meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer);
|
||||
|
||||
void meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
|
||||
struct wl_client *client,
|
||||
struct wl_resource *seat_resource,
|
||||
|
@@ -372,15 +372,6 @@ meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
||||
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat)
|
||||
{
|
||||
if ((seat->capabilities & WL_SEAT_CAPABILITY_POINTER) == 0)
|
||||
return;
|
||||
|
||||
meta_wayland_pointer_update_cursor_surface (&seat->pointer);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface,
|
||||
|
@@ -58,7 +58,6 @@ void meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_seat_repick (MetaWaylandSeat *seat);
|
||||
void meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat);
|
||||
|
||||
gboolean meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface,
|
||||
|
@@ -55,6 +55,11 @@
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
#include "meta-xwayland-private.h"
|
||||
|
||||
typedef struct _MetaWaylandSurfaceRolePrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
} MetaWaylandSurfaceRolePrivate;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
|
||||
@@ -68,24 +73,92 @@ typedef struct
|
||||
struct wl_listener sibling_destroy_listener;
|
||||
} MetaWaylandSubsurfacePlacementOp;
|
||||
|
||||
int
|
||||
meta_wayland_surface_set_role (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceRole role,
|
||||
struct wl_resource *error_resource,
|
||||
uint32_t error_code)
|
||||
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
|
||||
meta_wayland_surface_role,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleSubsurface
|
||||
{
|
||||
if (surface->role == META_WAYLAND_SURFACE_ROLE_NONE ||
|
||||
surface->role == role)
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleSubsurface,
|
||||
meta_wayland_surface_role_subsurface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleXdgSurface
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXdgSurface,
|
||||
meta_wayland_surface_role_xdg_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleXdgPopup
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXdgPopup,
|
||||
meta_wayland_surface_role_xdg_popup,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleWlShellSurface
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleWlShellSurface,
|
||||
meta_wayland_surface_role_wl_shell_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleDND
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND,
|
||||
meta_wayland_surface_role_dnd,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role);
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending);
|
||||
|
||||
static gboolean
|
||||
meta_wayland_surface_role_is_on_output (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *info);
|
||||
|
||||
gboolean
|
||||
meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
GType role_type)
|
||||
{
|
||||
if (!surface->role)
|
||||
{
|
||||
surface->role = role;
|
||||
return 0;
|
||||
MetaWaylandSurfaceRolePrivate *role_priv;
|
||||
|
||||
surface->role = g_object_new (role_type, NULL);
|
||||
role_priv =
|
||||
meta_wayland_surface_role_get_instance_private (surface->role);
|
||||
role_priv->surface = surface;
|
||||
|
||||
meta_wayland_surface_role_assigned (surface->role);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (G_OBJECT_TYPE (surface->role) != role_type)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_resource_post_error (error_resource, error_code,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface->resource));
|
||||
return -1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,18 +240,24 @@ surface_process_damage (MetaWaylandSurface *surface,
|
||||
cairo_region_destroy (scaled_region);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
void
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
if (pending->newly_attached)
|
||||
meta_wayland_seat_update_cursor_surface (surface->compositor->seat);
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
dnd_surface_commit (MetaWaylandSurface *surface,
|
||||
dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -235,12 +314,28 @@ destroy_window (MetaWaylandSurface *surface)
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
queue_surface_actor_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window = surface->window;
|
||||
|
||||
if (surface->role == META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE)
|
||||
queue_surface_actor_frame_callbacks (surface, pending);
|
||||
|
||||
if (META_IS_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE (surface->role))
|
||||
{
|
||||
/* For wl_shell, it's equivalent to an unmap. Semantics
|
||||
* are poorly defined, so we can choose some that are
|
||||
@@ -256,12 +351,6 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (surface->role == META_WAYLAND_SURFACE_ROLE_XDG_POPUP)
|
||||
{
|
||||
/* Ignore commits if we couldn't grab the pointer */
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (surface->buffer == NULL)
|
||||
@@ -274,10 +363,11 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
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 };
|
||||
|
||||
@@ -392,12 +482,16 @@ move_pending_state (MetaWaylandPendingState *from,
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_surface_commit (MetaWaylandSurface *surface,
|
||||
subsurface_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
queue_surface_actor_frame_callbacks (surface, pending);
|
||||
|
||||
if (surface->buffer != NULL)
|
||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||
else
|
||||
@@ -495,8 +589,6 @@ static void
|
||||
apply_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
|
||||
if (pending->newly_attached)
|
||||
{
|
||||
if (!surface->buffer && surface->window)
|
||||
@@ -540,42 +632,20 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
surface->input_region = NULL;
|
||||
}
|
||||
|
||||
/* wl_surface.frame */
|
||||
switch (surface->role)
|
||||
if (surface->role)
|
||||
{
|
||||
case META_WAYLAND_SURFACE_ROLE_NONE:
|
||||
case META_WAYLAND_SURFACE_ROLE_CURSOR:
|
||||
case META_WAYLAND_SURFACE_ROLE_DND:
|
||||
wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_POPUP:
|
||||
case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_SUBSURFACE:
|
||||
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor),
|
||||
&pending->frame_callback_list);
|
||||
break;
|
||||
meta_wayland_surface_role_commit (surface->role, pending);
|
||||
g_assert (wl_list_empty (&pending->frame_callback_list));
|
||||
}
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
|
||||
switch (surface->role)
|
||||
else
|
||||
{
|
||||
case META_WAYLAND_SURFACE_ROLE_NONE:
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_CURSOR:
|
||||
cursor_surface_commit (surface, pending);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_DND:
|
||||
dnd_surface_commit (surface, pending);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_POPUP:
|
||||
case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE:
|
||||
toplevel_surface_commit (surface, pending);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_SUBSURFACE:
|
||||
subsurface_surface_commit (surface, pending);
|
||||
break;
|
||||
/* Since there is no role assigned to the surface yet, keep frame
|
||||
* callbacks queued until a role is assigned and we know how
|
||||
* the surface will be drawn.
|
||||
*/
|
||||
wl_list_insert_list (&surface->pending_frame_callback_list,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
meta_surface_actor_wayland_sync_state (
|
||||
@@ -853,7 +923,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);
|
||||
@@ -884,16 +953,28 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
actor_surface_is_on_output (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *monitor)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
return meta_surface_actor_wayland_is_on_monitor (actor, monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
MetaWaylandOutput *wayland_output = value;
|
||||
MetaWaylandSurface *surface = user_data;
|
||||
MetaSurfaceActorWayland *actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
MetaMonitorInfo *monitor;
|
||||
gboolean is_on_output;
|
||||
|
||||
g_assert (surface->role);
|
||||
|
||||
monitor = wayland_output->monitor_info;
|
||||
if (!monitor)
|
||||
{
|
||||
@@ -901,7 +982,7 @@ update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
is_on_output = meta_surface_actor_wayland_is_on_monitor (actor, monitor);
|
||||
is_on_output = meta_wayland_surface_role_is_on_output (surface->role, monitor);
|
||||
set_surface_is_on_output (surface, wayland_output, is_on_output);
|
||||
}
|
||||
|
||||
@@ -930,6 +1011,9 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
MetaWaylandFrameCallback *cb, *next;
|
||||
|
||||
g_clear_object (&surface->role);
|
||||
|
||||
/* If we still have a window at the time of destruction, that means that
|
||||
* the client is disconnecting, as the resources are destroyed in a random
|
||||
@@ -954,6 +1038,9 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
|
||||
g_hash_table_unref (surface->outputs);
|
||||
|
||||
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
|
||||
if (surface->resource)
|
||||
wl_resource_set_user_data (surface->resource, NULL);
|
||||
|
||||
@@ -968,7 +1055,7 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
if (surface->gtk_surface)
|
||||
wl_resource_destroy (surface->gtk_surface);
|
||||
|
||||
g_slice_free (MetaWaylandSurface, surface);
|
||||
g_object_unref (surface);
|
||||
|
||||
meta_wayland_compositor_repick (compositor);
|
||||
}
|
||||
@@ -979,7 +1066,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||||
struct wl_resource *compositor_resource,
|
||||
guint32 id)
|
||||
{
|
||||
MetaWaylandSurface *surface = g_slice_new0 (MetaWaylandSurface);
|
||||
MetaWaylandSurface *surface = g_object_new (META_TYPE_WAYLAND_SURFACE, NULL);
|
||||
|
||||
surface->compositor = compositor;
|
||||
surface->scale = 1;
|
||||
@@ -990,6 +1077,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||||
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
|
||||
surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
|
||||
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
|
||||
sync_drag_dest_funcs (surface);
|
||||
|
||||
surface->outputs = g_hash_table_new (NULL, NULL);
|
||||
@@ -1279,11 +1368,14 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_wayland_surface_set_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_SURFACE,
|
||||
surface_resource,
|
||||
XDG_SHELL_ERROR_ROLE) != 0)
|
||||
return;
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_XDG_SURFACE))
|
||||
{
|
||||
wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
surface->xdg_surface = wl_resource_create (client, &xdg_surface_interface, wl_resource_get_version (resource), id);
|
||||
wl_resource_set_implementation (surface->xdg_surface, &meta_wayland_xdg_surface_interface, surface, xdg_surface_destructor);
|
||||
@@ -1387,11 +1479,14 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_wayland_surface_set_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_POPUP,
|
||||
surface_resource,
|
||||
XDG_SHELL_ERROR_ROLE) != 0)
|
||||
return;
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_XDG_POPUP))
|
||||
{
|
||||
wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent_surf == NULL ||
|
||||
parent_surf->window == NULL ||
|
||||
@@ -1420,15 +1515,15 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
surface,
|
||||
xdg_popup_destructor);
|
||||
|
||||
surface->xdg_popup = popup_resource;
|
||||
surface->xdg_shell_resource = resource;
|
||||
|
||||
if (!meta_wayland_pointer_can_popup (&seat->pointer, 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,
|
||||
@@ -1727,11 +1822,14 @@ wl_shell_get_shell_surface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_wayland_surface_set_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE,
|
||||
surface_resource,
|
||||
WL_SHELL_ERROR_ROLE) != 0)
|
||||
return;
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
surface->wl_shell_surface = wl_resource_create (client, &wl_shell_surface_interface, wl_resource_get_version (resource), id);
|
||||
wl_resource_set_implementation (surface->wl_shell_surface, &meta_wayland_wl_shell_surface_interface, surface, wl_shell_surface_destructor);
|
||||
@@ -2076,11 +2174,17 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_wayland_surface_set_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_SUBSURFACE,
|
||||
surface_resource,
|
||||
WL_SHELL_ERROR_ROLE) != 0)
|
||||
return;
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE))
|
||||
{
|
||||
/* FIXME: There is no subcompositor "role" error yet, so lets just use something
|
||||
* similar until there is.
|
||||
*/
|
||||
wl_resource_post_error (resource, WL_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
surface->wl_subsurface = wl_resource_create (client, &wl_subsurface_interface, wl_resource_get_version (resource), id);
|
||||
wl_resource_set_implementation (surface->wl_subsurface, &meta_wayland_wl_subsurface_interface, surface, wl_subsurface_destructor);
|
||||
@@ -2290,3 +2394,168 @@ meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_init (MetaWaylandSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_init (MetaWaylandSurfaceRole *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_class_init (MetaWaylandSurfaceRoleClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->commit (surface_role,
|
||||
pending);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_wayland_surface_role_is_on_output (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *monitor)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *klass;
|
||||
|
||||
klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
|
||||
if (klass->is_on_output)
|
||||
return klass->is_on_output (surface_role, monitor);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
|
||||
{
|
||||
MetaWaylandSurfaceRolePrivate *priv =
|
||||
meta_wayland_surface_role_get_instance_private (role);
|
||||
|
||||
return priv->surface;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface)
|
||||
{
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
default_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_frame_callbacks (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_dnd_init (MetaWaylandSurfaceRoleDND *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_dnd_class_init (MetaWaylandSurfaceRoleDNDClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = default_role_assigned;
|
||||
surface_role_class->commit = dnd_surface_commit;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_surface_init (MetaWaylandSurfaceRoleXdgSurface *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_surface_class_init (MetaWaylandSurfaceRoleXdgSurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = toplevel_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_popup_init (MetaWaylandSurfaceRoleXdgPopup *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_popup_class_init (MetaWaylandSurfaceRoleXdgPopupClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = toplevel_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_wl_shell_surface_init (MetaWaylandSurfaceRoleWlShellSurface *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_wl_shell_surface_class_init (MetaWaylandSurfaceRoleWlShellSurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = toplevel_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_subsurface_init (MetaWaylandSurfaceRoleSubsurface *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_subsurface_class_init (MetaWaylandSurfaceRoleSubsurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = subsurface_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
@@ -30,24 +30,67 @@
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-surface-actor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
|
||||
typedef struct _MetaWaylandPendingState MetaWaylandPendingState;
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE (meta_wayland_surface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurface,
|
||||
meta_wayland_surface,
|
||||
META, WAYLAND_SURFACE,
|
||||
GObject);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE (meta_wayland_surface_role_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRole, meta_wayland_surface_role,
|
||||
META, WAYLAND_SURFACE_ROLE, GObject);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*assigned) (MetaWaylandSurfaceRole *surface_role);
|
||||
void (*commit) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending);
|
||||
gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *monitor);
|
||||
};
|
||||
|
||||
struct _MetaWaylandSerial {
|
||||
gboolean set;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WAYLAND_SURFACE_ROLE_NONE,
|
||||
META_WAYLAND_SURFACE_ROLE_SUBSURFACE,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_SURFACE,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_POPUP,
|
||||
META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE,
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR,
|
||||
META_WAYLAND_SURFACE_ROLE_DND,
|
||||
} MetaWaylandSurfaceRole;
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE (meta_wayland_surface_role_subsurface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleSubsurface,
|
||||
meta_wayland_surface_role_subsurface,
|
||||
META, WAYLAND_SURFACE_ROLE_SUBSURFACE,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
typedef struct
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_XDG_SURFACE (meta_wayland_surface_role_xdg_surface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleXdgSurface,
|
||||
meta_wayland_surface_role_xdg_surface,
|
||||
META, WAYLAND_SURFACE_ROLE_XDG_SURFACE,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_XDG_POPUP (meta_wayland_surface_role_xdg_popup_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleXdgPopup,
|
||||
meta_wayland_surface_role_xdg_popup,
|
||||
META, WAYLAND_SURFACE_ROLE_XDG_POPUP,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE (meta_wayland_surface_role_wl_shell_surface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleWlShellSurface,
|
||||
meta_wayland_surface_role_wl_shell_surface,
|
||||
META, WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_DND (meta_wayland_surface_role_dnd_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleDND,
|
||||
meta_wayland_surface_role_dnd,
|
||||
META, WAYLAND_SURFACE_ROLE_DND,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
struct _MetaWaylandPendingState
|
||||
{
|
||||
/* wl_surface.attach */
|
||||
gboolean newly_attached;
|
||||
@@ -71,7 +114,7 @@ typedef struct
|
||||
|
||||
MetaRectangle new_geometry;
|
||||
gboolean has_new_geometry;
|
||||
} MetaWaylandPendingState;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDragDestFuncs
|
||||
{
|
||||
@@ -89,11 +132,13 @@ struct _MetaWaylandDragDestFuncs
|
||||
|
||||
struct _MetaWaylandSurface
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* Generic stuff */
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaWaylandSurfaceRole role;
|
||||
MetaWaylandSurfaceRole *role;
|
||||
MetaWindow *window;
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
@@ -104,6 +149,11 @@ struct _MetaWaylandSurface
|
||||
GList *subsurfaces;
|
||||
GHashTable *outputs;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
struct wl_list pending_frame_callback_list;
|
||||
|
||||
struct {
|
||||
const MetaWaylandDragDestFuncs *funcs;
|
||||
} dnd;
|
||||
@@ -166,10 +216,8 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
|
||||
struct wl_resource *compositor_resource,
|
||||
guint32 id);
|
||||
|
||||
int meta_wayland_surface_set_role (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceRole role,
|
||||
struct wl_resource *error_resource,
|
||||
uint32_t error_code);
|
||||
gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
GType role_type);
|
||||
|
||||
void meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
MetaWindow *window);
|
||||
@@ -197,4 +245,11 @@ void meta_wayland_surface_update_outputs (MetaWaylandSurface *sur
|
||||
|
||||
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending);
|
||||
|
||||
MetaWaylandSurface * meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role);
|
||||
|
||||
#endif
|
||||
|
@@ -44,6 +44,6 @@
|
||||
#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__WL_POINTER_GESTURES_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
|
||||
};
|
||||
@@ -207,6 +207,28 @@ meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||
return meta_wayland_seat_handle_event (compositor->seat, event);
|
||||
}
|
||||
|
||||
/* meta_wayland_compositor_update_key_state:
|
||||
* @compositor: the #MetaWaylandCompositor
|
||||
* @key_vector: bit vector of key states
|
||||
* @key_vector_len: length of @key_vector
|
||||
* @offset: the key for the first evdev keycode is found at this offset in @key_vector
|
||||
*
|
||||
* This function is used to resynchronize the key state that Mutter
|
||||
* is tracking with the actual keyboard state. This is useful, for example,
|
||||
* to handle changes in key state when a nested compositor doesn't
|
||||
* have focus. We need to fix up the XKB modifier tracking and deliver
|
||||
* any modifier changes to clients.
|
||||
*/
|
||||
void
|
||||
meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor,
|
||||
char *key_vector,
|
||||
int key_vector_len,
|
||||
int offset)
|
||||
{
|
||||
meta_wayland_keyboard_update_key_state (&compositor->seat->keyboard,
|
||||
key_vector, key_vector_len, offset);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface)
|
||||
@@ -250,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)
|
||||
@@ -313,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));
|
||||
}
|
||||
|
@@ -39,6 +39,10 @@ void meta_wayland_compositor_update (MetaWaylandComp
|
||||
const ClutterEvent *event);
|
||||
gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event);
|
||||
void meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor,
|
||||
char *key_vector,
|
||||
int key_vector_len,
|
||||
int offset);
|
||||
void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
||||
|
@@ -66,7 +66,7 @@ meta_window_wayland_manage (MetaWindow *window)
|
||||
0);
|
||||
}
|
||||
|
||||
if (window->surface->role == META_WAYLAND_SURFACE_ROLE_XDG_POPUP)
|
||||
if (META_IS_WAYLAND_SURFACE_ROLE_XDG_POPUP (window->surface->role))
|
||||
{
|
||||
MetaWaylandSurface *parent = window->surface->popup.parent;
|
||||
|
||||
@@ -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). */
|
||||
|
@@ -33,13 +33,12 @@
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <meta/errors.h>
|
||||
#include "meta-xwayland-private.h"
|
||||
#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
|
||||
|
||||
@@ -87,6 +86,7 @@ struct _MetaWaylandDataSourceXWayland
|
||||
MetaWaylandDataSource parent;
|
||||
|
||||
MetaSelectionBridge *selection;
|
||||
guint has_utf8_string_atom : 1;
|
||||
};
|
||||
|
||||
struct _MetaXWaylandSelection {
|
||||
@@ -161,7 +161,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)
|
||||
@@ -411,27 +410,33 @@ 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_finish (selection, success);
|
||||
}
|
||||
|
||||
if (!data->incr)
|
||||
x11_selection_data_finish (selection, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -706,7 +711,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);
|
||||
@@ -849,6 +855,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;
|
||||
@@ -882,10 +890,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);
|
||||
}
|
||||
|
||||
@@ -1279,6 +1290,9 @@ 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)
|
||||
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
|
||||
|
@@ -32,18 +32,38 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND (meta_wayland_surface_role_xwayland_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
meta_wayland_surface_role_xwayland,
|
||||
META, WAYLAND_SURFACE_ROLE_XWAYLAND,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleXWayland
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
meta_wayland_surface_role_xwayland,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
static void
|
||||
associate_window_with_surface (MetaWindow *window,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
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))
|
||||
{
|
||||
wl_resource_post_error (surface->resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_surface_set_window (surface, window);
|
||||
window->surface = surface;
|
||||
@@ -61,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)
|
||||
{
|
||||
@@ -144,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,
|
||||
@@ -543,3 +582,53 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
|
||||
g_clear_pointer (&manager->lock_file, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwayland_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
/* See comment in xwayland_surface_commit for why we reply even though the
|
||||
* surface may not be drawn the next frame.
|
||||
*/
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
xwayland_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
/* For Xwayland windows, throttling frames when the window isn't actually
|
||||
* drawn is less useful, because Xwayland still has to do the drawing sent
|
||||
* from the application - the throttling would only be of sending us damage
|
||||
* messages, so we simplify and send frame callbacks after the next paint of
|
||||
* the screen, whether the window was drawn or not.
|
||||
*
|
||||
* Currently it may take a few frames before we draw the window, for not
|
||||
* completely understood reasons, and in that case, not thottling frame
|
||||
* callbacks to drawing has the happy side effect that we avoid showing the
|
||||
* user the initial black frame from when the window is mapped empty.
|
||||
*/
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xwayland_init (MetaWaylandSurfaceRoleXWayland *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xwayland_class_init (MetaWaylandSurfaceRoleXWaylandClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = xwayland_surface_assigned;
|
||||
surface_role_class->commit = xwayland_surface_commit;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -16,6 +16,10 @@
|
||||
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
|
||||
|
@@ -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 },
|
||||
};
|
||||
|
@@ -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;
|
||||
@@ -1735,9 +1732,9 @@ meta_window_x11_update_input_region (MetaWindow *window)
|
||||
region = cairo_region_create ();
|
||||
}
|
||||
else if (n_rects == 1 &&
|
||||
(rects[0].x == 0 ||
|
||||
rects[0].y == 0 ||
|
||||
rects[0].width == priv->client_rect.width ||
|
||||
(rects[0].x == 0 &&
|
||||
rects[0].y == 0 &&
|
||||
rects[0].width == priv->client_rect.width &&
|
||||
rects[0].height == priv->client_rect.height))
|
||||
{
|
||||
/* This is the bounding region case. Keep the
|
||||
|
@@ -507,7 +507,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 +523,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