Compare commits

..

1 Commits

70 changed files with 3462 additions and 3878 deletions

10
.gitignore vendored
View File

@@ -64,10 +64,12 @@ src/meta-dbus-idle-monitor.[ch]
src/meta-dbus-login1.[ch]
src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h
src/xdg-shell-unstable-v*-protocol.c
src/xdg-shell-unstable-v*-server-protocol.h
src/pointer-gestures-unstable-v*-protocol.c
src/pointer-gestures-unstable-v*-server-protocol.h
src/xdg-shell-protocol.c
src/xdg-shell-server-protocol.h
src/pointer-gestures-protocol.c
src/pointer-gestures-server-protocol.h
src/xserver-protocol.c
src/xserver-server-protocol.h
src/meta/meta-version.h
doc/reference/*.args
doc/reference/*.bak

75
NEWS
View File

@@ -1,78 +1,3 @@
3.19.4
======
* Fix updating stacking order when setting transient_for [Jonas; #755606]
* Support screen rotation when supported by the driver [Carlos; #745079]
* Protect against broken WM_CLASS property implementations [Sebastian; #759658]
* Handle wl_pointer v5 events on wayland [Carlos; #760637]
* Implement DND actions on wayland [Carlos; #760805]
* Misc. bug fixes [Jonas, Rui, Ray, Marek; #754711, #756789, #759297, #758613,
#760330, #760476, #759222, #760670]
Contributors:
Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Sebastian Keller, Rui Matos,
Florian Müllner, Jasper St. Pierre, Ray Strode
Translations:
Aurimas Černius [lt]
3.19.3
======
* Correct refresh rate units on KMS/Wayland [Daniel; #758653]
* Fix crash when initial cursor position is not on a monitor [Marek; #756698]
* Fix crash when more CRTs are enabled than outputs connected [Rui; #751638]
* Fix touch pointer emulation on wayland [Carlos; #756754]
* Allow minimizing windows that don't advertise supporting it [Jasper; #758186]
* Force 2-finger scroll by default if available [Bastien; #759304]
* Fix crash during XWayland initialization [Marek; #751845]
* Ensure to send a ConfigureNotify to just mapped windows [Rui; #759492]
* Misc. bug fixes and cleanups [Carlos, Jonas, Lionel; #758239, #758633,
#755503, #759374]
Contributors:
Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Lionel Landwerlin, Rui Matos,
Bastien Nocera, Daniel Stone, Jasper St. Pierre
3.19.2
======
* Fix crash on monitor unplug [Rui; #756796]
* Exit cleanly on initialization errors [Owen; #757311]
* Allow to determine backend setting from session type [Ray; #741666]
* Fix DRM device detection for non-PCI devices [Alban; #754911]
* Don't force placement of windows without buffer on wayland [Marek; #751887]
* Fix initialization of bypass compositor hint [Rui; #758544]
Contributors:
Alban Browaeys, Marek Chalupa, Rui Matos, Florian Müllner, Ray Strode,
Owen W. Taylor
3.19.1
======
* wayland: Allow to trigger popups through keyboard/touch [Carlos; #756296]
* Fix modifiers-only input source switching on Ubuntu [Alberts; #756543]
* Misc. bug fixes [Jonas, Rui, Giovanni, Florian; #756675, #756660, #746420,
#756548, #756796, #757101, #757148]
Contributors:
Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Rui Matos,
Alberts Muktupāvels, Florian Müllner
Translations:
Daniel Șerbănescu [ro]
3.18.1
======
* Misc. crash fixes [Jonas, Rui, Carlos, Owen, Florian; #755096, #754979,
#755490, #754357, #745785, #756642]
* Improve HiDPI support on wayland [Jonas; #755097]
* Fix doubly-scaled cursor on XWayland HiDPI [Jonas; #755099]
* Stop hiding titlebar buttons in dialogs [Florian; #641630]
* Add support for fullscreen/unfullscreen animations [Cosimo; #707248]
* Misc. bug fixes [Rui, Colin, Florian; #743339, #752047, #756074, #756649]
Contributors:
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Colin Walters, Owen W. Taylor
3.18.0
======
* Misc. fixes [Florian, Jonas; #753434]

View File

@@ -1,8 +1,8 @@
AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [19])
m4_define([mutter_micro_version], [4])
m4_define([mutter_minor_version], [18])
m4_define([mutter_micro_version], [0])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@@ -46,7 +46,6 @@ IT_PROG_INTLTOOL([0.41])
AC_PROG_CC
AC_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_SED
AC_HEADER_STDC
PKG_PROG_PKG_CONFIG([0.21])
@@ -59,12 +58,12 @@ CANBERRA_GTK_VERSION=0.26
CLUTTER_PACKAGE=clutter-1.0
MUTTER_PC_MODULES="
gtk+-3.0 >= 3.19.7
gtk+-3.0 >= 3.9.11
gio-unix-2.0 >= 2.35.1
pango >= 1.2.0
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.19.3
$CLUTTER_PACKAGE >= 1.25.1
gsettings-desktop-schemas >= 3.15.92
$CLUTTER_PACKAGE >= 1.23.4
cogl-1.0 >= 1.17.1
upower-glib >= 0.99.0
gnome-desktop-3.0
@@ -220,10 +219,6 @@ AS_IF([test "$have_wayland" = "yes"], [
[AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])])
AC_SUBST([WAYLAND_SCANNER])
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.0],
[ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
])
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])

View File

@@ -1,5 +1,6 @@
desktopfiles_in_files = \
mutter.desktop.in
mutter.desktop.in \
mutter-wayland.desktop.in
desktopfilesdir = $(datadir)/applications
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)

View File

@@ -0,0 +1,17 @@
[Desktop Entry]
Type=Application
_Name=Mutter (wayland compositor)
Exec=mutter --wayland --display-server
NoDisplay=true
# name of loadable control center module
X-GNOME-WMSettingsModule=metacity
# name we put on the WM spec check window
X-GNOME-WMName=Mutter
# back compat only
X-GnomeWMSettingsLibrary=metacity
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=mutter
X-GNOME-Bugzilla-Component=general
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=windowmanager
X-GNOME-Autostart-Notify=true

View File

@@ -1,2 +1 @@
# List of source files that should NOT be translated.
# Please keep this file sorted alphabetically.
data/mutter-wayland.desktop.in

114
po/lt.po
View File

@@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: lt\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2016-01-05 13:43+0000\n"
"PO-Revision-Date: 2016-01-05 18:04+0200\n"
"POT-Creation-Date: 2015-02-28 11:14+0000\n"
"PO-Revision-Date: 2015-02-28 21:34+0200\n"
"Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n"
"Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n"
"Language: lt\n"
@@ -23,7 +23,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
"%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 1.8.6\n"
"X-Generator: Gtranslator 2.91.6\n"
#: ../data/50-mutter-navigation.xml.in.h:1
msgid "Navigation"
@@ -31,39 +31,39 @@ msgstr "Navigacija"
#: ../data/50-mutter-navigation.xml.in.h:2
msgid "Move window to workspace 1"
msgstr "Perkelti langą į darbo sritį Nr.1"
msgstr "Perkelti langą į darbalaukį Nr.1"
#: ../data/50-mutter-navigation.xml.in.h:3
msgid "Move window to workspace 2"
msgstr "Perkelti langą į darbo sritį Nr.2"
msgstr "Perkelti langą į darbalaukį Nr.2"
#: ../data/50-mutter-navigation.xml.in.h:4
msgid "Move window to workspace 3"
msgstr "Perkelti langą į darbo sritį Nr.3"
msgstr "Perkelti langą į darbalaukį Nr.3"
#: ../data/50-mutter-navigation.xml.in.h:5
msgid "Move window to workspace 4"
msgstr "Perkelti langą į darbo sritį Nr.4"
msgstr "Perkelti langą į darbalaukį Nr.4"
#: ../data/50-mutter-navigation.xml.in.h:6
msgid "Move window to last workspace"
msgstr "Perkelti langą į pastarąją darbo sritį"
msgstr "Perkelti langą į pastarąjį darbalaukį"
#: ../data/50-mutter-navigation.xml.in.h:7
msgid "Move window one workspace to the left"
msgstr "Perkelti langą į kairiau esančią darbo sritį"
msgstr "Perkelti langą į kairiau esan darbalaukį"
#: ../data/50-mutter-navigation.xml.in.h:8
msgid "Move window one workspace to the right"
msgstr "Perkelti langą į dešiniau esančią darbo sritį"
msgstr "Perkelti langą į dešiniau esan darbalaukį"
#: ../data/50-mutter-navigation.xml.in.h:9
msgid "Move window one workspace up"
msgstr "Perkelti langą į aukščiau esančią darbo sritį"
msgstr "Perkelti langą į aukščiau esan darbalaukį"
#: ../data/50-mutter-navigation.xml.in.h:10
msgid "Move window one workspace down"
msgstr "Perkelti langą į žemiau esančią darbo sritį"
msgstr "Perkelti langą į žemiau esan darbalaukį"
#: ../data/50-mutter-navigation.xml.in.h:11
msgid "Move window one monitor to the left"
@@ -143,39 +143,39 @@ msgstr "Paslėpti visus įprastinius langus"
#: ../data/50-mutter-navigation.xml.in.h:30
msgid "Switch to workspace 1"
msgstr "Persijungti į darbo sritį Nr.1"
msgstr "Persijungti į darbalaukį Nr.1"
#: ../data/50-mutter-navigation.xml.in.h:31
msgid "Switch to workspace 2"
msgstr "Persijungti į darbo sritį Nr.2"
msgstr "Persijungti į darbalaukį Nr.2"
#: ../data/50-mutter-navigation.xml.in.h:32
msgid "Switch to workspace 3"
msgstr "Persijungti į darbo sritį Nr.3"
msgstr "Persijungti į darbalaukį Nr.3"
#: ../data/50-mutter-navigation.xml.in.h:33
msgid "Switch to workspace 4"
msgstr "Persijungti į darbo sritį Nr.4"
msgstr "Persijungti į darbalaukį Nr.4"
#: ../data/50-mutter-navigation.xml.in.h:34
msgid "Switch to last workspace"
msgstr "Persijungti į pastarąją darbo sritį"
msgstr "Persijungti į pastarąjį darbalaukį"
#: ../data/50-mutter-navigation.xml.in.h:35
msgid "Move to workspace left"
msgstr "Perkelti į darbo sritį kairėje"
msgstr "Perkelti į darbalaukį kairėje"
#: ../data/50-mutter-navigation.xml.in.h:36
msgid "Move to workspace right"
msgstr "Perkelti į darbo sritį dešinėje"
msgstr "Perkelti į darbalaukį dešinėje"
#: ../data/50-mutter-navigation.xml.in.h:37
msgid "Move to workspace above"
msgstr "Perkelti į darbo sritį viršuje"
msgstr "Perkelti į darbalaukį viršuje"
#: ../data/50-mutter-navigation.xml.in.h:38
msgid "Move to workspace below"
msgstr "Perkelti į darbo sritį apačioje"
msgstr "Perkelti į darbalaukį apačioje"
#: ../data/50-mutter-system.xml.in.h:1
msgid "System"
@@ -235,7 +235,7 @@ msgstr "Keisti lango dydį"
#: ../data/50-mutter-windows.xml.in.h:12
msgid "Toggle window on all workspaces or one"
msgstr "Perjungti lango buvimo visose darbo srityse būseną"
msgstr "Perjungti lango buvimo visuose darbalaukiuose būseną"
#: ../data/50-mutter-windows.xml.in.h:13
msgid "Raise window if covered, otherwise lower it"
@@ -272,7 +272,7 @@ msgstr "Mutter"
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
msgid "Modifier to use for extended window management operations"
msgstr "Klavišas, naudojamas kartu su specialiomis lango tvarkymo operacijomis"
msgstr "Klavišas, naudojamas kartu su specialiais lango valdymo veiksmais"
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
msgid ""
@@ -315,7 +315,7 @@ msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
msgid "Workspaces are managed dynamically"
msgstr "Darbo sritys tvarkomos dinamiškai"
msgstr "Darbalaukiai valdomi dinamiškai"
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
msgid ""
@@ -323,21 +323,21 @@ msgid ""
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
"Nusako, ar darbo sritys yra tvarkomos dinamiškai, ar yra pastovus darbo "
"sričių skaičius (nusakomas raktu num-workspaces schemoje org.gnome.desktop."
"wm.preferences)."
"Nusako, ar darbastaliai yra valdomi dinamiškai, ar yra pastovus darbalaukių "
"skaičius (nusakomas raktu num-workspaces schemoje org.gnome.desktop.wm."
"preferences)."
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
msgid "Workspaces only on primary"
msgstr "Darbo sritys tik pagrindiniame"
msgstr "Darbalaukiai tik pagrindiniame"
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr ""
"Nusako, ar darbo sričių perjungimas turi įvykti langams visuose "
"monitoriuose, ar tik langams pagrindiniame monitoriuje."
"Nusako, ar darbalaukių perjungimas turi įvykti langams viusose monitoriuose, "
"ar tik langams pagrindiniame monitoriuje."
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
msgid "No tab popup"
@@ -438,41 +438,46 @@ msgid "Switch to VT 7"
msgstr "Persijungti į VT 7"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
#| msgid "Switch to VT 1"
msgid "Switch to VT 8"
msgstr "Persijungti į VT 8"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
#| msgid "Switch to VT 1"
msgid "Switch to VT 9"
msgstr "Persijungti į VT 9"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
#| msgid "Switch to VT 1"
msgid "Switch to VT 10"
msgstr "Persijungti į VT 10"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
#| msgid "Switch to VT 1"
msgid "Switch to VT 11"
msgstr "Persijungti į VT 11"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
#| msgid "Switch to VT 1"
msgid "Switch to VT 12"
msgstr "Persijungti į VT 12"
#: ../src/backends/meta-monitor-manager.c:518
#: ../src/backends/meta-monitor-manager.c:364
msgid "Built-in display"
msgstr "Integruotas vaizduoklis"
#: ../src/backends/meta-monitor-manager.c:544
#: ../src/backends/meta-monitor-manager.c:391
msgid "Unknown"
msgstr "Nežinomas"
#: ../src/backends/meta-monitor-manager.c:546
#: ../src/backends/meta-monitor-manager.c:393
msgid "Unknown Display"
msgstr "Nežinomas vaizduoklis"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:554
#: ../src/backends/meta-monitor-manager.c:401
#, c-format
msgid "%s %s"
msgstr "%s %s"
@@ -484,7 +489,7 @@ msgstr "%s %s"
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr "Kita kompozicijos tvarkytuvė jau veikia ekrane %i vaizduoklyje „%s“."
msgstr "Kita kompozicijos valdyklė jau veikia ekrane %i vaizduoklyje „%s“."
#: ../src/core/bell.c:185
msgid "Bell event"
@@ -513,40 +518,40 @@ msgstr "_Laukti"
msgid "_Force Quit"
msgstr "_Priverstinai išeiti"
#: ../src/core/display.c:563
#: ../src/core/display.c:562
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Nepavyko atverti X Window sistemos ekrano „%s“\n"
#: ../src/core/main.c:180
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
msgstr "Išjungti susijungimą su sesijos tvarkytuve"
msgstr "Išjungti susijungimą su sesijos valdykle"
#: ../src/core/main.c:186
#: ../src/core/main.c:182
msgid "Replace the running window manager"
msgstr "Pakeisti veikiančią langų tvarkytuvę"
msgstr "Pakeisti veikiančią langų valdyklę"
#: ../src/core/main.c:192
#: ../src/core/main.c:188
msgid "Specify session management ID"
msgstr "Nurodyti sesijos tvarkymo ID"
msgstr "Nurodyti sesijos valdymo ID"
#: ../src/core/main.c:197
#: ../src/core/main.c:193
msgid "X Display to use"
msgstr "Naudotinas X ekranas"
#: ../src/core/main.c:203
#: ../src/core/main.c:199
msgid "Initialize session from savefile"
msgstr "Inicializuoti sesiją iš išsaugojimo failo"
#: ../src/core/main.c:209
#: ../src/core/main.c:205
msgid "Make X calls synchronous"
msgstr "Sinchronizuoti X iškvietimus"
#: ../src/core/main.c:216
#: ../src/core/main.c:212
msgid "Run as a wayland compositor"
msgstr "Vykdyti kaip wayland kompozitorių"
#: ../src/core/main.c:224
#: ../src/core/main.c:220
msgid "Run as a full display server, rather than nested"
msgstr "Vykdyti kaip visą vaizduoklio serverį, o ne vidinį"
@@ -575,21 +580,24 @@ msgstr "Parodyti versiją"
msgid "Mutter plugin to use"
msgstr "Naudojamas Mutter įskiepis"
#: ../src/core/prefs.c:1997
#: ../src/core/prefs.c:2004
#, c-format
msgid "Workspace %d"
msgstr "Darbo sritis %d"
msgstr "Darbalaukis %d"
#: ../src/core/screen.c:526
#: ../src/core/screen.c:525
#, c-format
#| msgid ""
#| "Screen %d on display \"%s\" already has a window manager; try using the --"
#| "replace option to replace the current window manager.\n"
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Vaizduoklis „%s“ jau turi langų tvarkytuvę; pabandykite pakeisti esamą langų "
"tvarkytuvę, naudodami parametrą --replace."
"Vaizduoklis „%s“ jau turi langų valdyklę; pabandykite pakeisti esamą langų "
"valdyklę naudodami parametrą --replace."
#: ../src/core/screen.c:608
#: ../src/core/screen.c:607
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Ekranas %d vaizduoklyje „%s“ netinkamas\n"

3353
po/ro.po

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,6 @@ dist_stacking_DATA = \
tests/stacking/basic-wayland.metatest \
tests/stacking/minimized.metatest \
tests/stacking/mixed-windows.metatest \
tests/stacking/set-parent.metatest \
tests/stacking/override-redirect.metatest
mutter-all.test: tests/mutter-all.test.in

View File

@@ -45,17 +45,19 @@ mutter_built_sources = \
if HAVE_WAYLAND
mutter_built_sources += \
pointer-gestures-unstable-v1-protocol.c \
pointer-gestures-unstable-v1-server-protocol.h \
pointer-gestures-protocol.c \
pointer-gestures-server-protocol.h \
gtk-shell-protocol.c \
gtk-shell-server-protocol.h \
xdg-shell-unstable-v5-protocol.c \
xdg-shell-unstable-v5-server-protocol.h \
xdg-shell-protocol.c \
xdg-shell-server-protocol.h \
$(NULL)
endif
wayland_protocols = \
wayland/protocol/pointer-gestures.xml \
wayland/protocol/gtk-shell.xml \
wayland/protocol/xdg-shell.xml \
$(NULL)
libmutter_la_SOURCES = \
@@ -479,20 +481,6 @@ $(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
--generate-c-code meta-dbus-login1 \
$(srcdir)/org.freedesktop.login1.xml
.SECONDEXPANSION:
define protostability
$(shell echo $1 | sed 's/.*\(\<unstable\>\|\<stable\>\).*/\1/')
endef
define protoname
$(shell echo $1 | sed 's/\([a-z\-]\+\)-[a-z]\+-v[0-9]\+/\1/')
endef
%-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/$$(call protostability,$$*)/$$(call protoname,$$*)/$$*.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-server-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/$$(call protostability,$$*)/$$(call protoname,$$*)/$$*.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml

View File

@@ -24,8 +24,6 @@
#include "config.h"
#include <stdlib.h>
#include <meta/meta-backend.h>
#include "meta-backend-private.h"
#include "meta-input-settings-private.h"
@@ -628,10 +626,7 @@ meta_clutter_init (void)
meta_create_backend ();
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
{
g_warning ("Unable to initialize Clutter.\n");
exit (1);
}
g_error ("Unable to initialize Clutter.\n");
/*
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1

View File

@@ -27,8 +27,6 @@
#include "meta-cursor-renderer.h"
#include <meta/meta-backend.h>
#include <backends/meta-backend-private.h>
#include <backends/meta-monitor-manager-private.h>
#include <meta/util.h>
#include <cogl/cogl.h>
@@ -118,14 +116,6 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
};
}
static gboolean
is_cursor_in_monitors_area (int x, int y)
{
MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (meta_get_backend ());
return meta_monitor_manager_get_monitor_at_point (monitor_manager,
(gfloat) x, (gfloat) y) >= 0;
}
static void
update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
@@ -134,11 +124,6 @@ update_cursor (MetaCursorRenderer *renderer,
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
/* do not render cursor if it is not on any monitor. Such situation
* can occur e. g. after monitor hot-plug */
if (!is_cursor_in_monitors_area (priv->current_x, priv->current_y))
return;
if (cursor_sprite)
meta_cursor_sprite_prepare_at (cursor_sprite,
priv->current_x,

View File

@@ -361,12 +361,12 @@ get_pointer_position_gdk (int *x,
int *y,
int *mods)
{
GdkSeat *gseat;
GdkDeviceManager *gmanager;
GdkDevice *gdevice;
GdkScreen *gscreen;
gseat = gdk_display_get_default_seat (gdk_display_get_default ());
gdevice = gdk_seat_get_pointer (gseat);
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
gdk_device_get_position (gdevice, &gscreen, x, y);
if (mods)

View File

@@ -63,9 +63,9 @@ struct _MetaInputSettingsClass
void (* set_invert_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean inverted);
void (* set_edge_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_scroll_method) (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadScrollMethod mode);
void (* set_scroll_button) (MetaInputSettings *settings,
ClutterInputDevice *device,
guint button);

View File

@@ -395,11 +395,11 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
}
static void
update_touchpad_edge_scroll (MetaInputSettings *input_settings,
ClutterInputDevice *device)
update_touchpad_scroll_method (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
gboolean edge_scroll_enabled;
GDesktopTouchpadScrollMethod method;
MetaInputSettingsPrivate *priv;
if (device &&
@@ -408,19 +408,19 @@ update_touchpad_edge_scroll (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
edge_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "edge-scrolling-enabled");
method = g_settings_get_enum (priv->touchpad_settings, "scroll-method");
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_edge_scroll,
edge_scroll_enabled);
settings_device_set_uint_setting (input_settings, device,
input_settings_class->set_scroll_method,
method);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
(ConfigBoolFunc) input_settings_class->set_edge_scroll,
edge_scroll_enabled);
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
(ConfigUintFunc) input_settings_class->set_scroll_method,
method);
}
}
@@ -429,7 +429,7 @@ update_touchpad_click_method (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
GDesktopTouchpadClickMethod method;
GDesktopTouchpadScrollMethod method;
MetaInputSettingsPrivate *priv;
if (device &&
@@ -645,8 +645,8 @@ meta_input_settings_changed_cb (GSettings *settings,
update_touchpad_tap_enabled (input_settings, NULL);
else if (strcmp (key, "send-events") == 0)
update_touchpad_send_events (input_settings, NULL);
else if (strcmp (key, "edge-scrolling-enabled") == 0)
update_touchpad_edge_scroll (input_settings, NULL);
else if (strcmp (key, "scroll-method") == 0)
update_touchpad_scroll_method (input_settings, NULL);
else if (strcmp (key, "click-method") == 0)
update_touchpad_click_method (input_settings, NULL);
}
@@ -771,7 +771,7 @@ apply_device_settings (MetaInputSettings *input_settings,
update_device_natural_scroll (input_settings, device);
update_touchpad_tap_enabled (input_settings, device);
update_touchpad_send_events (input_settings, device);
update_touchpad_edge_scroll (input_settings, device);
update_touchpad_scroll_method (input_settings, device);
update_touchpad_click_method (input_settings, device);
update_trackball_scroll_button (input_settings, device);

View File

@@ -414,10 +414,6 @@ 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

View File

@@ -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_crtcs);
manager->n_outputs);
/* Walk the list of MetaCRTCs, and build a MetaMonitorInfo
for each of them, unless they reference a rectangle that
@@ -346,23 +346,6 @@ 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)
@@ -370,22 +353,22 @@ meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
int i;
for (i = 0; i < n_old_outputs; i++)
meta_monitor_manager_clear_output (&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]);
}
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)
@@ -393,20 +376,16 @@ meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
int i;
for (i = 0; i < n_old_modes; i++)
meta_monitor_manager_clear_mode (&old_modes[i]);
{
g_free (old_modes[i].name);
if (old_modes[i].driver_notify)
old_modes[i].driver_notify (&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)
@@ -414,7 +393,10 @@ meta_monitor_manager_free_crtc_array (MetaCRTC *old_crtcs,
int i;
for (i = 0; i < n_old_crtcs; i++)
meta_monitor_manager_clear_crtc (&old_crtcs[i]);
{
if (old_crtcs[i].driver_notify)
old_crtcs[i].driver_notify (&old_crtcs[i]);
}
g_free (old_crtcs);
}

View File

@@ -37,8 +37,6 @@
#include "meta-cursor-renderer-native.h"
#include "meta-launcher.h"
#include <stdlib.h>
struct _MetaBackendNativePrivate
{
MetaLauncher *launcher;
@@ -329,15 +327,8 @@ static void
meta_backend_native_init (MetaBackendNative *native)
{
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
GError *error = NULL;
priv->launcher = meta_launcher_new (&error);
if (priv->launcher == NULL)
{
g_warning ("Can't initialize KMS backend: %s\n", error->message);
exit (1);
}
priv->launcher = meta_launcher_new ();
priv->barrier_manager = meta_barrier_manager_native_new ();
priv->up_client = up_client_new ();

View File

@@ -258,9 +258,6 @@ has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
if (!cursor_priv)
return FALSE;
switch (cursor_priv->pending_bo_state)
{
case META_CURSOR_GBM_BO_STATE_NONE:
@@ -276,32 +273,6 @@ has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
return FALSE;
}
static gboolean
cursor_over_transformed_crtc (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaMonitorManager *monitors;
MetaCRTC *crtcs;
unsigned int i, n_crtcs;
MetaRectangle rect;
monitors = meta_monitor_manager_get ();
meta_monitor_manager_get_resources (monitors, NULL, NULL,
&crtcs, &n_crtcs, NULL, NULL);
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
for (i = 0; i < n_crtcs; i++)
{
if (!meta_rectangle_overlap (&rect, &crtcs[i].rect))
continue;
if (crtcs[i].transform != META_MONITOR_TRANSFORM_NORMAL)
return TRUE;
}
return FALSE;
}
static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
@@ -311,9 +282,6 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
if (!cursor_sprite)
return FALSE;
if (cursor_over_transformed_crtc (renderer, cursor_sprite))
return FALSE;
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return FALSE;

View File

@@ -164,36 +164,56 @@ meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native)
monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
}
typedef struct {
MetaIdleMonitorNative *monitor_native;
GList *fired_watches;
} CheckNativeClosure;
static gboolean
check_native_watch (gpointer key,
gpointer value,
gpointer user_data)
{
MetaIdleMonitorWatchNative *watch_native = value;
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native;
CheckNativeClosure *closure = user_data;
gboolean steal;
if (watch->timeout_msec == 0)
{
closure->fired_watches = g_list_prepend (closure->fired_watches, watch);
steal = TRUE;
}
else
{
g_source_set_ready_time (watch_native->timeout_source,
closure->monitor_native->last_event_time +
watch->timeout_msec * 1000);
steal = FALSE;
}
return steal;
}
static void
fire_native_watch (gpointer watch,
gpointer data)
{
_meta_idle_monitor_watch_fire (watch);
}
void
meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor)
{
MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor);
GList *node, *watch_ids;
CheckNativeClosure closure;
monitor_native->last_event_time = g_get_monotonic_time ();
watch_ids = g_hash_table_get_keys (monitor->watches);
closure.monitor_native = monitor_native;
closure.fired_watches = NULL;
g_hash_table_foreach_steal (monitor->watches, check_native_watch, &closure);
for (node = watch_ids; node != NULL; node = node->next)
{
guint watch_id = GPOINTER_TO_UINT (node->data);
MetaIdleMonitorWatchNative *watch;
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
if (!watch)
continue;
if (watch->base.timeout_msec == 0)
{
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
}
else
{
g_source_set_ready_time (watch->timeout_source,
monitor_native->last_event_time +
watch->base.timeout_msec * 1000);
}
}
g_list_free (watch_ids);
g_list_foreach (closure.fired_watches, fire_native_watch, NULL);
g_list_free (closure.fired_watches);
}

View File

@@ -154,30 +154,30 @@ device_set_click_method (struct libinput_device *libinput_device,
}
static void
meta_input_settings_native_set_edge_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean edge_scrolling_enabled)
meta_input_settings_native_set_scroll_method (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadScrollMethod mode)
{
enum libinput_config_scroll_method scroll_method = 0;
struct libinput_device *libinput_device;
enum libinput_config_scroll_method supported;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
supported = libinput_device_config_scroll_get_methods (libinput_device);
if (supported & LIBINPUT_CONFIG_SCROLL_2FG)
{
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
}
else if (supported & LIBINPUT_CONFIG_SCROLL_EDGE &&
edge_scrolling_enabled)
{
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
}
else
switch (mode)
{
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
}
break;
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
break;
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
break;
default:
g_assert_not_reached ();
return;
}
device_set_scroll_method (libinput_device, scroll_method);
}
@@ -252,7 +252,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
input_settings_class->set_left_handed = meta_input_settings_native_set_left_handed;
input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled;
input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_native_set_edge_scroll;
input_settings_class->set_scroll_method = meta_input_settings_native_set_scroll_method;
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
input_settings_class->set_click_method = meta_input_settings_native_set_click_method;
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;

View File

@@ -54,22 +54,30 @@ struct _MetaLauncher
gboolean session_active;
};
static void
report_error_and_die (const char *prefix,
GError *error)
{
/* if a function returns due to g_return_val_if_fail,
* then the error may not be set */
if (error)
g_error ("%s: %s", prefix, error->message);
else
g_error ("%s", prefix);
/* the error is not freed, but it is ok as g_error aborts the process */
}
static Login1Session *
get_session_proxy (GCancellable *cancellable,
GError **error)
get_session_proxy (GCancellable *cancellable)
{
char *proxy_path;
char *session_id;
Login1Session *session_proxy;
GError *error = NULL;
if (sd_pid_get_session (getpid (), &session_id) < 0)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get session ID: %m");
return NULL;
}
return NULL;
proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
@@ -77,9 +85,9 @@ get_session_proxy (GCancellable *cancellable,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
proxy_path,
cancellable, error);
cancellable, &error);
if (!session_proxy)
g_prefix_error(error, "Could not get session proxy: ");
report_error_and_die ("Failed getting session proxy", error);
free (proxy_path);
@@ -87,16 +95,16 @@ get_session_proxy (GCancellable *cancellable,
}
static Login1Seat *
get_seat_proxy (GCancellable *cancellable,
GError **error)
get_seat_proxy (GCancellable *cancellable)
{
GError *error = NULL;
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
cancellable, error);
cancellable, &error);
if (!seat)
g_prefix_error(error, "Could not get seat proxy: ");
report_error_and_die ("Could not get seat proxy", error);
return seat;
}
@@ -297,7 +305,7 @@ get_primary_gpu_path (const gchar *seat_name)
for (tmp = devices; tmp != NULL; tmp = tmp->next)
{
GUdevDevice *platform_device = NULL, *pci_device = NULL;
GUdevDevice *pci_device;
GUdevDevice *dev = tmp->data;
gint boot_vga;
const gchar *device_seat;
@@ -324,27 +332,19 @@ get_primary_gpu_path (const gchar *seat_name)
if (g_strcmp0 (seat_name, device_seat))
continue;
platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
if (platform_device != NULL)
{
path = g_strdup (g_udev_device_get_device_file (dev));
g_object_unref (platform_device);
break;
}
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
if (pci_device != NULL)
{
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
if (boot_vga == 1)
{
/* found the boot_vga device */
path = g_strdup (g_udev_device_get_device_file (dev));
break;
}
if (!pci_device)
continue;
g_object_unref (pci_device);
/* 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;
}
}
@@ -357,114 +357,69 @@ out:
return path;
}
static gboolean
static void
get_kms_fd (Login1Session *session_proxy,
const gchar *seat_id,
int *fd_out,
GError **error)
const gchar *seat_id,
int *fd_out)
{
int major, minor;
int fd;
gchar *path;
GError *error = NULL;
g_autofree gchar *path = get_primary_gpu_path (seat_id);
path = get_primary_gpu_path (seat_id);
if (!path)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"could not find drm kms device");
return FALSE;
}
g_error ("could not find drm kms device");
if (!get_device_info_from_path (path, &major, &minor))
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get device info for path %s: %m", path);
return FALSE;
}
g_error ("Could not stat %s: %m", path);
if (!take_device (session_proxy, major, minor, &fd, NULL, error))
{
g_prefix_error (error, "Could not open DRM device: ");
return FALSE;
}
g_free (path);
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
report_error_and_die ("Could not open DRM device", error);
*fd_out = fd;
return TRUE;
}
static gchar *
get_seat_id (GError **error)
get_seat_id (void)
{
char *session_id, *seat_id;
int r;
char *session_id, *seat_id = NULL;
r = sd_pid_get_session (0, &session_id);
if (r < 0)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get session for PID: %s", g_strerror (-r));
return NULL;
}
if (sd_pid_get_session (0, &session_id) < 0)
return NULL;
r = sd_session_get_seat (session_id, &seat_id);
/* on error the seat_id will remain NULL */
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)
meta_launcher_new (void)
{
MetaLauncher *self = NULL;
Login1Session *session_proxy = NULL;
Login1Seat *seat_proxy = NULL;
char *seat_id = NULL;
gboolean have_control = FALSE;
Login1Session *session_proxy;
char *seat_id;
GError *error = NULL;
int kms_fd;
session_proxy = get_session_proxy (NULL, error);
if (!session_proxy)
goto fail;
session_proxy = get_session_proxy (NULL);
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
report_error_and_die ("Could not take control", error);
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);
seat_id = get_seat_id ();
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;
g_error ("Failed getting seat id");
get_kms_fd (session_proxy, seat_id, &kms_fd);
free (seat_id);
self = g_slice_new0 (MetaLauncher);
self->session_proxy = session_proxy;
self->seat_proxy = seat_proxy;
self->seat_proxy = get_seat_proxy (NULL);
self->session_active = TRUE;
@@ -474,16 +429,8 @@ meta_launcher_new (GError **error)
self);
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
return self;
fail:
if (have_control)
login1_session_call_release_control_sync (session_proxy, NULL, NULL);
g_clear_object (&session_proxy);
g_clear_object (&seat_proxy);
free (seat_id);
return NULL;
}
void

View File

@@ -24,7 +24,7 @@
typedef struct _MetaLauncher MetaLauncher;
MetaLauncher *meta_launcher_new (GError **error);
MetaLauncher *meta_launcher_new (void);
void meta_launcher_free (MetaLauncher *self);
gboolean meta_launcher_activate_session (MetaLauncher *self,

View File

@@ -42,8 +42,6 @@
#include <gudev/gudev.h>
#define ALL_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)
typedef struct {
drmModeConnector *connector;
@@ -68,9 +66,6 @@ typedef struct {
uint32_t underscan_prop_id;
uint32_t underscan_hborder_prop_id;
uint32_t underscan_vborder_prop_id;
uint32_t primary_plane_id;
uint32_t rotation_prop_id;
uint32_t rotation_map[ALL_TRANSFORMS];
} MetaCRTCKms;
struct _MetaMonitorManagerKms
@@ -434,137 +429,6 @@ get_output_scale (MetaMonitorManager *manager,
return compute_scale (output);
}
static int
find_property_index (MetaMonitorManager *manager,
drmModeObjectPropertiesPtr props,
const gchar *prop_name,
drmModePropertyPtr *found)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
unsigned int i;
for (i = 0; i < props->count_props; i++)
{
drmModePropertyPtr prop;
prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
if (!prop)
continue;
if (strcmp (prop->name, prop_name) == 0)
{
*found = prop;
return i;
}
drmModeFreeProperty (prop);
}
return -1;
}
static void
parse_transforms (MetaMonitorManager *manager,
drmModePropertyPtr prop,
MetaCRTC *crtc)
{
MetaCRTCKms *crtc_kms = crtc->driver_private;
int i;
for (i = 0; i < prop->count_enums; i++)
{
int cur = -1;
if (strcmp (prop->enums[i].name, "rotate-0") == 0)
cur = META_MONITOR_TRANSFORM_NORMAL;
else if (strcmp (prop->enums[i].name, "rotate-90") == 0)
cur = META_MONITOR_TRANSFORM_90;
else if (strcmp (prop->enums[i].name, "rotate-180") == 0)
cur = META_MONITOR_TRANSFORM_180;
else if (strcmp (prop->enums[i].name, "rotate-270") == 0)
cur = META_MONITOR_TRANSFORM_270;
if (cur != -1)
{
crtc->all_transforms |= 1 << cur;
crtc_kms->rotation_map[cur] = 1 << prop->enums[i].value;
}
}
}
static gboolean
is_primary_plane (MetaMonitorManager *manager,
drmModeObjectPropertiesPtr props)
{
drmModePropertyPtr prop;
int idx;
idx = find_property_index (manager, props, "type", &prop);
if (idx < 0)
return FALSE;
drmModeFreeProperty (prop);
return props->prop_values[idx] == DRM_PLANE_TYPE_PRIMARY;
}
static void
init_crtc_rotations (MetaMonitorManager *manager,
MetaCRTC *crtc,
unsigned int idx)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
drmModeObjectPropertiesPtr props;
drmModePlaneRes *planes;
drmModePlane *drm_plane;
MetaCRTCKms *crtc_kms;
unsigned int i;
crtc_kms = crtc->driver_private;
planes = drmModeGetPlaneResources(manager_kms->fd);
if (planes == NULL)
return;
for (i = 0; i < planes->count_planes; i++)
{
drmModePropertyPtr prop;
drm_plane = drmModeGetPlane (manager_kms->fd, planes->planes[i]);
if (!drm_plane)
continue;
if ((drm_plane->possible_crtcs & (1 << idx)))
{
props = drmModeObjectGetProperties (manager_kms->fd,
drm_plane->plane_id,
DRM_MODE_OBJECT_PLANE);
if (props && is_primary_plane (manager, props))
{
int rotation_idx;
crtc_kms->primary_plane_id = drm_plane->plane_id;
rotation_idx = find_property_index (manager, props, "rotation", &prop);
if (rotation_idx >= 0)
{
crtc_kms->rotation_prop_id = props->props[rotation_idx];
parse_transforms (manager, prop, crtc);
drmModeFreeProperty (prop);
}
}
if (props)
drmModeFreeObjectProperties (props);
}
drmModeFreePlane (drm_plane);
}
drmModeFreePlaneResources (planes);
}
static void
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
{
@@ -632,18 +496,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
meta_mode->width = mode->hdisplay;
meta_mode->height = mode->vdisplay;
/* Calculate refresh rate in milliHz first for extra precision. */
meta_mode->refresh_rate = (mode->clock * 1000000LL) / mode->htotal;
meta_mode->refresh_rate += (mode->vtotal / 2);
meta_mode->refresh_rate /= mode->vtotal;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
meta_mode->refresh_rate *= 2;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
meta_mode->refresh_rate /= 2;
if (mode->vscan > 1)
meta_mode->refresh_rate /= mode->vscan;
meta_mode->refresh_rate /= 1000.0;
meta_mode->refresh_rate = (1000 * mode->clock /
((float)mode->htotal * mode->vtotal));
meta_mode->driver_private = g_slice_dup (drmModeModeInfo, mode);
meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
@@ -692,7 +546,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
find_crtc_properties (manager_kms, meta_crtc);
init_crtc_rotations (manager, meta_crtc, i);
drmModeFreeCrtc (crtc);
}
@@ -1075,7 +928,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
{
MetaCRTCInfo *crtc_info = crtcs[i];
MetaCRTC *crtc = crtc_info->crtc;
MetaCRTCKms *crtc_kms = crtc->driver_private;
CoglKmsCrtc *cogl_crtc;
crtc->is_dirty = TRUE;
@@ -1148,13 +1000,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
}
if (crtc->all_transforms & (1 << crtc->transform))
drmModeObjectSetProperty (manager_kms->fd,
crtc_kms->primary_plane_id,
DRM_MODE_OBJECT_PLANE,
crtc_kms->rotation_prop_id,
crtc_kms->rotation_map[crtc->transform]);
}
/* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
@@ -1307,8 +1152,6 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
manager_kms->fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
const char *subsystems[2] = { "drm", NULL };
manager_kms->udev = g_udev_client_new (subsystems);
g_signal_connect (manager_kms->udev, "uevent",

View File

@@ -82,7 +82,6 @@ struct _MetaBackendX11Private
gchar *keymap_layouts;
gchar *keymap_variants;
gchar *keymap_options;
int locked_group;
};
typedef struct _MetaBackendX11Private MetaBackendX11Private;
@@ -298,23 +297,15 @@ handle_host_xevent (MetaBackend *backend,
if (event->type == priv->xkb_event_base)
{
XkbEvent *xkb_ev = (XkbEvent *) event;
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
{
switch (xkb_ev->any.xkb_type)
switch (xkb_ev->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;
}
@@ -785,7 +776,6 @@ 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);
}

View File

@@ -107,6 +107,20 @@ set_alarm_enabled (Display *dpy,
XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr);
}
static void
check_x11_watch (gpointer data,
gpointer user_data)
{
MetaIdleMonitorWatchXSync *watch_xsync = data;
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync;
XSyncAlarm alarm = (XSyncAlarm) user_data;
if (watch_xsync->xalarm != alarm)
return;
_meta_idle_monitor_watch_fire (watch);
}
static char *
counter_name_for_device (int device_id)
{
@@ -313,38 +327,13 @@ meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync)
monitor_xsync->alarms = g_hash_table_new (NULL, NULL);
}
static void
check_x11_watches (MetaIdleMonitor *monitor,
XSyncAlarm alarm)
{
GList *node, *watch_ids;
/* we get the keys and do explicit look ups in case
* an early iteration of the loop ends up leading
* to watches from later iterations getting invalidated
*/
watch_ids = g_hash_table_get_keys (monitor->watches);
for (node = watch_ids; node != NULL; node = node->next)
{
guint watch_id = GPOINTER_TO_UINT (node->data);
MetaIdleMonitorWatchXSync *watch;
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
if (watch && watch->xalarm == alarm)
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
}
g_list_free (watch_ids);
}
void
meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor,
XSyncAlarmNotifyEvent *alarm_event)
{
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
XSyncAlarm alarm;
GList *watches;
gboolean has_alarm;
if (alarm_event->state != XSyncAlarmActive)
@@ -369,5 +358,10 @@ meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor,
}
if (has_alarm)
check_x11_watches (monitor, alarm);
{
watches = g_hash_table_get_values (monitor->watches);
g_list_foreach (watches, check_x11_watch, (gpointer) alarm);
g_list_free (watches);
}
}

View File

@@ -199,9 +199,9 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
}
static void
meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean edge_scroll_enabled)
meta_input_settings_x11_set_scroll_method (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadScrollMethod mode)
{
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
guchar *available;
@@ -211,21 +211,26 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings,
if (!available)
return;
if (available[0])
{
values[0] = 1;
}
else if (available[1] && edge_scroll_enabled)
switch (mode)
{
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
break;
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
values[1] = 1;
}
else
{
/* Disabled */
break;
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
values[0] = 1;
break;
default:
g_assert_not_reached ();
}
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, &values, 3);
if ((values[0] && !available[0]) || (values[1] && !available[1]))
g_warning ("Device '%s' does not support scroll mode %d\n",
clutter_input_device_get_device_name (device), mode);
else
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, &values, 3);
meta_XFree (available);
}
@@ -316,7 +321,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
input_settings_class->set_left_handed = meta_input_settings_x11_set_left_handed;
input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled;
input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_x11_set_edge_scroll;
input_settings_class->set_scroll_method = meta_input_settings_x11_set_scroll_method;
input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button;
input_settings_class->set_click_method = meta_input_settings_x11_set_click_method;
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;

View File

@@ -419,6 +419,12 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
}
if (!result)
{
edid_atom = XInternAtom (manager_xrandr->xdisplay, "XFree86_DDC_EDID1_RAWDATA", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
}
if (result)
{
if (len > 0 && len % 128 == 0)
@@ -631,70 +637,6 @@ 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)
{
@@ -831,8 +773,6 @@ 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];
@@ -856,8 +796,44 @@ 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);
output_get_modes (manager, meta_output, output);
output_get_crtcs (manager, meta_output, 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;
}
}
meta_output->n_possible_clones = output->nclone;
meta_output->possible_clones = g_new0 (MetaOutput *, meta_output->n_possible_clones);
@@ -881,10 +857,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
else
meta_output->backlight = -1;
if (meta_output->n_modes == 0 || meta_output->n_possible_crtcs == 0)
meta_monitor_manager_clear_output (meta_output);
else
n_actual_outputs++;
n_actual_outputs++;
}
XRRFreeOutputInfo (output);

View File

@@ -255,31 +255,6 @@ get_actor_private (MetaWindowActor *actor)
return priv;
}
static ClutterTimeline *
actor_animate (ClutterActor *actor,
ClutterAnimationMode mode,
guint duration,
const gchar *first_property,
...)
{
va_list args;
ClutterTransition *transition;
clutter_actor_save_easing_state (actor);
clutter_actor_set_easing_mode (actor, mode);
clutter_actor_set_easing_duration (actor, duration);
va_start (args, first_property);
g_object_set_valist (G_OBJECT (actor), first_property, args);
va_end (args);
transition = clutter_actor_get_transition (actor, first_property);
clutter_actor_restore_easing_state (actor);
return CLUTTER_TIMELINE (transition);
}
static void
on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
{
@@ -296,10 +271,7 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
if (apriv->orig_parent)
{
g_object_ref (a);
clutter_actor_remove_child (clutter_actor_get_parent (a), a);
clutter_actor_add_child (apriv->orig_parent, a);
g_object_unref (a);
clutter_actor_reparent (a, apriv->orig_parent);
apriv->orig_parent = NULL;
}
@@ -388,10 +360,11 @@ switch_workspace (MetaPlugin *plugin,
MetaScreen *screen;
MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
GList *l;
ClutterActor *workspace0 = clutter_actor_new ();
ClutterActor *workspace1 = clutter_actor_new ();
ClutterActor *workspace0 = clutter_group_new ();
ClutterActor *workspace1 = clutter_group_new ();
ClutterActor *stage;
int screen_width, screen_height;
ClutterAnimation *animation;
screen = meta_plugin_get_screen (plugin);
stage = meta_get_stage_for_screen (screen);
@@ -400,15 +373,17 @@ switch_workspace (MetaPlugin *plugin,
&screen_width,
&screen_height);
clutter_actor_set_pivot_point (workspace1, 1.0, 1.0);
clutter_actor_set_anchor_point (workspace1,
screen_width,
screen_height);
clutter_actor_set_position (workspace1,
screen_width,
screen_height);
clutter_actor_set_scale (workspace1, 0.0, 0.0);
clutter_actor_add_child (stage, workspace1);
clutter_actor_add_child (stage, workspace0);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0);
if (from == to)
{
@@ -431,15 +406,12 @@ switch_workspace (MetaPlugin *plugin,
if (win_workspace == to || win_workspace == from)
{
ClutterActor *parent = win_workspace == to ? workspace1 : workspace0;
apriv->orig_parent = clutter_actor_get_parent (actor);
g_object_ref (actor);
clutter_actor_remove_child (clutter_actor_get_parent (actor), actor);
clutter_actor_add_child (parent, actor);
clutter_actor_show (actor);
clutter_actor_set_child_below_sibling (parent, actor, NULL);
g_object_unref (actor);
clutter_actor_reparent (actor,
win_workspace == to ? workspace1 : workspace0);
clutter_actor_show_all (actor);
clutter_actor_raise_top (actor);
}
else if (win_workspace < 0)
{
@@ -459,21 +431,23 @@ switch_workspace (MetaPlugin *plugin,
priv->desktop1 = workspace0;
priv->desktop2 = workspace1;
priv->tml_switch_workspace1 = actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
SWITCH_TIMEOUT,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
animation = clutter_actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
SWITCH_TIMEOUT,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
priv->tml_switch_workspace1 = clutter_animation_get_timeline (animation);
g_signal_connect (priv->tml_switch_workspace1,
"completed",
G_CALLBACK (on_switch_workspace_effect_complete),
plugin);
priv->tml_switch_workspace2 = actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
SWITCH_TIMEOUT,
"scale-x", 0.0,
"scale-y", 0.0,
NULL);
animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
SWITCH_TIMEOUT,
"scale-x", 0.0,
"scale-y", 0.0,
NULL);
priv->tml_switch_workspace2 = clutter_animation_get_timeline (animation);
}
@@ -530,17 +504,19 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
ActorPrivate *apriv = get_actor_private (window_actor);
apriv->tml_minimize = actor_animate (actor,
CLUTTER_EASE_IN_SINE,
MINIMIZE_TIMEOUT,
"scale-x", 0.0,
"scale-y", 0.0,
"x", (double)icon_geometry.x,
"y", (double)icon_geometry.y,
NULL);
animation = clutter_actor_animate (actor,
CLUTTER_EASE_IN_SINE,
MINIMIZE_TIMEOUT,
"scale-x", 0.0,
"scale-y", 0.0,
"x", (double)icon_geometry.x,
"y", (double)icon_geometry.y,
NULL);
apriv->tml_minimize = clutter_animation_get_timeline (animation);
data->plugin = plugin;
data->actor = actor;
g_signal_connect (apriv->tml_minimize, "completed",
@@ -585,6 +561,7 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor)
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
ActorPrivate *apriv = get_actor_private (window_actor);
@@ -593,13 +570,14 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor)
clutter_actor_set_scale (actor, 0.5, 0.5);
clutter_actor_show (actor);
apriv->tml_map = actor_animate (actor,
CLUTTER_EASE_OUT_QUAD,
MAP_TIMEOUT,
"opacity", 255,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
animation = clutter_actor_animate (actor,
CLUTTER_EASE_OUT_QUAD,
MAP_TIMEOUT,
"opacity", 255,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
apriv->tml_map = clutter_animation_get_timeline (animation);
data->actor = actor;
data->plugin = plugin;
g_signal_connect (apriv->tml_map, "completed",
@@ -640,16 +618,18 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
ActorPrivate *apriv = get_actor_private (window_actor);
apriv->tml_destroy = actor_animate (actor,
CLUTTER_EASE_OUT_QUAD,
DESTROY_TIMEOUT,
"opacity", 0,
"scale-x", 0.8,
"scale-y", 0.8,
NULL);
animation = clutter_actor_animate (actor,
CLUTTER_EASE_OUT_QUAD,
DESTROY_TIMEOUT,
"opacity", 0,
"scale-x", 0.8,
"scale-y", 0.8,
NULL);
apriv->tml_destroy = clutter_animation_get_timeline (animation);
data->plugin = plugin;
data->actor = actor;
g_signal_connect (apriv->tml_destroy, "completed",
@@ -722,9 +702,7 @@ show_tile_preview (MetaPlugin *plugin,
clutter_actor_show (preview->actor);
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
clutter_actor_set_child_below_sibling (clutter_actor_get_parent (preview->actor),
preview->actor,
window_actor);
clutter_actor_lower (preview->actor, window_actor);
preview->tile_rect = *tile_rect;
}

View File

@@ -182,25 +182,10 @@ meta_display_handle_event (MetaDisplay *display,
sequence = clutter_event_get_event_sequence (event);
/* Set the pointer emulating sequence on touch begin, if eligible */
if (event->type == CLUTTER_TOUCH_BEGIN)
{
if (sequence_is_pointer_emulated (display, event))
{
/* This is the new pointer emulating sequence */
display->pointer_emulating_sequence = sequence;
}
else if (display->pointer_emulating_sequence == sequence)
{
/* This sequence was "pointer emulating" in a prior incarnation,
* but now it isn't. We unset the pointer emulating sequence at
* this point so the current sequence is not mistaken as pointer
* emulating, while we've ensured that it's been deemed
* "pointer emulating" throughout all of the event processing
* of the previous incarnation.
*/
display->pointer_emulating_sequence = NULL;
}
}
if (event->type == CLUTTER_TOUCH_BEGIN &&
!display->pointer_emulating_sequence &&
sequence_is_pointer_emulated (display, event))
display->pointer_emulating_sequence = sequence;
#ifdef HAVE_WAYLAND
MetaWaylandCompositor *compositor = NULL;
@@ -350,6 +335,11 @@ meta_display_handle_event (MetaDisplay *display,
}
#endif
/* Unset the pointer emulating sequence after its end event is processed */
if (event->type == CLUTTER_TOUCH_END &&
display->pointer_emulating_sequence == sequence)
display->pointer_emulating_sequence = NULL;
display->current_time = CurrentTime;
return bypass_clutter;
}

View File

@@ -80,10 +80,6 @@
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland.h"
# endif
#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND)
#include <systemd/sd-login.h>
#endif
/*
@@ -295,95 +291,6 @@ on_sigterm (gpointer user_data)
return G_SOURCE_REMOVE;
}
#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
static char *
find_logind_session_type (void)
{
char **sessions;
char *session_id;
char *session_type;
int ret, i;
ret = sd_pid_get_session (0, &session_id);
if (ret == 0 && session_id != NULL)
{
ret = sd_session_get_type (session_id, &session_type);
free (session_id);
if (ret < 0)
session_type = NULL;
goto out;
}
session_type = NULL;
ret = sd_uid_get_sessions (getuid (), TRUE, &sessions);
if (ret < 0 || sessions == NULL)
goto out;
for (i = 0; sessions[i] != NULL; i++)
{
ret = sd_session_get_type (sessions[i], &session_type);
if (ret < 0)
continue;
if (g_strcmp0 (session_type, "x11") == 0||
g_strcmp0 (session_type, "wayland") == 0)
break;
g_clear_pointer (&session_type, (GDestroyNotify) free);
}
for (i = 0; sessions[i] != NULL; i++)
free (sessions[i]);
free (sessions);
out:
return session_type;
}
static gboolean
check_for_wayland_session_type (void)
{
char *session_type = NULL;
gboolean is_wayland = FALSE;
session_type = find_logind_session_type ();
if (session_type != NULL)
{
is_wayland = g_strcmp0 (session_type, "wayland") == 0;
free (session_type);
}
return is_wayland;
}
#endif
static void
init_backend (void)
{
gboolean session_type_is_wayland = FALSE;
#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
session_type_is_wayland = check_for_wayland_session_type ();
#endif
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
if (opt_display_server || session_type_is_wayland)
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
else
#endif
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
#ifdef HAVE_WAYLAND
meta_set_is_wayland_compositor (opt_wayland || session_type_is_wayland);
#endif
}
/**
* meta_init: (skip)
*
@@ -416,7 +323,16 @@ meta_init (void)
if (g_getenv ("MUTTER_DEBUG"))
meta_set_debugging (TRUE);
init_backend ();
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
if (opt_display_server)
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
else
#endif
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
#ifdef HAVE_WAYLAND
meta_set_is_wayland_compositor (opt_wayland);
#endif
if (g_get_home_dir ())
if (chdir (g_get_home_dir ()) < 0)

View File

@@ -1477,11 +1477,42 @@ button_function_from_string (const char *str)
return META_BUTTON_FUNCTION_MAXIMIZE;
else if (strcmp (str, "close") == 0)
return META_BUTTON_FUNCTION_CLOSE;
else if (strcmp (str, "shade") == 0)
return META_BUTTON_FUNCTION_SHADE;
else if (strcmp (str, "above") == 0)
return META_BUTTON_FUNCTION_ABOVE;
else if (strcmp (str, "stick") == 0)
return META_BUTTON_FUNCTION_STICK;
else
/* don't know; give up */
return META_BUTTON_FUNCTION_LAST;
}
static MetaButtonFunction
button_opposite_function (MetaButtonFunction ofwhat)
{
switch (ofwhat)
{
case META_BUTTON_FUNCTION_SHADE:
return META_BUTTON_FUNCTION_UNSHADE;
case META_BUTTON_FUNCTION_UNSHADE:
return META_BUTTON_FUNCTION_SHADE;
case META_BUTTON_FUNCTION_ABOVE:
return META_BUTTON_FUNCTION_UNABOVE;
case META_BUTTON_FUNCTION_UNABOVE:
return META_BUTTON_FUNCTION_ABOVE;
case META_BUTTON_FUNCTION_STICK:
return META_BUTTON_FUNCTION_UNSTICK;
case META_BUTTON_FUNCTION_UNSTICK:
return META_BUTTON_FUNCTION_STICK;
default:
return META_BUTTON_FUNCTION_LAST;
}
}
static gboolean
button_layout_handler (GVariant *value,
gpointer *result,
@@ -1525,6 +1556,12 @@ button_layout_handler (GVariant *value,
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
{
new_layout.left_buttons_has_spacer[i-1] = TRUE;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
{
new_layout.left_buttons_has_spacer[i-2] = TRUE;
}
}
else
{
@@ -1533,6 +1570,11 @@ button_layout_handler (GVariant *value,
new_layout.left_buttons[i] = f;
used[f] = TRUE;
++i;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
new_layout.left_buttons[i++] = f;
}
else
{
@@ -1576,6 +1618,11 @@ button_layout_handler (GVariant *value,
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
{
new_layout.right_buttons_has_spacer[i-1] = TRUE;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
{
new_layout.right_buttons_has_spacer[i-2] = TRUE;
}
}
else
{
@@ -1584,6 +1631,12 @@ button_layout_handler (GVariant *value,
new_layout.right_buttons[i] = f;
used[f] = TRUE;
++i;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
new_layout.right_buttons[i++] = f;
}
else
{

View File

@@ -1579,10 +1579,8 @@ implement_showing (MetaWindow *window,
* windows we might want to know where they are on the screen,
* so we should place the window even if we're hiding it rather
* than showing it.
* Force placing windows only when they should be already mapped,
* see #751887
*/
if (!window->placed && client_window_should_be_mapped (window))
if (!window->placed)
meta_window_force_placement (window);
meta_window_hide (window);
@@ -3536,7 +3534,10 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
{
const MetaMonitorInfo *old, *new;
if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
if (window->type == META_WINDOW_DESKTOP)
return;
if (window->override_redirect)
{
meta_window_update_monitor (window, FALSE);
return;
@@ -5302,11 +5303,6 @@ meta_window_recalc_features (MetaWindow *window)
meta_window_recalc_skip_features (window);
/* To prevent users from losing windows, let's prevent users from
* minimizing skip-taskbar windows through the window decorations. */
if (window->skip_taskbar)
window->has_minimize_func = FALSE;
meta_topic (META_DEBUG_WINDOW_OPS,
"Window %s decorated = %d border_only = %d has_close = %d has_minimize = %d has_maximize = %d has_move = %d has_shade = %d skip_taskbar = %d skip_pager = %d\n",
window->desc,
@@ -7417,14 +7413,14 @@ meta_window_set_transient_for (MetaWindow *window,
}
}
/* We know this won't create a reference cycle because we check for loops */
g_clear_object (&window->transient_for);
window->transient_for = parent ? g_object_ref (parent) : NULL;
/* update stacking constraints */
if (!window->override_redirect)
meta_stack_update_transient (window->screen->stack, window);
/* We know this won't create a reference cycle because we check for loops */
g_clear_object (&window->transient_for);
window->transient_for = parent ? g_object_ref (parent) : NULL;
/* possibly change its group. We treat being a window's transient as
* equivalent to making it your group leader, to work around shortcomings
* in programs such as xmms-- see #328211.
@@ -7435,7 +7431,7 @@ meta_window_set_transient_for (MetaWindow *window,
meta_window_group_leader_changed (window);
if (!window->constructing && !window->override_redirect)
meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
if (meta_window_appears_focused (window) && window->transient_for != NULL)
meta_window_propagate_focus_appearance (window, TRUE);
@@ -7674,29 +7670,13 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
MetaDisplay *display = window->display;
gboolean unmodified;
gboolean is_window_grab;
ClutterModifierType grab_mods, event_mods;
gfloat x, y;
guint button;
if (window->frame && meta_ui_frame_handle_event (window->frame->ui_frame, event))
return;
if (event->type != CLUTTER_BUTTON_PRESS &&
event->type != CLUTTER_TOUCH_BEGIN)
if (event->type != CLUTTER_BUTTON_PRESS)
return;
if (event->type == CLUTTER_TOUCH_BEGIN)
{
ClutterEventSequence *sequence;
button = 1;
sequence = clutter_event_get_event_sequence (event);
if (!meta_display_is_pointer_emulating_sequence (window->display, sequence))
return;
}
else
button = clutter_event_get_button (event);
if (display->grab_op != META_GRAB_OP_NONE)
return;
@@ -7707,22 +7687,6 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
if (window->override_redirect)
return;
/* Don't focus panels--they must explicitly request focus.
* See bug 160470
*/
if (window->type != META_WINDOW_DOCK)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s due to button %u press (display.c)\n",
window->desc, button);
meta_window_focus (window, event->any.time);
}
else
/* However, do allow terminals to lose focus due to new
* window mappings after the user clicks on a panel.
*/
display->allow_terminal_deactivation = TRUE;
/* We have three passive button grabs:
* - on any button, without modifiers => focuses and maybe raises the window
* - on resize button, with modifiers => start an interactive resizing
@@ -7743,12 +7707,9 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
* care about. Just let the event through.
*/
grab_mods = meta_display_get_window_grab_modifiers (display);
event_mods = clutter_event_get_state (event);
unmodified = (event_mods & grab_mods) == 0;
is_window_grab = (event_mods & grab_mods) == grab_mods;
clutter_event_get_coords (event, &x, &y);
ClutterModifierType grab_mods = meta_display_get_window_grab_modifiers (display);
unmodified = (event->button.modifier_state & grab_mods) == 0;
is_window_grab = (event->button.modifier_state & grab_mods) == grab_mods;
if (unmodified)
{
@@ -7757,8 +7718,27 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
else
meta_topic (META_DEBUG_FOCUS,
"Not raising window on click due to don't-raise-on-click option\n");
/* Don't focus panels--they must explicitly request focus.
* See bug 160470
*/
if (window->type != META_WINDOW_DOCK)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s due to unmodified button %u press (display.c)\n",
window->desc, event->button.button);
meta_window_focus (window, event->any.time);
}
else
/* However, do allow terminals to lose focus due to new
* window mappings after the user clicks on a panel.
*/
display->allow_terminal_deactivation = TRUE;
meta_verbose ("Allowing events time %u\n",
(unsigned int)event->button.time);
}
else if (is_window_grab && (int) button == meta_prefs_get_mouse_button_resize ())
else if (is_window_grab && (int) event->button.button == meta_prefs_get_mouse_button_resize ())
{
if (window->has_resize_func)
{
@@ -7769,10 +7749,10 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
meta_window_get_frame_rect (window, &frame_rect);
west = x < (frame_rect.x + 1 * frame_rect.width / 3);
east = x > (frame_rect.x + 2 * frame_rect.width / 3);
north = y < (frame_rect.y + 1 * frame_rect.height / 3);
south = y > (frame_rect.y + 2 * frame_rect.height / 3);
west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3);
east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3);
north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3);
south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3);
if (west)
op |= META_GRAB_OP_WINDOW_DIR_WEST;
@@ -7790,21 +7770,23 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
op,
TRUE,
FALSE,
button,
event->button.button,
0,
event->any.time,
x, y);
event->button.x,
event->button.y);
}
}
else if (is_window_grab && (int) button == meta_prefs_get_mouse_button_menu ())
else if (is_window_grab && (int) event->button.button == meta_prefs_get_mouse_button_menu ())
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
meta_window_show_menu (window,
META_WINDOW_MENU_WM,
x, y);
event->button.x,
event->button.y);
}
else if (is_window_grab && (int) button == 1)
else if (is_window_grab && (int) event->button.button == 1)
{
if (window->has_move_func)
{
@@ -7814,10 +7796,11 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
META_GRAB_OP_MOVING,
TRUE,
FALSE,
button,
event->button.button,
0,
event->any.time,
x, y);
event->button.x,
event->button.y);
}
}
}

View File

@@ -372,6 +372,12 @@ typedef enum
* @META_BUTTON_FUNCTION_MINIMIZE: Minimize
* @META_BUTTON_FUNCTION_MAXIMIZE: Maximize
* @META_BUTTON_FUNCTION_CLOSE: Close
* @META_BUTTON_FUNCTION_SHADE: Shade
* @META_BUTTON_FUNCTION_ABOVE: Above
* @META_BUTTON_FUNCTION_STICK: Stick
* @META_BUTTON_FUNCTION_UNSHADE: Unshade
* @META_BUTTON_FUNCTION_UNABOVE: Unabove
* @META_BUTTON_FUNCTION_UNSTICK: Unstick
* @META_BUTTON_FUNCTION_LAST: Marks the end of the #MetaButtonFunction enumeration
*
* Function a window button can have. Note, you can't add stuff here
@@ -384,6 +390,12 @@ typedef enum
META_BUTTON_FUNCTION_MINIMIZE,
META_BUTTON_FUNCTION_MAXIMIZE,
META_BUTTON_FUNCTION_CLOSE,
META_BUTTON_FUNCTION_SHADE,
META_BUTTON_FUNCTION_ABOVE,
META_BUTTON_FUNCTION_STICK,
META_BUTTON_FUNCTION_UNSHADE,
META_BUTTON_FUNCTION_UNABOVE,
META_BUTTON_FUNCTION_UNSTICK,
META_BUTTON_FUNCTION_APPMENU,
META_BUTTON_FUNCTION_LAST
} MetaButtonFunction;
@@ -393,10 +405,10 @@ typedef enum
/* Keep array size in sync with MAX_BUTTONS_PER_CORNER */
/**
* MetaButtonLayout:
* @left_buttons: (array fixed-size=5):
* @right_buttons: (array fixed-size=5):
* @left_buttons_has_spacer: (array fixed-size=5):
* @right_buttons_has_spacer: (array fixed-size=5):
* @left_buttons: (array fixed-size=11):
* @right_buttons: (array fixed-size=11):
* @left_buttons_has_spacer: (array fixed-size=11):
* @right_buttons_has_spacer: (array fixed-size=11):
*/
typedef struct _MetaButtonLayout MetaButtonLayout;
struct _MetaButtonLayout

View File

@@ -58,7 +58,7 @@ typedef enum {
META_SIZE_CHANGE_MAXIMIZE,
META_SIZE_CHANGE_UNMAXIMIZE,
META_SIZE_CHANGE_FULLSCREEN,
META_SIZE_CHANGE_UNFULLSCREEN,
META_SIZE_CHANGE_UNFULLSCREEN
} MetaSizeChange;
MetaCompositor *meta_compositor_new (MetaDisplay *display);

View File

@@ -9,8 +9,6 @@
<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"/>

View File

@@ -1,14 +0,0 @@
new_client 1 wayland
create 1/1
show 1/1
create 1/2
show 1/2
wait
assert_stacking 1/1 1/2
set_parent 1/1 2
wait
assert_stacking 1/2 1/1
local_activate 1/2
assert_stacking 1/2 1/1

View File

@@ -41,16 +41,6 @@ lookup_window (const char *window_id)
return window;
}
static void
on_after_paint (GdkFrameClock *clock,
GMainLoop *loop)
{
g_signal_handlers_disconnect_by_func (clock,
(gpointer) on_after_paint,
loop);
g_main_loop_quit (loop);
}
static void
process_line (const char *line)
{
@@ -136,31 +126,6 @@ process_line (const char *line)
}
}
else if (strcmp (argv[0], "set_parent") == 0)
{
if (argc != 3)
{
g_print ("usage: menu <window-id> <parent-id>");
goto out;
}
GtkWidget *window = lookup_window (argv[1]);
if (!window)
{
g_print ("unknown window %s", argv[1]);
goto out;
}
GtkWidget *parent_window = lookup_window (argv[2]);
if (!parent_window)
{
g_print ("unknown parent window %s", argv[2]);
goto out;
}
gtk_window_set_transient_for (GTK_WINDOW (window),
GTK_WINDOW (parent_window));
}
else if (strcmp (argv[0], "show") == 0)
{
if (argc != 2)
@@ -170,25 +135,10 @@ process_line (const char *line)
}
GtkWidget *window = lookup_window (argv[1]);
GdkWindow *gdk_window = gtk_widget_get_window (window);
if (!window)
goto out;
gtk_widget_show (window);
/* When a Wayland client, we cannot be really sure that the window has
* been mappable until after we have painted. So, in order to have the
* test runner rely on the "show" command to have done what the client
* needs to do in order for a window to be mappable compositor side, lets
* wait with returning until after the first frame.
*/
GdkFrameClock *frame_clock = gdk_window_get_frame_clock (gdk_window);
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_after_paint),
loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
else if (strcmp (argv[0], "hide") == 0)
{

View File

@@ -767,23 +767,6 @@ test_case_do (TestCase *test,
NULL))
return FALSE;
}
else if (strcmp (argv[0], "set_parent") == 0)
{
if (argc != 3)
BAD_COMMAND("usage: %s <client-id>/<window-id> <parent-window-id>",
argv[0]);
TestClient *client;
const char *window_id;
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
return FALSE;
if (!test_client_do (client, error,
"set_parent", window_id,
argv[2],
NULL))
return FALSE;
}
else if (strcmp (argv[0], "show") == 0 ||
strcmp (argv[0], "hide") == 0 ||
strcmp (argv[0], "activate") == 0 ||

View File

@@ -970,6 +970,12 @@ meta_frame_left_click_event (MetaUIFrame *frame,
case META_FRAME_CONTROL_UNMAXIMIZE:
case META_FRAME_CONTROL_MINIMIZE:
case META_FRAME_CONTROL_DELETE:
case META_FRAME_CONTROL_SHADE:
case META_FRAME_CONTROL_UNSHADE:
case META_FRAME_CONTROL_ABOVE:
case META_FRAME_CONTROL_UNABOVE:
case META_FRAME_CONTROL_STICK:
case META_FRAME_CONTROL_UNSTICK:
case META_FRAME_CONTROL_MENU:
case META_FRAME_CONTROL_APPMENU:
frame->grab_button = event->button;
@@ -1068,10 +1074,7 @@ handle_button_press_event (MetaUIFrame *frame,
control = get_control (frame, event->x, event->y);
/* don't do the rest of this if on client area */
if (control == META_FRAME_CONTROL_CLIENT_AREA)
return FALSE; /* not on the frame, just passed through from client */
/* focus on click, even if click was on client area */
if (event->button == 1 &&
!(control == META_FRAME_CONTROL_MINIMIZE ||
control == META_FRAME_CONTROL_DELETE ||
@@ -1083,6 +1086,10 @@ handle_button_press_event (MetaUIFrame *frame,
meta_window_focus (frame->meta_window, event->time);
}
/* don't do the rest of this if on client area */
if (control == META_FRAME_CONTROL_CLIENT_AREA)
return FALSE; /* not on the frame, just passed through from client */
/* We want to shade even if we have a GrabOp, since we'll have a move grab
* if we double click the titlebar.
*/
@@ -1147,6 +1154,24 @@ handle_button_release_event (MetaUIFrame *frame,
case META_FRAME_CONTROL_DELETE:
meta_window_delete (frame->meta_window, event->time);
break;
case META_FRAME_CONTROL_SHADE:
meta_window_shade (frame->meta_window, event->time);
break;
case META_FRAME_CONTROL_UNSHADE:
meta_window_unshade (frame->meta_window, event->time);
break;
case META_FRAME_CONTROL_ABOVE:
meta_window_make_above (frame->meta_window);
break;
case META_FRAME_CONTROL_UNABOVE:
meta_window_unmake_above (frame->meta_window);
break;
case META_FRAME_CONTROL_STICK:
meta_window_stick (frame->meta_window);
break;
case META_FRAME_CONTROL_UNSTICK:
meta_window_unstick (frame->meta_window);
break;
default:
break;
}
@@ -1195,6 +1220,18 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
break;
case META_FRAME_CONTROL_SHADE:
break;
case META_FRAME_CONTROL_UNSHADE:
break;
case META_FRAME_CONTROL_ABOVE:
break;
case META_FRAME_CONTROL_UNABOVE:
break;
case META_FRAME_CONTROL_STICK:
break;
case META_FRAME_CONTROL_UNSTICK:
break;
case META_FRAME_CONTROL_RESIZE_SE:
cursor = META_CURSOR_SE_RESIZE;
break;
@@ -1233,6 +1270,12 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
case META_FRAME_CONTROL_MINIMIZE:
case META_FRAME_CONTROL_MAXIMIZE:
case META_FRAME_CONTROL_DELETE:
case META_FRAME_CONTROL_SHADE:
case META_FRAME_CONTROL_UNSHADE:
case META_FRAME_CONTROL_ABOVE:
case META_FRAME_CONTROL_UNABOVE:
case META_FRAME_CONTROL_STICK:
case META_FRAME_CONTROL_UNSTICK:
case META_FRAME_CONTROL_UNMAXIMIZE:
/* leave control set */
break;
@@ -1444,6 +1487,24 @@ meta_ui_frame_paint (MetaUIFrame *frame,
case META_FRAME_CONTROL_UNMAXIMIZE:
button_type = META_BUTTON_TYPE_MAXIMIZE;
break;
case META_FRAME_CONTROL_SHADE:
button_type = META_BUTTON_TYPE_SHADE;
break;
case META_FRAME_CONTROL_UNSHADE:
button_type = META_BUTTON_TYPE_UNSHADE;
break;
case META_FRAME_CONTROL_ABOVE:
button_type = META_BUTTON_TYPE_ABOVE;
break;
case META_FRAME_CONTROL_UNABOVE:
button_type = META_BUTTON_TYPE_UNABOVE;
break;
case META_FRAME_CONTROL_STICK:
button_type = META_BUTTON_TYPE_STICK;
break;
case META_FRAME_CONTROL_UNSTICK:
button_type = META_BUTTON_TYPE_UNSTICK;
break;
case META_FRAME_CONTROL_DELETE:
button_type = META_BUTTON_TYPE_CLOSE;
break;
@@ -1563,6 +1624,24 @@ control_rect (MetaFrameControl control,
case META_FRAME_CONTROL_UNMAXIMIZE:
rect = &fgeom->max_rect.visible;
break;
case META_FRAME_CONTROL_SHADE:
rect = &fgeom->shade_rect.visible;
break;
case META_FRAME_CONTROL_UNSHADE:
rect = &fgeom->unshade_rect.visible;
break;
case META_FRAME_CONTROL_ABOVE:
rect = &fgeom->above_rect.visible;
break;
case META_FRAME_CONTROL_UNABOVE:
rect = &fgeom->unabove_rect.visible;
break;
case META_FRAME_CONTROL_STICK:
rect = &fgeom->stick_rect.visible;
break;
case META_FRAME_CONTROL_UNSTICK:
rect = &fgeom->unstick_rect.visible;
break;
case META_FRAME_CONTROL_RESIZE_SE:
break;
case META_FRAME_CONTROL_RESIZE_S:
@@ -1647,6 +1726,36 @@ get_control (MetaUIFrame *frame, int root_x, int root_y)
return META_FRAME_CONTROL_MAXIMIZE;
}
if (POINT_IN_RECT (x, y, fgeom.shade_rect.clickable))
{
return META_FRAME_CONTROL_SHADE;
}
if (POINT_IN_RECT (x, y, fgeom.unshade_rect.clickable))
{
return META_FRAME_CONTROL_UNSHADE;
}
if (POINT_IN_RECT (x, y, fgeom.above_rect.clickable))
{
return META_FRAME_CONTROL_ABOVE;
}
if (POINT_IN_RECT (x, y, fgeom.unabove_rect.clickable))
{
return META_FRAME_CONTROL_UNABOVE;
}
if (POINT_IN_RECT (x, y, fgeom.stick_rect.clickable))
{
return META_FRAME_CONTROL_STICK;
}
if (POINT_IN_RECT (x, y, fgeom.unstick_rect.clickable))
{
return META_FRAME_CONTROL_UNSTICK;
}
/* South resize always has priority over north resize,
* in case of overlap.
*/

View File

@@ -39,6 +39,12 @@ typedef enum
META_FRAME_CONTROL_MINIMIZE,
META_FRAME_CONTROL_MAXIMIZE,
META_FRAME_CONTROL_UNMAXIMIZE,
META_FRAME_CONTROL_SHADE,
META_FRAME_CONTROL_UNSHADE,
META_FRAME_CONTROL_ABOVE,
META_FRAME_CONTROL_UNABOVE,
META_FRAME_CONTROL_STICK,
META_FRAME_CONTROL_UNSTICK,
META_FRAME_CONTROL_RESIZE_SE,
META_FRAME_CONTROL_RESIZE_S,
META_FRAME_CONTROL_RESIZE_SW,

View File

@@ -60,16 +60,6 @@ struct _MetaFrameLayout
/** Border/padding of titlebar buttons */
GtkBorder button_border;
/** Margin of title */
GtkBorder title_margin;
/** Margin of titlebar buttons */
GtkBorder button_margin;
/** Min size of titlebar region */
GtkRequisition titlebar_min_size;
/** Min size of titlebar buttons */
GtkRequisition button_min_size;
/** Size of images in buttons */
guint icon_size;
@@ -125,7 +115,7 @@ struct _MetaFrameGeometry
/* used for a memset hack */
#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, appmenu_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, unstick_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
/* The button rects (if changed adjust memset hack) */
MetaButtonSpace close_rect;
@@ -133,6 +123,12 @@ struct _MetaFrameGeometry
MetaButtonSpace min_rect;
MetaButtonSpace menu_rect;
MetaButtonSpace appmenu_rect;
MetaButtonSpace shade_rect;
MetaButtonSpace above_rect;
MetaButtonSpace stick_rect;
MetaButtonSpace unshade_rect;
MetaButtonSpace unabove_rect;
MetaButtonSpace unstick_rect;
/* End of button rects (if changed adjust memset hack) */
/* Saved button layout */
@@ -162,6 +158,12 @@ typedef enum
META_BUTTON_TYPE_MINIMIZE,
META_BUTTON_TYPE_MENU,
META_BUTTON_TYPE_APPMENU,
META_BUTTON_TYPE_SHADE,
META_BUTTON_TYPE_ABOVE,
META_BUTTON_TYPE_STICK,
META_BUTTON_TYPE_UNSHADE,
META_BUTTON_TYPE_UNABOVE,
META_BUTTON_TYPE_UNSTICK,
META_BUTTON_TYPE_LAST
} MetaButtonType;

View File

@@ -79,14 +79,10 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout,
if (!layout->has_title)
text_height = 0;
else
text_height = layout->title_margin.top + text_height + layout->title_margin.bottom;
buttons_height = MAX ((int)layout->icon_size, layout->button_min_size.height) +
layout->button_margin.top + layout->button_border.top +
layout->button_margin.bottom + layout->button_border.bottom;
content_height = MAX (buttons_height, text_height);
content_height = MAX (content_height, layout->titlebar_min_size.height) +
buttons_height = layout->icon_size +
layout->button_border.top + layout->button_border.bottom;
content_height = MAX (buttons_height, text_height) +
layout->titlebar_border.top + layout->titlebar_border.bottom;
borders->visible.top = layout->frame_border.top + content_height;
@@ -181,6 +177,17 @@ rect_for_function (MetaFrameGeometry *fgeom,
return &fgeom->close_rect;
else
return NULL;
case META_BUTTON_FUNCTION_STICK:
case META_BUTTON_FUNCTION_SHADE:
case META_BUTTON_FUNCTION_ABOVE:
case META_BUTTON_FUNCTION_UNSTICK:
case META_BUTTON_FUNCTION_UNSHADE:
case META_BUTTON_FUNCTION_UNABOVE:
/* Fringe buttons that used to be supported by theme versions >v1;
* if we want to support them again, we need to return the
* correspondings rects here
*/
return NULL;
case META_BUTTON_FUNCTION_LAST:
return NULL;
@@ -238,16 +245,6 @@ get_padding_and_border (GtkStyleContext *style,
border->bottom += tmp.bottom;
}
static void
get_min_size (GtkStyleContext *style,
GtkRequisition *requisition)
{
gtk_style_context_get (style, gtk_style_context_get_state (style),
"min-width", &requisition->width,
"min-height", &requisition->height,
NULL);
}
static void
scale_border (GtkBorder *border,
double factor)
@@ -265,7 +262,6 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
{
GtkStyleContext *style;
GtkBorder border;
GtkRequisition requisition;
int border_radius, max_radius;
meta_style_info_set_flags (style_info, flags);
@@ -296,25 +292,14 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
max_radius = MIN (layout->frame_border.bottom, layout->frame_border.right);
layout->bottom_right_corner_rounded_radius = MAX (border_radius, max_radius);
get_min_size (style, &layout->titlebar_min_size);
get_padding_and_border (style, &layout->titlebar_border);
scale_border (&layout->titlebar_border, layout->title_scale);
style = style_info->styles[META_STYLE_ELEMENT_TITLE];
gtk_style_context_get_margin (style, gtk_style_context_get_state (style),
&layout->title_margin);
scale_border (&layout->title_margin, layout->title_scale);
style = style_info->styles[META_STYLE_ELEMENT_BUTTON];
get_min_size (style, &layout->button_min_size);
get_padding_and_border (style, &layout->button_border);
scale_border (&layout->button_border, layout->title_scale);
gtk_style_context_get_margin (style, gtk_style_context_get_state (style),
&layout->button_margin);
scale_border (&layout->button_margin, layout->title_scale);
style = style_info->styles[META_STYLE_ELEMENT_IMAGE];
get_min_size (style, &requisition);
get_padding_and_border (style, &border);
scale_border (&border, layout->title_scale);
@@ -322,18 +307,6 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
layout->button_border.right += border.right;
layout->button_border.top += border.top;
layout->button_border.bottom += border.bottom;
gtk_style_context_get_margin (style, gtk_style_context_get_state (style),
&border);
layout->button_border.left += border.left;
layout->button_border.right += border.right;
layout->button_border.top += border.top;
layout->button_border.bottom += border.bottom;
layout->button_min_size.width = MAX(layout->button_min_size.width,
requisition.width);
layout->button_min_size.height = MAX(layout->button_min_size.height,
requisition.height);
}
static void
@@ -397,9 +370,9 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
(fgeom->content_border.right + borders.invisible.right);
content_height = borders.visible.top - fgeom->content_border.top - fgeom->content_border.bottom;
button_width = MAX ((int)layout->icon_size, layout->button_min_size.width) +
button_width = layout->icon_size +
layout->button_border.left + layout->button_border.right;
button_height = MAX ((int)layout->icon_size, layout->button_min_size.height) +
button_height = layout->icon_size +
layout->button_border.top + layout->button_border.bottom;
button_width *= scale;
button_height *= scale;
@@ -460,15 +433,11 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
space_used_by_buttons = 0;
space_used_by_buttons += layout->button_margin.left * scale * n_left;
space_used_by_buttons += button_width * n_left;
space_used_by_buttons += layout->button_margin.right * scale * n_left;
space_used_by_buttons += (button_width * 0.75) * n_left_spacers;
space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_left - 1, 0);
space_used_by_buttons += layout->button_margin.left * scale * n_right;
space_used_by_buttons += button_width * n_right;
space_used_by_buttons += layout->button_margin.right * scale * n_right;
space_used_by_buttons += (button_width * 0.75) * n_right_spacers;
space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_right - 1, 0);
@@ -488,10 +457,22 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
}
/* Otherwise we need to shave out a button. Shave
* min, max, close, then menu (menu is most useful);
* above, stick, shade, min, max, close, then menu (menu is most useful);
* prefer the default button locations.
*/
if (strip_button (left_func_rects, &n_left, &fgeom->min_rect))
if (strip_button (left_func_rects, &n_left, &fgeom->above_rect))
continue;
else if (strip_button (right_func_rects, &n_right, &fgeom->above_rect))
continue;
else if (strip_button (left_func_rects, &n_left, &fgeom->stick_rect))
continue;
else if (strip_button (right_func_rects, &n_right, &fgeom->stick_rect))
continue;
else if (strip_button (left_func_rects, &n_left, &fgeom->shade_rect))
continue;
else if (strip_button (right_func_rects, &n_right, &fgeom->shade_rect))
continue;
else if (strip_button (left_func_rects, &n_left, &fgeom->min_rect))
continue;
else if (strip_button (right_func_rects, &n_right, &fgeom->min_rect))
continue;
@@ -538,8 +519,6 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */
break;
x -= layout->button_margin.right * scale;
rect = right_func_rects[i];
rect->visible.x = x - button_width;
if (right_buttons_has_spacer[i])
@@ -565,7 +544,7 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
else
g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
x = rect->visible.x - layout->button_margin.left * scale;
x = rect->visible.x;
if (i > 0)
x -= layout->titlebar_spacing;
@@ -584,8 +563,6 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
{
MetaButtonSpace *rect;
x += layout->button_margin.left * scale;
rect = left_func_rects[i];
rect->visible.x = x;
@@ -612,7 +589,7 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
else
g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
x = rect->visible.x + rect->visible.width + layout->button_margin.right * scale;
x = rect->visible.x + rect->visible.width;
if (i < n_left - 1)
x += layout->titlebar_spacing * scale;
if (left_buttons_has_spacer[i])
@@ -666,6 +643,30 @@ get_button_rect (MetaButtonType type,
*rect = fgeom->close_rect.visible;
break;
case META_BUTTON_TYPE_SHADE:
*rect = fgeom->shade_rect.visible;
break;
case META_BUTTON_TYPE_UNSHADE:
*rect = fgeom->unshade_rect.visible;
break;
case META_BUTTON_TYPE_ABOVE:
*rect = fgeom->above_rect.visible;
break;
case META_BUTTON_TYPE_UNABOVE:
*rect = fgeom->unabove_rect.visible;
break;
case META_BUTTON_TYPE_STICK:
*rect = fgeom->stick_rect.visible;
break;
case META_BUTTON_TYPE_UNSTICK:
*rect = fgeom->unstick_rect.visible;
break;
case META_BUTTON_TYPE_MAXIMIZE:
*rect = fgeom->max_rect.visible;
break;
@@ -889,7 +890,6 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
cairo_restore (cr);
if (button_class)
gtk_style_context_remove_class (style, button_class);
gtk_style_context_set_state (style, state);
}
}
@@ -975,7 +975,6 @@ static GtkStyleContext *
create_style_context (GType widget_type,
GtkStyleContext *parent_style,
GtkCssProvider *provider,
const char *object_name,
const char *first_class,
...)
{
@@ -995,9 +994,6 @@ create_style_context (GType widget_type,
gtk_widget_path_append_type (path, widget_type);
if (object_name)
gtk_widget_path_iter_set_object_name (path, -1, object_name);
va_start (ap, first_class);
for (name = first_class; name; name = va_arg (ap, const char *))
gtk_widget_path_iter_add_class (path, -1, name);
@@ -1037,7 +1033,6 @@ meta_theme_create_style_info (GdkScreen *screen,
create_style_context (META_TYPE_FRAMES,
NULL,
provider,
"decoration",
GTK_STYLE_CLASS_BACKGROUND,
"window-frame",
"ssd",
@@ -1046,30 +1041,28 @@ meta_theme_create_style_info (GdkScreen *screen,
create_style_context (GTK_TYPE_HEADER_BAR,
style_info->styles[META_STYLE_ELEMENT_FRAME],
provider,
"headerbar",
GTK_STYLE_CLASS_TITLEBAR,
GTK_STYLE_CLASS_HORIZONTAL,
"default-decoration",
"header-bar",
NULL);
style_info->styles[META_STYLE_ELEMENT_TITLE] =
create_style_context (GTK_TYPE_LABEL,
style_info->styles[META_STYLE_ELEMENT_TITLEBAR],
provider,
"label",
GTK_STYLE_CLASS_TITLE,
NULL);
style_info->styles[META_STYLE_ELEMENT_BUTTON] =
create_style_context (GTK_TYPE_BUTTON,
style_info->styles[META_STYLE_ELEMENT_TITLEBAR],
provider,
"button",
GTK_STYLE_CLASS_BUTTON,
"titlebutton",
NULL);
style_info->styles[META_STYLE_ELEMENT_IMAGE] =
create_style_context (GTK_TYPE_IMAGE,
style_info->styles[META_STYLE_ELEMENT_BUTTON],
provider,
"image",
NULL);
return style_info;
}
@@ -1176,10 +1169,9 @@ meta_style_info_create_font_desc (MetaStyleInfo *style_info)
{
PangoFontDescription *font_desc;
const PangoFontDescription *override = meta_prefs_get_titlebar_font ();
GtkStyleContext *context = style_info->styles[META_STYLE_ELEMENT_TITLE];
gtk_style_context_get (context,
gtk_style_context_get_state (context),
gtk_style_context_get (style_info->styles[META_STYLE_ELEMENT_TITLE],
GTK_STATE_FLAG_NORMAL,
"font", &font_desc, NULL);
if (override)

View File

@@ -37,30 +37,17 @@
#include "meta-wayland-private.h"
#include "meta-dnd-actor-private.h"
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
struct _MetaWaylandDataOffer
{
struct wl_resource *resource;
MetaWaylandDataSource *source;
struct wl_listener source_destroy_listener;
uint32_t dnd_actions;
enum wl_data_device_manager_dnd_action preferred_dnd_action;
};
typedef struct _MetaWaylandDataSourcePrivate
{
MetaWaylandDataOffer *offer;
struct wl_array mime_types;
gboolean has_target;
uint32_t dnd_actions;
enum wl_data_device_manager_dnd_action user_dnd_action;
enum wl_data_device_manager_dnd_action current_dnd_action;
MetaWaylandSeat *seat;
guint actions_set : 1;
guint in_ask : 1;
} MetaWaylandDataSourcePrivate;
typedef struct _MetaWaylandDataSourceWayland
@@ -87,75 +74,6 @@ unbind_resource (struct wl_resource *resource)
wl_list_remove (wl_resource_get_link (resource));
}
static gboolean
meta_wayland_source_get_in_ask (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
return priv->in_ask;
}
static void
meta_wayland_source_update_in_ask (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
priv->in_ask =
priv->current_dnd_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
}
static enum wl_data_device_manager_dnd_action
data_offer_choose_action (MetaWaylandDataOffer *offer)
{
MetaWaylandDataSource *source = offer->source;
uint32_t actions, user_action, available_actions;
actions = meta_wayland_data_source_get_actions (source);
user_action = meta_wayland_data_source_get_user_action (source);
available_actions = actions & offer->dnd_actions;
if (!available_actions)
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
/* If the user is forcing an action, go for it */
if ((user_action & available_actions) != 0)
return user_action;
/* If the dest side has a preferred DnD action, use it */
if ((offer->preferred_dnd_action & available_actions) != 0)
return offer->preferred_dnd_action;
/* Use the first found action, in bit order */
return 1 << (ffs (available_actions) - 1);
}
static void
data_offer_update_action (MetaWaylandDataOffer *offer)
{
enum wl_data_device_manager_dnd_action current_action, action;
MetaWaylandDataSource *source;
if (!offer->source)
return;
source = offer->source;
current_action = meta_wayland_data_source_get_current_action (source);
action = data_offer_choose_action (offer);
if (current_action == action)
return;
meta_wayland_data_source_set_current_action (source, action);
if (!meta_wayland_source_get_in_ask (source) &&
wl_resource_get_version (offer->resource) >=
WL_DATA_OFFER_ACTION_SINCE_VERSION)
wl_data_offer_send_action (offer->resource, action);
}
static void
meta_wayland_data_source_target (MetaWaylandDataSource *source,
const char *mime_type)
@@ -180,25 +98,6 @@ meta_wayland_data_source_has_target (MetaWaylandDataSource *source)
return priv->has_target;
}
static void
meta_wayland_data_source_set_seat (MetaWaylandDataSource *source,
MetaWaylandSeat *seat)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
priv->seat = seat;
}
static MetaWaylandSeat *
meta_wayland_data_source_get_seat (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
return priv->seat;
}
void
meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
gboolean has_target)
@@ -213,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 ((MetaWaylandDataSource *)source);
meta_wayland_data_source_get_instance_private (source);
return &priv->mime_types;
}
@@ -224,100 +123,6 @@ meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
}
uint32_t
meta_wayland_data_source_get_actions (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
return priv->dnd_actions;
}
enum wl_data_device_manager_dnd_action
meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
if (!priv->seat)
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
return priv->user_dnd_action;
}
enum wl_data_device_manager_dnd_action
meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
return priv->current_dnd_action;
}
static void
meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source,
MetaWaylandDataOffer *offer)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
priv->offer = offer;
}
static MetaWaylandDataOffer *
meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
return priv->offer;
}
void
meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
enum wl_data_device_manager_dnd_action action)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
if (priv->current_dnd_action == action)
return;
priv->current_dnd_action = action;
if (!meta_wayland_source_get_in_ask (source))
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->action (source, action);
}
void
meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
uint32_t dnd_actions)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
priv->dnd_actions = dnd_actions;
priv->actions_set = TRUE;
}
static void
meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
enum wl_data_device_manager_dnd_action action)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
MetaWaylandDataOffer *offer;
if (priv->user_dnd_action == action)
return;
priv->user_dnd_action = action;
offer = meta_wayland_data_source_get_current_offer (source);
if (offer)
data_offer_update_action (offer);
}
static void
data_offer_accept (struct wl_client *client,
struct wl_resource *resource,
@@ -356,117 +161,21 @@ data_offer_destroy (struct wl_client *client, struct wl_resource *resource)
wl_resource_destroy (resource);
}
static void
data_offer_finish (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
enum wl_data_device_manager_dnd_action current_action;
if (!offer->source ||
offer != meta_wayland_data_source_get_current_offer (offer->source))
return;
if (meta_wayland_data_source_get_seat (offer->source) ||
!meta_wayland_data_source_has_target (offer->source))
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_FINISH,
"premature finish request");
return;
}
current_action = meta_wayland_data_source_get_current_action (offer->source);
if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE ||
current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_OFFER,
"offer finished with an invalid action");
return;
}
meta_wayland_data_source_notify_finish (offer->source);
}
static void
data_offer_set_actions (struct wl_client *client,
struct wl_resource *resource,
uint32_t dnd_actions,
uint32_t preferred_action)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
if (dnd_actions & ~(ALL_ACTIONS))
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
"invalid actions mask %x", dnd_actions);
return;
}
if (preferred_action &&
(!(preferred_action & dnd_actions) ||
__builtin_popcount (preferred_action) > 1))
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_ACTION,
"invalid action %x", preferred_action);
return;
}
offer->dnd_actions = dnd_actions;
offer->preferred_dnd_action = preferred_action;
data_offer_update_action (offer);
}
static const struct wl_data_offer_interface data_offer_interface = {
data_offer_accept,
data_offer_receive,
data_offer_destroy,
data_offer_finish,
data_offer_set_actions,
};
static void
meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source)
{
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drop_performed (source);
}
void
meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source)
{
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drag_finished (source);
}
static void
destroy_data_offer (struct wl_resource *resource)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
if (offer->source)
{
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
{
if (wl_resource_get_version (offer->resource) <
WL_DATA_OFFER_ACTION_SINCE_VERSION)
meta_wayland_data_source_notify_finish (offer->source);
else
{
meta_wayland_data_source_cancel (offer->source);
meta_wayland_data_source_set_current_offer (offer->source, NULL);
}
}
g_object_remove_weak_pointer (G_OBJECT (offer->source),
(gpointer *)&offer->source);
g_object_remove_weak_pointer (G_OBJECT (offer->source),
(gpointer *)&offer->source);
offer->source = NULL;
}
meta_display_sync_wayland_input_focus (meta_get_display ());
g_slice_free (MetaWaylandDataOffer, offer);
}
@@ -494,9 +203,6 @@ meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
wl_array_for_each (p, &priv->mime_types)
wl_data_offer_send_offer (offer->resource, *p);
data_offer_update_action (offer);
meta_wayland_data_source_set_current_offer (source, offer);
return offer->resource;
}
@@ -516,56 +222,14 @@ data_source_destroy (struct wl_client *client, struct wl_resource *resource)
wl_resource_destroy (resource);
}
static void
data_source_set_actions (struct wl_client *client,
struct wl_resource *resource,
uint32_t dnd_actions)
{
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private (source);
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
if (priv->actions_set)
{
wl_resource_post_error (source_wayland->resource,
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
"cannot set actions more than once");
return;
}
if (dnd_actions & ~(ALL_ACTIONS))
{
wl_resource_post_error (source_wayland->resource,
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
"invalid actions mask %x", dnd_actions);
return;
}
if (meta_wayland_data_source_get_seat (source))
{
wl_resource_post_error (source_wayland->resource,
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
"invalid action change after "
"wl_data_device.start_drag");
return;
}
meta_wayland_data_source_set_actions (source, dnd_actions);
}
static struct wl_data_source_interface data_source_interface = {
data_source_offer,
data_source_destroy,
data_source_set_actions
data_source_destroy
};
struct _MetaWaylandDragGrab {
MetaWaylandPointerGrab generic;
MetaWaylandKeyboardGrab keyboard_grab;
MetaWaylandSeat *seat;
struct wl_client *drag_client;
@@ -584,7 +248,6 @@ struct _MetaWaylandDragGrab {
struct wl_listener drag_origin_listener;
int drag_start_x, drag_start_y;
ClutterModifierType buttons;
};
static void
@@ -593,24 +256,6 @@ destroy_drag_focus (struct wl_listener *listener, void *data)
MetaWaylandDragGrab *grab = wl_container_of (listener, grab, drag_focus_listener);
grab->drag_focus_data_device = NULL;
grab->drag_focus = NULL;
}
static void
meta_wayland_drag_grab_set_source (MetaWaylandDragGrab *drag_grab,
MetaWaylandDataSource *source)
{
if (drag_grab->drag_data_source)
g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
drag_grab_data_source_destroyed,
drag_grab);
drag_grab->drag_data_source = source;
if (source)
g_object_weak_ref (G_OBJECT (source),
drag_grab_data_source_destroyed,
drag_grab);
}
void
@@ -630,9 +275,6 @@ meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
drag_grab->drag_focus = NULL;
}
if (drag_grab->drag_data_source)
meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL);
if (!surface)
return;
@@ -670,22 +312,6 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
meta_wayland_drag_grab_set_focus (drag_grab, surface);
}
static void
data_source_update_user_dnd_action (MetaWaylandDataSource *source,
ClutterModifierType modifiers)
{
enum wl_data_device_manager_dnd_action user_dnd_action = 0;
if (modifiers & CLUTTER_SHIFT_MASK)
user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
else if (modifiers & CLUTTER_CONTROL_MASK)
user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
else if (modifiers & (CLUTTER_MOD1_MASK | CLUTTER_BUTTON2_MASK))
user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
meta_wayland_data_source_set_user_action (source, user_dnd_action);
}
static void
drag_grab_motion (MetaWaylandPointerGrab *grab,
const ClutterEvent *event)
@@ -717,7 +343,10 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
wl_list_remove (&drag_grab->drag_icon_listener.link);
}
meta_wayland_drag_grab_set_source (drag_grab, NULL);
if (drag_grab->drag_data_source)
g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
drag_grab_data_source_destroyed,
drag_grab);
if (drag_grab->feedback_actor)
{
@@ -727,15 +356,7 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
drag_grab->seat->data_device.current_grab = NULL;
/* There might be other grabs created in result to DnD actions like popups
* on "ask" actions, we must not reset those, only our own.
*/
if (drag_grab->generic.pointer->grab == (MetaWaylandPointerGrab *) drag_grab)
{
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
meta_wayland_keyboard_end_grab (drag_grab->keyboard_grab.keyboard);
}
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
g_slice_free (MetaWaylandDragGrab, drag_grab);
}
@@ -750,33 +371,17 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
if (drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
event_type == CLUTTER_BUTTON_RELEASE)
{
MetaWaylandDataSource *source = drag_grab->drag_data_source;
gboolean success;
gboolean success = FALSE;
if (drag_grab->drag_focus && source &&
meta_wayland_data_source_has_target (source) &&
meta_wayland_data_source_get_current_action (source))
if (meta_wayland_data_source_has_target (drag_grab->drag_data_source))
{
/* Detach the data source from the grab, it's meant to live longer */
meta_wayland_drag_grab_set_source (drag_grab, NULL);
meta_wayland_data_source_set_seat (source, NULL);
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
meta_wayland_data_source_notify_drop_performed (source);
meta_wayland_source_update_in_ask (source);
success = TRUE;
}
else
{
meta_wayland_data_source_cancel (source);
meta_wayland_data_source_set_current_offer (source, NULL);
meta_wayland_data_device_set_dnd_source (&seat->data_device, NULL);
success= FALSE;
}
/* Finish drag and let actor self-destruct */
meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor), success);
meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor),
success);
drag_grab->feedback_actor = NULL;
}
@@ -791,40 +396,6 @@ static const MetaWaylandPointerGrabInterface drag_grab_interface = {
drag_grab_button,
};
static gboolean
keyboard_drag_grab_key (MetaWaylandKeyboardGrab *grab,
const ClutterEvent *event)
{
return FALSE;
}
static void
keyboard_drag_grab_modifiers (MetaWaylandKeyboardGrab *grab,
ClutterModifierType modifiers)
{
MetaWaylandDragGrab *drag_grab;
drag_grab = wl_container_of (grab, drag_grab, keyboard_grab);
/* The modifiers here just contain keyboard modifiers, mix it with the
* mouse button modifiers we got when starting the drag operation.
*/
modifiers |= drag_grab->buttons;
if (drag_grab->drag_data_source)
{
data_source_update_user_dnd_action (drag_grab->drag_data_source, modifiers);
if (drag_grab->drag_focus)
meta_wayland_surface_drag_dest_update (drag_grab->drag_focus);
}
}
static const MetaWaylandKeyboardGrabInterface keyboard_drag_grab_interface = {
keyboard_drag_grab_key,
keyboard_drag_grab_modifiers
};
static void
destroy_data_device_origin (struct wl_listener *listener, void *data)
{
@@ -869,16 +440,12 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
MetaWaylandDragGrab *drag_grab;
ClutterPoint pos, stage_pos;
ClutterModifierType modifiers;
data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
drag_grab->generic.interface = funcs;
drag_grab->generic.pointer = &seat->pointer;
drag_grab->keyboard_grab.interface = &keyboard_drag_grab_interface;
drag_grab->keyboard_grab.keyboard = &seat->keyboard;
drag_grab->drag_client = client;
drag_grab->seat = seat;
@@ -893,15 +460,13 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
drag_grab->drag_start_x = stage_pos.x;
drag_grab->drag_start_y = stage_pos.y;
modifiers = clutter_input_device_get_modifier_state (seat->pointer.device);
drag_grab->buttons = modifiers &
(CLUTTER_BUTTON1_MASK | CLUTTER_BUTTON2_MASK | CLUTTER_BUTTON3_MASK |
CLUTTER_BUTTON4_MASK | CLUTTER_BUTTON5_MASK);
g_object_weak_ref (G_OBJECT (source),
drag_grab_data_source_destroyed,
drag_grab);
meta_wayland_drag_grab_set_source (drag_grab, source);
drag_grab->drag_data_source = source;
meta_wayland_data_device_set_dnd_source (data_device,
drag_grab->drag_data_source);
data_source_update_user_dnd_action (source, modifiers);
if (icon_surface)
{
@@ -915,7 +480,8 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
drag_grab->drag_start_x,
drag_grab->drag_start_y);
meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
0, 0);
-drag_grab->drag_surface->offset_x,
-drag_grab->drag_surface->offset_y);
clutter_actor_add_child (drag_grab->feedback_actor,
CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor));
@@ -924,7 +490,6 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
}
meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*) drag_grab);
meta_wayland_data_source_set_seat (source, seat);
}
void
@@ -983,10 +548,6 @@ data_device_start_drag (struct wl_client *client,
meta_wayland_data_device_start_drag (data_device, client,
&drag_grab_interface,
surface, drag_source, icon_surface);
meta_wayland_keyboard_set_focus (&seat->keyboard, NULL);
meta_wayland_keyboard_start_grab (&seat->keyboard,
&seat->data_device.current_grab->keyboard_grab);
}
static void
@@ -1039,47 +600,6 @@ meta_wayland_source_cancel (MetaWaylandDataSource *source)
wl_data_source_send_cancelled (source_wayland->resource);
}
static void
meta_wayland_source_action (MetaWaylandDataSource *source,
enum wl_data_device_manager_dnd_action action)
{
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
if (wl_resource_get_version (source_wayland->resource) >=
WL_DATA_SOURCE_ACTION_SINCE_VERSION)
wl_data_source_send_action (source_wayland->resource, action);
}
static void
meta_wayland_source_drop_performed (MetaWaylandDataSource *source)
{
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
if (wl_resource_get_version (source_wayland->resource) >=
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
wl_data_source_send_dnd_drop_performed (source_wayland->resource);
}
static void
meta_wayland_source_drag_finished (MetaWaylandDataSource *source)
{
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
enum wl_data_device_manager_dnd_action action;
if (meta_wayland_source_get_in_ask (source))
{
action = meta_wayland_data_source_get_current_action (source);
meta_wayland_source_action (source, action);
}
if (wl_resource_get_version (source_wayland->resource) >=
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
wl_data_source_send_dnd_finished (source_wayland->resource);
}
static void
meta_wayland_source_finalize (GObject *object)
{
@@ -1103,9 +623,6 @@ meta_wayland_data_source_wayland_class_init (MetaWaylandDataSourceWaylandClass *
data_source_class->send = meta_wayland_source_send;
data_source_class->target = meta_wayland_source_target;
data_source_class->cancel = meta_wayland_source_cancel;
data_source_class->action = meta_wayland_source_action;
data_source_class->drop_performed = meta_wayland_source_drop_performed;
data_source_class->drag_finished = meta_wayland_source_drag_finished;
}
static void
@@ -1130,7 +647,6 @@ meta_wayland_data_source_init (MetaWaylandDataSource *source)
meta_wayland_data_source_get_instance_private (source);
wl_array_init (&priv->mime_types);
priv->current_dnd_action = -1;
}
static void
@@ -1149,7 +665,6 @@ meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device,
MetaWaylandDragGrab *grab = data_device->current_grab;
struct wl_display *display;
struct wl_client *client;
uint32_t source_actions;
wl_fixed_t sx, sy;
if (!grab->drag_focus_data_device)
@@ -1162,13 +677,6 @@ meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device,
wl_resource_add_destroy_listener (grab->drag_focus_data_device,
&grab->drag_focus_listener);
if (wl_resource_get_version (offer->resource) >=
WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION)
{
source_actions = meta_wayland_data_source_get_actions (offer->source);
wl_data_offer_send_source_actions (offer->resource, source_actions);
}
meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer,
surface, &sx, &sy);
wl_data_device_send_enter (grab->drag_focus_data_device,
@@ -1214,18 +722,11 @@ meta_wayland_drag_dest_drop (MetaWaylandDataDevice *data_device,
wl_data_device_send_drop (grab->drag_focus_data_device);
}
static void
meta_wayland_drag_dest_update (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface)
{
}
static const MetaWaylandDragDestFuncs meta_wayland_drag_dest_funcs = {
meta_wayland_drag_dest_focus_in,
meta_wayland_drag_dest_focus_out,
meta_wayland_drag_dest_motion,
meta_wayland_drag_dest_drop,
meta_wayland_drag_dest_update
meta_wayland_drag_dest_drop
};
const MetaWaylandDragDestFuncs *
@@ -1314,7 +815,6 @@ data_device_set_selection (struct wl_client *client,
guint32 serial)
{
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
MetaWaylandDataSourcePrivate *priv;
MetaWaylandDataSource *source;
if (source_resource)
@@ -1322,19 +822,6 @@ data_device_set_selection (struct wl_client *client,
else
source = NULL;
if (source)
{
priv = meta_wayland_data_source_get_instance_private (source);
if (priv->actions_set)
{
wl_resource_post_error(source_resource,
WL_DATA_SOURCE_ERROR_INVALID_SOURCE,
"cannot set drag-and-drop source as selection");
return;
}
}
/* FIXME: Store serial and check against incoming serial here. */
meta_wayland_data_device_set_selection (data_device, source, serial);
}
@@ -1456,12 +943,30 @@ meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
data_device->current_grab->drag_surface == surface;
}
void
meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device)
{
MetaWaylandDragGrab *drag_grab;
if (!data_device->current_grab)
return;
drag_grab = data_device->current_grab;
if (!drag_grab->feedback_actor || !drag_grab->drag_surface)
return;
meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
-drag_grab->drag_surface->offset_x,
-drag_grab->drag_surface->offset_y);
}
gboolean
meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
const gchar *mime_type)
{
MetaWaylandDataSourcePrivate *priv =
meta_wayland_data_source_get_instance_private ((MetaWaylandDataSource *)source);
meta_wayland_data_source_get_instance_private (source);
gchar **p;
wl_array_for_each (p, &priv->mime_types)

View File

@@ -45,11 +45,6 @@ struct _MetaWaylandDataSourceClass
void (* target) (MetaWaylandDataSource *source,
const gchar *mime_type);
void (* cancel) (MetaWaylandDataSource *source);
void (* action) (MetaWaylandDataSource *source,
uint32_t action);
void (* drop_performed) (MetaWaylandDataSource *source);
void (* drag_finished) (MetaWaylandDataSource *source);
};
struct _MetaWaylandDataDevice
@@ -74,6 +69,7 @@ void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_de
gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface);
void meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device);
void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
MetaWaylandDataSource *source);
@@ -99,17 +95,6 @@ void meta_wayland_data_source_send (MetaWaylandDataSource *source,
const gchar *mime_type,
gint fd);
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
uint32_t meta_wayland_data_source_get_actions (MetaWaylandDataSource *source);
uint32_t meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
uint32_t meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
uint32_t dnd_actions);
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
uint32_t action);
const MetaWaylandDragDestFuncs *
meta_wayland_data_device_get_drag_dest_funcs (void);

View File

@@ -56,19 +56,13 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <clutter/evdev/clutter-evdev.h>
#include "backends/meta-backend-private.h"
#include "meta-wayland-private.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
#endif
static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard);
static void notify_modifiers (MetaWaylandKeyboard *keyboard);
static guint evdev_code (const ClutterKeyEvent *event);
static void
unbind_resource (struct wl_resource *resource)
@@ -246,10 +240,8 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
}
static gboolean
meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
uint32_t time,
uint32_t key,
uint32_t state)
notify_key (MetaWaylandKeyboard *keyboard,
uint32_t time, uint32_t key, uint32_t state)
{
struct wl_resource *resource;
struct wl_list *l;
@@ -259,12 +251,11 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
{
struct wl_client *client = wl_resource_get_client (keyboard->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
keyboard->key_serial = wl_display_next_serial (display);
uint32_t serial = wl_display_next_serial (display);
wl_resource_for_each (resource, l)
{
wl_keyboard_send_key (resource, keyboard->key_serial, time, key, state);
wl_keyboard_send_key (resource, serial, time, key, state);
}
}
@@ -272,15 +263,8 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
return (keyboard->focus_surface != NULL);
}
static gboolean
notify_key (MetaWaylandKeyboard *keyboard,
const ClutterEvent *event)
{
return keyboard->grab->interface->key (keyboard->grab, event);
}
static void
meta_wayland_keyboard_broadcast_modifiers (MetaWaylandKeyboard *keyboard)
notify_modifiers (MetaWaylandKeyboard *keyboard)
{
struct xkb_state *state;
struct wl_resource *resource;
@@ -305,16 +289,6 @@ meta_wayland_keyboard_broadcast_modifiers (MetaWaylandKeyboard *keyboard)
}
}
static void
notify_modifiers (MetaWaylandKeyboard *keyboard)
{
struct xkb_state *state;
state = keyboard->xkb_info.state;
keyboard->grab->interface->modifiers (keyboard->grab,
xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE));
}
static void
meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
{
@@ -394,45 +368,6 @@ settings_changed (GSettings *settings,
notify_key_repeat (keyboard);
}
static gboolean
default_grab_key (MetaWaylandKeyboardGrab *grab,
const ClutterEvent *event)
{
MetaWaylandKeyboard *keyboard = grab->keyboard;
gboolean is_press = event->type == CLUTTER_KEY_PRESS;
guint32 code;
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend = meta_get_backend ();
#endif
/* Synthetic key events are for autorepeat. Ignore those, as
* autorepeat in Wayland is done on the client side. */
if (event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC)
return FALSE;
#ifdef HAVE_NATIVE_BACKEND
if (META_IS_BACKEND_NATIVE (backend))
code = clutter_evdev_event_get_event_code (event);
else
#endif
code = evdev_code (&event->key);
return meta_wayland_keyboard_broadcast_key (keyboard, event->key.time,
code, is_press);
}
static void
default_grab_modifiers (MetaWaylandKeyboardGrab *grab,
ClutterModifierType modifiers)
{
meta_wayland_keyboard_broadcast_modifiers (grab->keyboard);
}
static const MetaWaylandKeyboardGrabInterface default_keyboard_grab_interface = {
default_grab_key,
default_grab_modifiers
};
void
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
struct wl_display *display)
@@ -450,10 +385,6 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
keyboard->xkb_info.keymap_fd = -1;
keyboard->default_grab.interface = &default_keyboard_grab_interface;
keyboard->default_grab.keyboard = keyboard;
keyboard->grab = &keyboard->default_grab;
keyboard->settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
g_signal_connect (keyboard->settings, "changed",
G_CALLBACK (settings_changed), keyboard);
@@ -530,7 +461,7 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
is_press ? "press" : "release",
event->hardware_keycode);
handled = notify_key (keyboard, (const ClutterEvent *) event);
handled = notify_key (keyboard, event->time, evdev_code (event), is_press);
if (handled)
meta_verbose ("Sent event to wayland client\n");
@@ -741,25 +672,3 @@ meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
wl_list_insert (&keyboard->resource_list, wl_resource_get_link (cr));
}
}
gboolean
meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
uint32_t serial)
{
return keyboard->key_serial == serial;
}
void
meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard,
MetaWaylandKeyboardGrab *grab)
{
meta_wayland_keyboard_set_focus (keyboard, NULL);
keyboard->grab = grab;
grab->keyboard = keyboard;
}
void
meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard)
{
keyboard->grab = &keyboard->default_grab;
}

View File

@@ -49,20 +49,6 @@
#include <wayland-server.h>
#include <xkbcommon/xkbcommon.h>
struct _MetaWaylandKeyboardGrabInterface
{
gboolean (*key) (MetaWaylandKeyboardGrab *grab,
const ClutterEvent *event);
void (*modifiers) (MetaWaylandKeyboardGrab *grab,
ClutterModifierType modifiers);
};
struct _MetaWaylandKeyboardGrab
{
const MetaWaylandKeyboardGrabInterface *interface;
MetaWaylandKeyboard *keyboard;
};
typedef struct
{
struct xkb_keymap *keymap;
@@ -82,14 +68,10 @@ struct _MetaWaylandKeyboard
MetaWaylandSurface *focus_surface;
struct wl_listener focus_surface_listener;
uint32_t focus_serial;
uint32_t key_serial;
MetaWaylandXkbInfo xkb_info;
enum xkb_state_component mods_changed;
MetaWaylandKeyboardGrab *grab;
MetaWaylandKeyboardGrab default_grab;
GSettings *settings;
};
@@ -118,11 +100,4 @@ void meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
struct wl_resource *seat_resource,
uint32_t id);
gboolean meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
uint32_t serial);
void meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard,
MetaWaylandKeyboardGrab *grab);
void meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard);
#endif /* META_WAYLAND_KEYBOARD_H */

View File

@@ -99,7 +99,7 @@ bind_output (struct wl_client *client,
mode_flags,
(int)monitor_info->rect.width,
(int)monitor_info->rect.height,
(int)(monitor_info->refresh_rate * 1000));
(int)monitor_info->refresh_rate);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
wl_output_send_scale (resource, output->scale);
@@ -160,7 +160,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
mode_flags,
(int)monitor_info->rect.width,
(int)monitor_info->rect.height,
(int)(monitor_info->refresh_rate * 1000));
(int)monitor_info->refresh_rate);
}
/* It's very important that we change the output pointer here, as

View File

@@ -30,7 +30,7 @@
#include "meta-wayland-pointer-gesture-pinch.h"
#include "meta-wayland-pointer.h"
#include "meta-wayland-surface.h"
#include "pointer-gestures-unstable-v1-server-protocol.h"
#include "pointer-gestures-server-protocol.h"
static void
handle_pinch_begin (MetaWaylandPointer *pointer,
@@ -45,10 +45,10 @@ handle_pinch_begin (MetaWaylandPointer *pointer,
wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
{
zwp_pointer_gesture_pinch_v1_send_begin (resource, serial,
clutter_event_get_time (event),
pointer->focus_surface->resource,
2);
_wl_pointer_gesture_pinch_send_begin (resource, serial,
clutter_event_get_time (event),
pointer->focus_surface->resource,
2);
}
}
@@ -67,12 +67,12 @@ handle_pinch_update (MetaWaylandPointer *pointer,
wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
{
zwp_pointer_gesture_pinch_v1_send_update (resource,
clutter_event_get_time (event),
wl_fixed_from_double (dx),
wl_fixed_from_double (dy),
wl_fixed_from_double (scale),
wl_fixed_from_double (rotation));
_wl_pointer_gesture_pinch_send_update (resource,
clutter_event_get_time (event),
wl_fixed_from_double (dx),
wl_fixed_from_double (dy),
wl_fixed_from_double (scale),
wl_fixed_from_double (rotation));
}
}
@@ -93,9 +93,9 @@ handle_pinch_end (MetaWaylandPointer *pointer,
wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
{
zwp_pointer_gesture_pinch_v1_send_end (resource, serial,
clutter_event_get_time (event),
cancelled);
_wl_pointer_gesture_pinch_send_end (resource, serial,
clutter_event_get_time (event),
cancelled);
}
}
@@ -135,7 +135,7 @@ pointer_gesture_pinch_destroy (struct wl_client *client,
wl_resource_destroy (resource);
}
static const struct zwp_pointer_gesture_pinch_v1_interface pointer_gesture_pinch_interface = {
static const struct _wl_pointer_gesture_pinch_interface pointer_gesture_pinch_interface = {
pointer_gesture_pinch_destroy
};
@@ -151,7 +151,7 @@ meta_wayland_pointer_gesture_pinch_create_new_resource (MetaWaylandPointer *poin
pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
g_return_if_fail (pointer_client != NULL);
res = wl_resource_create (client, &zwp_pointer_gesture_pinch_v1_interface,
res = wl_resource_create (client, &_wl_pointer_gesture_pinch_interface,
wl_resource_get_version (gestures_resource), id);
wl_resource_set_implementation (res, &pointer_gesture_pinch_interface, pointer,
meta_wayland_pointer_unbind_pointer_client_resource);

View File

@@ -30,7 +30,7 @@
#include "meta-wayland-pointer-gesture-swipe.h"
#include "meta-wayland-pointer.h"
#include "meta-wayland-surface.h"
#include "pointer-gestures-unstable-v1-server-protocol.h"
#include "pointer-gestures-server-protocol.h"
static void
handle_swipe_begin (MetaWaylandPointer *pointer,
@@ -46,10 +46,10 @@ handle_swipe_begin (MetaWaylandPointer *pointer,
wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
{
zwp_pointer_gesture_swipe_v1_send_begin (resource, serial,
clutter_event_get_time (event),
pointer->focus_surface->resource,
fingers);
_wl_pointer_gesture_swipe_send_begin (resource, serial,
clutter_event_get_time (event),
pointer->focus_surface->resource,
fingers);
}
}
@@ -66,10 +66,10 @@ handle_swipe_update (MetaWaylandPointer *pointer,
wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
{
zwp_pointer_gesture_swipe_v1_send_update (resource,
clutter_event_get_time (event),
wl_fixed_from_double (dx),
wl_fixed_from_double (dy));
_wl_pointer_gesture_swipe_send_update (resource,
clutter_event_get_time (event),
wl_fixed_from_double (dx),
wl_fixed_from_double (dy));
}
}
@@ -90,9 +90,9 @@ handle_swipe_end (MetaWaylandPointer *pointer,
wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
{
zwp_pointer_gesture_swipe_v1_send_end (resource, serial,
clutter_event_get_time (event),
cancelled);
_wl_pointer_gesture_swipe_send_end (resource, serial,
clutter_event_get_time (event),
cancelled);
}
}
@@ -131,7 +131,7 @@ pointer_gesture_swipe_release (struct wl_client *client,
wl_resource_destroy (resource);
}
static const struct zwp_pointer_gesture_swipe_v1_interface pointer_gesture_swipe_interface = {
static const struct _wl_pointer_gesture_swipe_interface pointer_gesture_swipe_interface = {
pointer_gesture_swipe_release
};
@@ -147,7 +147,7 @@ meta_wayland_pointer_gesture_swipe_create_new_resource (MetaWaylandPointer *poin
pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
g_return_if_fail (pointer_client != NULL);
res = wl_resource_create (client, &zwp_pointer_gesture_swipe_v1_interface,
res = wl_resource_create (client, &_wl_pointer_gesture_swipe_interface,
wl_resource_get_version (pointer_resource), id);
wl_resource_set_implementation (res, &pointer_gesture_swipe_interface, pointer,
meta_wayland_pointer_unbind_pointer_client_resource);

View File

@@ -27,7 +27,7 @@
#include <glib.h>
#include "meta-wayland-pointer-gestures.h"
#include "pointer-gestures-unstable-v1-server-protocol.h"
#include "pointer-gestures-server-protocol.h"
#include "meta-wayland-versions.h"
#include "meta-wayland-private.h"
@@ -53,7 +53,7 @@ gestures_get_pinch (struct wl_client *client,
meta_wayland_pointer_gesture_pinch_create_new_resource (pointer, client, resource, id);
}
static const struct zwp_pointer_gestures_v1_interface pointer_gestures_interface = {
static const struct _wl_pointer_gestures_interface pointer_gestures_interface = {
gestures_get_swipe,
gestures_get_pinch
};
@@ -66,8 +66,16 @@ bind_pointer_gestures (struct wl_client *client,
{
struct wl_resource *resource;
resource = wl_resource_create (client, &zwp_pointer_gestures_v1_interface,
version, id);
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,7 +84,7 @@ void
meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor)
{
wl_global_create (compositor->wayland_display,
&zwp_pointer_gestures_v1_interface,
META_ZWP_POINTER_GESTURES_V1_VERSION,
&_wl_pointer_gestures_interface,
META__WL_POINTER_GESTURES_VERSION,
NULL, bind_pointer_gestures);
}

View File

@@ -44,7 +44,6 @@
#include "config.h"
#include <clutter/clutter.h>
#include <clutter/evdev/clutter-evdev.h>
#include <cogl/cogl.h>
#include <cogl/cogl-wayland-server.h>
#include <linux/input.h>
@@ -63,10 +62,6 @@
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-cursor-renderer.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
#endif
#include <string.h>
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
@@ -242,28 +237,6 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
meta_wayland_pointer_set_focus (pointer, NULL);
}
static void
meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer,
struct wl_resource *resource)
{
if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
wl_pointer_send_frame (resource);
}
static void
meta_wayland_pointer_broadcast_frame (MetaWaylandPointer *pointer)
{
struct wl_resource *resource;
if (!pointer->focus_client)
return;
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
{
meta_wayland_pointer_send_frame (pointer, resource);
}
}
void
meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
const ClutterEvent *event)
@@ -284,8 +257,6 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
{
wl_pointer_send_motion (resource, time, sx, sy);
}
meta_wayland_pointer_broadcast_frame (pointer);
}
void
@@ -306,37 +277,26 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
uint32_t button;
uint32_t serial;
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend = meta_get_backend ();
if (META_IS_BACKEND_NATIVE (backend))
button = clutter_evdev_event_get_event_code (event);
else
#endif
{
button = clutter_event_get_button (event);
switch (button)
{
case 1:
button = BTN_LEFT;
break;
/* The evdev input right and middle button numbers are swapped
relative to how Clutter numbers them */
case 2:
button = BTN_MIDDLE;
break;
case 3:
button = BTN_RIGHT;
break;
default:
button = button + (BTN_LEFT - 1) + 4;
break;
}
}
time = clutter_event_get_time (event);
button = clutter_event_get_button (event);
switch (button)
{
/* The evdev input right and middle button numbers are swapped
relative to how Clutter numbers them */
case 2:
button = BTN_MIDDLE;
break;
case 3:
button = BTN_RIGHT;
break;
default:
button = button + BTN_LEFT - 1;
break;
}
serial = wl_display_next_serial (display);
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
@@ -345,8 +305,6 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
time, button,
event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
}
meta_wayland_pointer_broadcast_frame (pointer);
}
if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE)
@@ -536,48 +494,26 @@ handle_scroll_event (MetaWaylandPointer *pointer,
{
struct wl_resource *resource;
wl_fixed_t x_value = 0, y_value = 0;
int x_discrete = 0, y_discrete = 0;
enum wl_pointer_axis_source source = -1;
if (clutter_event_is_pointer_emulated (event))
return;
switch (event->scroll.scroll_source)
{
case CLUTTER_SCROLL_SOURCE_WHEEL:
source = WL_POINTER_AXIS_SOURCE_WHEEL;
break;
case CLUTTER_SCROLL_SOURCE_FINGER:
source = WL_POINTER_AXIS_SOURCE_FINGER;
break;
case CLUTTER_SCROLL_SOURCE_CONTINUOUS:
source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
break;
default:
source = WL_POINTER_AXIS_SOURCE_WHEEL;
break;
}
switch (clutter_event_get_scroll_direction (event))
{
case CLUTTER_SCROLL_UP:
y_value = -DEFAULT_AXIS_STEP_DISTANCE;
y_discrete = -1;
break;
case CLUTTER_SCROLL_DOWN:
y_value = DEFAULT_AXIS_STEP_DISTANCE;
y_discrete = 1;
break;
case CLUTTER_SCROLL_LEFT:
x_value = -DEFAULT_AXIS_STEP_DISTANCE;
x_discrete = -1;
break;
case CLUTTER_SCROLL_RIGHT:
x_value = DEFAULT_AXIS_STEP_DISTANCE;
x_discrete = 1;
break;
case CLUTTER_SCROLL_SMOOTH:
@@ -601,44 +537,13 @@ handle_scroll_event (MetaWaylandPointer *pointer,
{
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
{
if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
wl_pointer_send_axis_source (resource, source);
/* X axis */
if (x_discrete != 0 &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
wl_pointer_send_axis_discrete (resource,
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
x_discrete);
if (x_value)
wl_pointer_send_axis (resource, clutter_event_get_time (event),
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
wl_pointer_send_axis_stop (resource,
clutter_event_get_time (event),
WL_POINTER_AXIS_HORIZONTAL_SCROLL);
/* Y axis */
if (y_discrete != 0 &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
wl_pointer_send_axis_discrete (resource,
WL_POINTER_AXIS_VERTICAL_SCROLL,
y_discrete);
if (y_value)
wl_pointer_send_axis (resource, clutter_event_get_time (event),
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
wl_pointer_send_axis_stop (resource,
clutter_event_get_time (event),
WL_POINTER_AXIS_VERTICAL_SCROLL);
}
meta_wayland_pointer_broadcast_frame (pointer);
}
}
@@ -677,57 +582,13 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
}
static void
meta_wayland_pointer_send_enter (MetaWaylandPointer *pointer,
struct wl_resource *pointer_resource,
uint32_t serial,
MetaWaylandSurface *surface)
broadcast_focus (MetaWaylandPointer *pointer,
struct wl_resource *resource)
{
wl_fixed_t sx, sy;
meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy);
wl_pointer_send_enter (pointer_resource,
serial,
surface->resource,
sx, sy);
}
static void
meta_wayland_pointer_send_leave (MetaWaylandPointer *pointer,
struct wl_resource *pointer_resource,
uint32_t serial,
MetaWaylandSurface *surface)
{
wl_pointer_send_leave (pointer_resource, serial, surface->resource);
}
static void
meta_wayland_pointer_broadcast_enter (MetaWaylandPointer *pointer,
uint32_t serial,
MetaWaylandSurface *surface)
{
struct wl_resource *pointer_resource;
wl_resource_for_each (pointer_resource,
&pointer->focus_client->pointer_resources)
meta_wayland_pointer_send_enter (pointer, pointer_resource,
serial, surface);
meta_wayland_pointer_broadcast_frame (pointer);
}
static void
meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer,
uint32_t serial,
MetaWaylandSurface *surface)
{
struct wl_resource *pointer_resource;
wl_resource_for_each (pointer_resource,
&pointer->focus_client->pointer_resources)
meta_wayland_pointer_send_leave (pointer, pointer_resource,
serial, surface);
meta_wayland_pointer_broadcast_frame (pointer);
meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy);
wl_pointer_send_enter (resource, pointer->focus_serial, pointer->focus_surface->resource, sx, sy);
}
void
@@ -746,14 +607,18 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
wl_resource_get_client (pointer->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
uint32_t serial;
struct wl_resource *resource;
serial = wl_display_next_serial (display);
if (pointer->focus_client)
{
meta_wayland_pointer_broadcast_leave (pointer,
serial,
pointer->focus_surface);
wl_resource_for_each (resource,
&pointer->focus_client->pointer_resources)
{
wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
}
pointer->focus_client = NULL;
}
@@ -765,6 +630,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
{
struct wl_client *client = wl_resource_get_client (surface->resource);
struct wl_display *display = wl_client_get_display (client);
struct wl_resource *resource;
ClutterPoint pos;
pointer->focus_surface = surface;
@@ -783,9 +649,12 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
if (pointer->focus_client)
{
pointer->focus_serial = wl_display_next_serial (display);
meta_wayland_pointer_broadcast_enter (pointer,
pointer->focus_serial,
pointer->focus_surface);
wl_resource_for_each (resource,
&pointer->focus_client->pointer_resources)
{
broadcast_focus (pointer, resource);
}
}
}
@@ -1061,12 +930,7 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
wl_resource_get_link (cr));
if (pointer->focus_client == pointer_client)
{
meta_wayland_pointer_send_enter (pointer, cr,
pointer->focus_serial,
pointer->focus_surface);
meta_wayland_pointer_send_frame (pointer, cr);
}
broadcast_focus (pointer, cr);
}
gboolean

View File

@@ -405,12 +405,3 @@ meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
return sequence || can_grab_surface;
}
gboolean
meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
uint32_t serial)
{
return (meta_wayland_pointer_can_popup (&seat->pointer, serial) ||
meta_wayland_keyboard_can_popup (&seat->keyboard, serial) ||
meta_wayland_touch_can_popup (&seat->touch, serial));
}

View File

@@ -64,7 +64,5 @@ gboolean meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
uint32_t serial,
gfloat *x,
gfloat *y);
gboolean meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
uint32_t serial);
#endif /* META_WAYLAND_SEAT_H */

View File

@@ -31,7 +31,7 @@
#include <wayland-server.h>
#include "gtk-shell-server-protocol.h"
#include "xdg-shell-unstable-v5-server-protocol.h"
#include "xdg-shell-server-protocol.h"
#include "meta-wayland-private.h"
#include "meta-xwayland-private.h"
@@ -257,6 +257,8 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_surface_role_get_surface (surface_role);
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
meta_wayland_data_device_update_dnd_surface (&surface->compositor->seat->data_device);
}
static void
@@ -931,26 +933,22 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
MetaWaylandOutput *wayland_output,
gboolean is_on_output)
{
gpointer orig_id;
gboolean was_on_output = g_hash_table_lookup_extended (surface->outputs_to_destroy_notify_id,
wayland_output,
NULL, &orig_id);
gboolean was_on_output = g_hash_table_contains (surface->outputs,
wayland_output);
if (!was_on_output && is_on_output)
{
gulong id;
id = g_signal_connect (wayland_output, "output-destroyed",
G_CALLBACK (surface_handle_output_destroy),
surface);
g_hash_table_insert (surface->outputs_to_destroy_notify_id, wayland_output,
GSIZE_TO_POINTER ((gsize)id));
g_signal_connect (wayland_output, "output-destroyed",
G_CALLBACK (surface_handle_output_destroy),
surface);
g_hash_table_add (surface->outputs, wayland_output);
surface_entered_output (surface, wayland_output);
}
else if (was_on_output && !is_on_output)
{
g_hash_table_remove (surface->outputs_to_destroy_notify_id, wayland_output);
g_signal_handler_disconnect (wayland_output, (gulong) GPOINTER_TO_SIZE (orig_id));
g_hash_table_remove (surface->outputs, wayland_output);
g_signal_handlers_disconnect_by_func (
wayland_output, (gpointer)surface_handle_output_destroy, surface);
surface_left_output (surface, wayland_output);
}
}
@@ -988,12 +986,6 @@ update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
set_surface_is_on_output (surface, wayland_output, is_on_output);
}
static void
surface_output_disconnect_signal (gpointer key, gpointer value, gpointer user_data)
{
g_signal_handler_disconnect (key, (gulong) GPOINTER_TO_SIZE (value));
}
void
meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
{
@@ -1044,8 +1036,7 @@ wl_surface_destructor (struct wl_resource *resource)
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
g_hash_table_foreach (surface->outputs_to_destroy_notify_id, surface_output_disconnect_signal, surface);
g_hash_table_unref (surface->outputs_to_destroy_notify_id);
g_hash_table_unref (surface->outputs);
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
wl_resource_destroy (cb->resource);
@@ -1090,7 +1081,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
sync_drag_dest_funcs (surface);
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
surface->outputs = g_hash_table_new (NULL, NULL);
pending_state_init (&surface->pending);
return surface;
@@ -1431,8 +1422,8 @@ handle_popup_parent_destroyed (struct wl_listener *listener, void *data)
MetaWaylandSurface *surface =
wl_container_of (listener, surface, popup.parent_destroy_listener);
wl_resource_post_error (surface->xdg_shell_resource,
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
wl_resource_post_error (surface->xdg_popup,
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
"destroyed popup not top most popup");
surface->popup.parent = NULL;
@@ -1450,8 +1441,8 @@ handle_popup_destroyed (struct wl_listener *listener, void *data)
top_popup = meta_wayland_popup_get_top_popup (popup);
if (surface != top_popup)
{
wl_resource_post_error (surface->xdg_shell_resource,
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
wl_resource_post_error (surface->xdg_popup,
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
"destroyed popup not top most popup");
}
@@ -1502,7 +1493,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
(parent_surf->xdg_popup == NULL && parent_surf->xdg_surface == NULL))
{
wl_resource_post_error (resource,
XDG_SHELL_ERROR_INVALID_POPUP_PARENT,
XDG_POPUP_ERROR_INVALID_PARENT,
"invalid parent surface");
return;
}
@@ -1512,7 +1503,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
(top_popup != NULL && parent_surf != top_popup))
{
wl_resource_post_error (resource,
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
"parent not top most surface");
return;
}
@@ -1524,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_seat_can_popup (seat, serial))
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,
@@ -1748,7 +1739,7 @@ wl_shell_surface_set_popup (struct wl_client *client,
wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
if (!meta_wayland_seat_can_popup (seat, serial))
if (!meta_wayland_pointer_can_popup (&seat->pointer, serial))
{
wl_shell_surface_send_popup_done (resource);
return;
@@ -2385,15 +2376,6 @@ meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface)
surface->dnd.funcs->drop (data_device, surface);
}
void
meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
surface->dnd.funcs->update (data_device, surface);
}
MetaWindow *
meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
{

View File

@@ -128,8 +128,6 @@ struct _MetaWaylandDragDestFuncs
const ClutterEvent *event);
void (* drop) (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface);
void (* update) (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface);
};
struct _MetaWaylandSurface
@@ -149,7 +147,7 @@ struct _MetaWaylandSurface
int scale;
int32_t offset_x, offset_y;
GList *subsurfaces;
GHashTable *outputs_to_destroy_notify_id;
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.
@@ -242,7 +240,6 @@ void meta_wayland_surface_drag_dest_motion (MetaWaylandSurface
const ClutterEvent *event);
void meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface);
void meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface);
void meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface);
void meta_wayland_surface_update_outputs (MetaWaylandSurface *surface);

View File

@@ -208,8 +208,8 @@ touch_get_relative_coordinates (MetaWaylandTouch *touch,
&event_x, &event_y);
}
*x = event_x / surface->scale;
*y = event_y / surface->scale;
*x = event_x;
*y = event_y;
}
@@ -575,26 +575,6 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
}
gboolean
meta_wayland_touch_can_popup (MetaWaylandTouch *touch,
uint32_t serial)
{
MetaWaylandTouchInfo *touch_info;
GHashTableIter iter;
if (!touch->touches)
return FALSE;
g_hash_table_iter_init (&iter, touch->touches);
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info))
{
if (touch_info->slot_serial == serial)
return TRUE;
}
return FALSE;
}
ClutterEventSequence *
meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch,
MetaWaylandSurface *surface,

View File

@@ -70,7 +70,4 @@ gboolean meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch,
gfloat *x,
gfloat *y);
gboolean meta_wayland_touch_can_popup (MetaWaylandTouch *touch,
uint32_t serial);
#endif /* META_WAYLAND_TOUCH_H */

View File

@@ -29,8 +29,6 @@ typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface;
typedef struct _MetaWaylandPopupGrab MetaWaylandPopupGrab;
typedef struct _MetaWaylandPopup MetaWaylandPopup;
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
typedef struct _MetaWaylandKeyboardGrab MetaWaylandKeyboardGrab;
typedef struct _MetaWaylandKeyboardGrabInterface MetaWaylandKeyboardGrabInterface;
typedef struct _MetaWaylandTouch MetaWaylandTouch;
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;

View File

@@ -36,14 +36,14 @@
/* Global/master objects (version exported by wl_registry and negotiated through bind) */
#define META_WL_COMPOSITOR_VERSION 3
#define META_WL_DATA_DEVICE_MANAGER_VERSION 3
#define META_WL_DATA_DEVICE_MANAGER_VERSION 2
#define META_XDG_SHELL_VERSION 1
#define META_WL_SHELL_VERSION 1
#define META_WL_SEAT_VERSION 5
#define META_WL_SEAT_VERSION 4
#define META_WL_OUTPUT_VERSION 2
#define META_XSERVER_VERSION 1
#define META_GTK_SHELL_VERSION 2
#define META_WL_SUBCOMPOSITOR_VERSION 1
#define META_ZWP_POINTER_GESTURES_V1_VERSION 1
#define META__WL_POINTER_GESTURES_VERSION 1
#endif

View File

@@ -337,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));
}

View File

@@ -108,7 +108,6 @@ enum {
ATOM_DND_ACTION_MOVE,
ATOM_DND_ACTION_COPY,
ATOM_DND_ACTION_ASK,
ATOM_DND_ACTION_PRIVATE,
N_DND_ATOMS
};
@@ -127,7 +126,6 @@ const gchar *atom_names[] = {
"XdndActionMove",
"XdndActionCopy",
"XdndActionAsk",
"XdndActionPrivate",
NULL
};
@@ -137,33 +135,6 @@ G_DEFINE_TYPE (MetaWaylandDataSourceXWayland, meta_wayland_data_source_xwayland,
META_TYPE_WAYLAND_DATA_SOURCE);
/* XDND helpers */
static Atom
action_to_atom (uint32_t action)
{
if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
return xdnd_atoms[ATOM_DND_ACTION_COPY];
else if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
return xdnd_atoms[ATOM_DND_ACTION_MOVE];
else if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
return xdnd_atoms[ATOM_DND_ACTION_ASK];
else
return None;
}
static enum wl_data_device_manager_dnd_action
atom_to_action (Atom atom)
{
if (atom == xdnd_atoms[ATOM_DND_ACTION_COPY] ||
atom == xdnd_atoms[ATOM_DND_ACTION_PRIVATE])
return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
else if (atom == xdnd_atoms[ATOM_DND_ACTION_MOVE])
return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
else if (atom == xdnd_atoms[ATOM_DND_ACTION_ASK])
return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
else
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
}
static void
xdnd_send_enter (MetaXWaylandSelection *selection_data,
Window dest)
@@ -246,21 +217,10 @@ xdnd_send_position (MetaXWaylandSelection *selection_data,
int x,
int y)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaSelectionBridge *selection = &selection_data->dnd.selection;
MetaWaylandDataSource *source = compositor->seat->data_device.dnd_data_source;
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
uint32_t action = 0, user_action, actions;
XEvent xev = { 0 };
user_action = meta_wayland_data_source_get_user_action (source);
actions = meta_wayland_data_source_get_actions (source);
if (user_action & actions)
action = user_action;
if (!action)
action = actions;
xev.xclient.type = ClientMessage;
xev.xclient.message_type = xdnd_atoms[ATOM_DND_POSITION];
xev.xclient.format = 32;
@@ -270,7 +230,7 @@ xdnd_send_position (MetaXWaylandSelection *selection_data,
xev.xclient.data.l[1] = 0;
xev.xclient.data.l[2] = (x << 16) | y;
xev.xclient.data.l[3] = time;
xev.xclient.data.l[4] = action_to_atom (action);
xev.xclient.data.l[4] = xdnd_atoms[ATOM_DND_ACTION_COPY];
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
}
@@ -302,8 +262,6 @@ xdnd_send_finished (MetaXWaylandSelection *selection_data,
{
MetaDndBridge *selection = &selection_data->dnd;
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
MetaWaylandDataSource *source = selection_data->dnd.selection.source;
uint32_t action = 0;
XEvent xev = { 0 };
xev.xclient.type = ClientMessage;
@@ -315,9 +273,8 @@ xdnd_send_finished (MetaXWaylandSelection *selection_data,
if (accepted)
{
action = meta_wayland_data_source_get_current_action (source);
xev.xclient.data.l[1] = 1; /* Drop successful */
xev.xclient.data.l[2] = action_to_atom (action);
xev.xclient.data.l[2] = xdnd_atoms[ATOM_DND_ACTION_COPY];
}
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
@@ -326,7 +283,7 @@ xdnd_send_finished (MetaXWaylandSelection *selection_data,
static void
xdnd_send_status (MetaXWaylandSelection *selection_data,
Window dest,
uint32_t action)
gboolean accepted)
{
MetaDndBridge *selection = &selection_data->dnd;
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
@@ -339,10 +296,12 @@ xdnd_send_status (MetaXWaylandSelection *selection_data,
xev.xclient.data.l[0] = selection->dnd_window;
xev.xclient.data.l[1] = 1 << 1; /* Bit 2: dest wants XdndPosition messages */
xev.xclient.data.l[4] = action_to_atom (action);
if (xev.xclient.data.l[4])
xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */
if (accepted)
{
xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */
xev.xclient.data.l[4] = xdnd_atoms[ATOM_DND_ACTION_COPY];
}
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
}
@@ -428,32 +387,6 @@ x11_selection_data_free (X11SelectionData *data)
g_slice_free (X11SelectionData, data);
}
static void
x11_selection_data_send_finished (MetaSelectionBridge *selection,
gboolean success)
{
uint32_t action = meta_wayland_data_source_get_current_action (selection->source);
if (!selection->x11_selection)
return;
if (success && action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
{
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
/* Request data deletion on the drag source */
XConvertSelection (xdisplay,
selection->selection_atom,
gdk_x11_get_xatom_by_name ("DELETE"),
gdk_x11_get_xatom_by_name ("_META_SELECTION"),
selection->window,
CurrentTime);
}
xdnd_send_finished (selection->x11_selection->selection_data,
selection->owner, success);
}
static void
x11_selection_data_finish (MetaSelectionBridge *selection,
gboolean success)
@@ -462,18 +395,13 @@ x11_selection_data_finish (MetaSelectionBridge *selection,
return;
if (selection == &selection->x11_selection->selection_data->dnd.selection)
x11_selection_data_send_finished (selection, success);
xdnd_send_finished (selection->x11_selection->selection_data,
selection->owner, success);
g_clear_pointer (&selection->x11_selection,
(GDestroyNotify) x11_selection_data_free);
}
static void
x11_selection_data_close (X11SelectionData *data)
{
g_output_stream_close (data->stream, data->cancellable, NULL);
}
static void
x11_data_write_cb (GObject *object,
GAsyncResult *res,
@@ -507,7 +435,6 @@ x11_data_write_cb (GObject *object,
}
else
{
x11_selection_data_close (selection->x11_selection);
x11_selection_data_finish (selection, success);
}
}
@@ -766,7 +693,6 @@ meta_xwayland_selection_get_incr_chunk (MetaWaylandCompositor *compositor,
else
{
/* Transfer has completed */
x11_selection_data_close (selection->x11_selection);
x11_selection_data_finish (selection, TRUE);
}
@@ -815,15 +741,11 @@ meta_x11_source_target (MetaWaylandDataSource *source,
MetaWaylandDataSourceXWayland *source_xwayland =
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
MetaSelectionBridge *selection = source_xwayland->selection;
uint32_t action = 0;
if (selection->selection_atom == xdnd_atoms[ATOM_DND_SELECTION])
{
if (mime_type)
action = meta_wayland_data_source_get_current_action (source);
xdnd_send_status (compositor->xwayland_manager.selection_data,
selection->owner, action);
selection->owner, mime_type != NULL);
}
}
@@ -834,46 +756,10 @@ meta_x11_source_cancel (MetaWaylandDataSource *source)
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
MetaSelectionBridge *selection = source_xwayland->selection;
x11_selection_data_send_finished (selection, FALSE);
g_clear_pointer (&selection->x11_selection,
(GDestroyNotify) x11_selection_data_free);
}
static void
meta_x11_source_action (MetaWaylandDataSource *source,
uint32_t action)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandDataSourceXWayland *source_xwayland =
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
MetaSelectionBridge *selection = source_xwayland->selection;
if (selection->selection_atom == xdnd_atoms[ATOM_DND_SELECTION])
{
if (!meta_wayland_data_source_has_target (source))
action = 0;
xdnd_send_status (compositor->xwayland_manager.selection_data,
selection->owner, action);
}
}
static void
meta_x11_source_drop_performed (MetaWaylandDataSource *source)
{
}
static void
meta_x11_source_drag_finished (MetaWaylandDataSource *source)
{
MetaWaylandDataSourceXWayland *source_xwayland =
META_WAYLAND_DATA_SOURCE_XWAYLAND (source);
MetaSelectionBridge *selection = source_xwayland->selection;
if (selection->x11_selection)
x11_selection_data_send_finished (selection, TRUE);
}
static void
meta_wayland_data_source_xwayland_init (MetaWaylandDataSourceXWayland *source_xwayland)
{
@@ -888,9 +774,6 @@ meta_wayland_data_source_xwayland_class_init (MetaWaylandDataSourceXWaylandClass
data_source_class->send = meta_x11_source_send;
data_source_class->target = meta_x11_source_target;
data_source_class->cancel = meta_x11_source_cancel;
data_source_class->action = meta_x11_source_action;
data_source_class->drop_performed = meta_x11_source_drop_performed;
data_source_class->drag_finished = meta_x11_source_drag_finished;
}
static MetaWaylandDataSource *
@@ -954,27 +837,11 @@ meta_x11_drag_dest_drop (MetaWaylandDataDevice *data_device,
meta_display_get_current_time_roundtrip (meta_get_display ()));
}
static void
meta_x11_drag_dest_update (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandSeat *seat = compositor->seat;
ClutterPoint pos;
clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
xdnd_send_position (compositor->xwayland_manager.selection_data,
compositor->xwayland_manager.selection_data->dnd.dnd_dest,
clutter_get_current_event_time (),
pos.x, pos.y);
}
static const MetaWaylandDragDestFuncs meta_x11_drag_dest_funcs = {
meta_x11_drag_dest_focus_in,
meta_x11_drag_dest_focus_out,
meta_x11_drag_dest_motion,
meta_x11_drag_dest_drop,
meta_x11_drag_dest_update
meta_x11_drag_dest_drop
};
const MetaWaylandDragDestFuncs *
@@ -1268,10 +1135,6 @@ meta_xwayland_selection_handle_selection_request (MetaWaylandCompositor *composi
selection->timestamp);
reply_selection_request (event, TRUE);
}
else if (data_source && event->target == gdk_x11_get_xatom_by_name ("DELETE"))
{
reply_selection_request (event, TRUE);
}
else
{
if (data_source &&
@@ -1394,7 +1257,6 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
if (event->window == dnd->selection.window)
{
MetaWaylandDataSource *data_source;
uint32_t action = 0;
data_source = compositor->seat->data_device.dnd_data_source;
@@ -1407,11 +1269,6 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
meta_wayland_data_source_set_has_target (data_source,
(event->data.l[1] & 1) != 0);
/* data.l[4] contains the action atom */
if (event->data.l[4])
action = atom_to_action ((Atom) event->data.l[4]);
meta_wayland_data_source_set_current_action (data_source, action);
return TRUE;
}
else if (event->message_type == xdnd_atoms[ATOM_DND_FINISHED])
@@ -1420,7 +1277,8 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
if (compositor->seat->data_device.current_grab)
return FALSE;
meta_wayland_data_source_notify_finish (data_source);
meta_wayland_data_device_set_dnd_source (&compositor->seat->data_device,
NULL);
return TRUE;
}
}
@@ -1432,8 +1290,7 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
MetaWaylandDragGrab *drag_grab = compositor->seat->data_device.current_grab;
MetaWaylandSurface *drag_focus = meta_wayland_drag_grab_get_focus (drag_grab);
if (!drag_focus &&
event->message_type != xdnd_atoms[ATOM_DND_ENTER])
if (!drag_focus)
return FALSE;
if (event->message_type == xdnd_atoms[ATOM_DND_ENTER])
@@ -1481,7 +1338,6 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
{
ClutterEvent *motion;
ClutterPoint pos;
uint32_t action = 0;
motion = clutter_event_new (CLUTTER_MOTION);
clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
@@ -1490,13 +1346,11 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
clutter_event_set_source_device (motion, seat->pointer.device);
clutter_event_set_time (motion, dnd->last_motion_time);
action = atom_to_action ((Atom) event->data.l[4]);
meta_wayland_data_source_set_actions (dnd->selection.source, action);
meta_wayland_surface_drag_dest_motion (drag_focus, motion);
xdnd_send_status (compositor->xwayland_manager.selection_data,
(Window) event->data.l[0],
meta_wayland_data_source_get_current_action (dnd->selection.source));
meta_wayland_data_source_has_target (
dnd->selection.source));
clutter_event_free (motion);
return TRUE;

View File

@@ -0,0 +1,176 @@
<protocol name="pointer_gestures">
<interface name="_wl_pointer_gestures" version="1">
<description summary="touchpad gestures">
A global interface to provide semantic touchpad gestures for a given
pointer.
Two gestures are currently supported: swipe and zoom/rotate.
All gestures follow a three-stage cycle: begin, update, end and
are identified by a unique id.
Warning! The protocol described in this file is experimental. Each
version of this protocol should be considered incompatible with any
other version, and a client binding to a version different to the one
advertised will be terminated. Once the protocol is declared stable,
compatibility is guaranteed, the '_' prefix will be removed from the
name and the version will be reset to 1.
</description>
<enum name="error">
<entry name="version_mismatch" value="0"/>
</enum>
<request name="get_swipe_gesture">
<description summary="get swipe gesture">
Create a swipe gesture object. See the
wl_pointer_gesture_swipe interface for details.
</description>
<arg name="id" type="new_id" interface="_wl_pointer_gesture_swipe"/>
<arg name="pointer" type="object" interface="wl_pointer"/>
</request>
<request name="get_pinch_gesture">
<description summary="get pinch gesture">
Create a pinch gesture object. See the
wl_pointer_gesture_pinch interface for details.
</description>
<arg name="id" type="new_id" interface="_wl_pointer_gesture_pinch"/>
<arg name="pointer" type="object" interface="wl_pointer"/>
</request>
</interface>
<interface name="_wl_pointer_gesture_swipe" version="1">
<description summary="a swipe gesture object">
A swipe gesture object notifies a client about a multi-finger swipe
gesture detected on an indirect input device such as a touchpad.
The gesture is usually initiated by multiple fingers moving in the
same direction but once initiated the direction may change.
The precise conditions of when such a gesture is detected are
implementation-dependent.
A gesture consists of three stages: begin, update (optional) and end.
There cannot be multiple simultaneous pinch or swipe gestures on a
same pointer/seat, how compositors prevent these situations is
implementation-dependent.
A gesture may be cancelled by the compositor or the hardware.
Clients should not consider performing permanent or irreversible
actions until the end of a gesture has been received.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the pointer swipe gesture object"/>
</request>
<event name="begin">
<description summary="multi-finger swipe begin">
This event is sent when a multi-finger swipe gesture is detected
on the device.
</description>
<arg name="serial" type="uint"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="fingers" type="uint" summary="number of fingers"/>
</event>
<event name="update">
<description summary="multi-finger swipe motion">
This event is sent when a multi-finger swipe gesture changes the
position of the logical center.
The dx and dy coordinates are relative coordinates of the logical
center of the gesture compared to the previous event.
</description>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/>
<arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/>
</event>
<event name="end">
<description summary="multi-finger swipe end">
This event is sent when a multi-finger swipe gesture ceases to
be valid. This may happen when one or more finger is lifted or
the gesture is cancelled.
When a gesture is cancelled, the client should undo state changes
caused by this gesture. What causes a gesture to be cancelled is
implementation-dependent.
</description>
<arg name="serial" type="uint"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/>
</event>
</interface>
<interface name="_wl_pointer_gesture_pinch" version="1">
<description summary="a pinch gesture object">
A pinch gesture object notifies a client about a multi-finger pinch
gesture detected on an indirect input device such as a touchpad.
The gesture is usually initiated by multiple fingers moving towards
each other or away from each other, or by two or more fingers rotating
around a logical center of gravity. The precise conditions of when
such a gesture is detected are implementation-dependent.
A gesture consists of three stages: begin, update (optional) and end.
There cannot be multiple simultaneous pinch or swipe gestures on a
same pointer/seat, how compositors prevent these situations is
implementation-dependent.
A gesture may be cancelled by the compositor or the hardware.
Clients should not consider performing permanent or irreversible
actions until the end of a gesture has been received.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the pinch gesture object"/>
</request>
<event name="begin">
<description summary="multi-finger pinch begin">
This event is sent when a multi-finger pinch gesture is detected
on the device.
</description>
<arg name="serial" type="uint"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="fingers" type="uint" summary="number of fingers"/>
</event>
<event name="update">
<description summary="multi-finger pinch motion">
This event is sent when a multi-finger pinch gesture changes the
position of the logical center, the rotation or the relative scale.
The dx and dy coordinates are relative coordinates in the
surface coordinate space of the logical center of the gesture.
The scale factor is an absolute scale compared to the
pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers
are now twice as far apart as on pointer_gesture_pinch.begin.
The rotation is the relative angle in degrees clockwise compared to the previous
pointer_gesture_pinch.begin or pointer_gesture_pinch.update event.
</description>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/>
<arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/>
<arg name="scale" type="fixed" summary="scale relative to the initial finger position"/>
<arg name="rotation" type="fixed" summary="angle in degrees cw relative to the previous event"/>
</event>
<event name="end">
<description summary="multi-finger pinch end">
This event is sent when a multi-finger pinch gesture ceases to
be valid. This may happen when one or more finger is lifted or
the gesture is cancelled.
When a gesture is cancelled, the client should undo state changes
caused by this gesture. What causes a gesture to be cancelled is
implementation-dependent.
</description>
<arg name="serial" type="uint"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/>
</event>
</interface>
</protocol>

View File

@@ -0,0 +1,485 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="xdg_shell">
<copyright>
Copyright © 2008-2013 Kristian Høgsberg
Copyright © 2013 Rafael Antognolli
Copyright © 2013 Jasper St. Pierre
Copyright © 2010-2013 Intel Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<interface name="xdg_shell" version="1">
<description summary="create desktop-style surfaces">
xdg_shell allows clients to turn a wl_surface into a "real window"
which can be dragged, resized, stacked, and moved around by the
user. Everything about this interface is suited towards traditional
desktop environments.
</description>
<enum name="version">
<description summary="latest protocol version">
The 'current' member of this enum gives the version of the
protocol. Implementations can compare this to the version
they implement using static_assert to ensure the protocol and
implementation versions match.
</description>
<entry name="current" value="5" summary="Always the latest version"/>
</enum>
<enum name="error">
<entry name="role" value="0" summary="given wl_surface has another role"/>
</enum>
<request name="destroy" type="destructor">
<description summary="destroy xdg_shell">
Destroy this xdg_shell object.
Destroying a bound xdg_shell object while there are surfaces
still alive with roles from this interface is illegal and will
result in a protocol error. Make sure to destroy all surfaces
before destroying this object.
</description>
</request>
<request name="use_unstable_version">
<description summary="enable use of this unstable version">
Negotiate the unstable version of the interface. This
mechanism is in place to ensure client and server agree on the
unstable versions of the protocol that they speak or exit
cleanly if they don't agree. This request will go away once
the xdg-shell protocol is stable.
</description>
<arg name="version" type="int"/>
</request>
<request name="get_xdg_surface">
<description summary="create a shell surface from a surface">
This creates an xdg_surface for the given surface and gives it the
xdg_surface role. See the documentation of xdg_surface for more details.
</description>
<arg name="id" type="new_id" interface="xdg_surface"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>
<request name="get_xdg_popup">
<description summary="create a popup for a surface">
This creates an xdg_popup for the given surface and gives it the
xdg_popup role. See the documentation of xdg_popup for more details.
This request must be used in response to some sort of user action
like a button press, key press, or touch down event.
</description>
<arg name="id" type="new_id" interface="xdg_popup"/>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="parent" type="object" interface="wl_surface"/>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/>
<arg name="x" type="int"/>
<arg name="y" type="int"/>
</request>
<event name="ping">
<description summary="check if the client is alive">
The ping event asks the client if it's still alive. Pass the
serial specified in the event back to the compositor by sending
a "pong" request back with the specified serial.
Compositors can use this to determine if the client is still
alive. It's unspecified what will happen if the client doesn't
respond to the ping request, or in what timeframe. Clients should
try to respond in a reasonable amount of time.
</description>
<arg name="serial" type="uint" summary="pass this to the pong request"/>
</event>
<request name="pong">
<description summary="respond to a ping event">
A client must respond to a ping event with a pong request or
the client may be deemed unresponsive.
</description>
<arg name="serial" type="uint" summary="serial of the ping event"/>
</request>
</interface>
<interface name="xdg_surface" version="1">
<description summary="A desktop window">
An interface that may be implemented by a wl_surface, for
implementations that provide a desktop-style user interface.
It provides requests to treat surfaces like windows, allowing to set
properties like maximized, fullscreen, minimized, and to move and resize
them, and associate metadata like title and app id.
</description>
<request name="destroy" type="destructor">
<description summary="Destroy the xdg_surface">
Unmap and destroy the window. The window will be effectively
hidden from the user's point of view, and all state like
maximization, fullscreen, and so on, will be lost.
</description>
</request>
<request name="set_parent">
<description summary="set the parent of this surface">
Set the "parent" of this surface. This window should be stacked
above a parent. The parent surface must be mapped as long as this
surface is mapped.
Parent windows should be set on dialogs, toolboxes, or other
"auxilliary" surfaces, so that the parent is raised when the dialog
is raised.
</description>
<arg name="parent" type="object" interface="xdg_surface" allow-null="true"/>
</request>
<request name="set_title">
<description summary="set surface title">
Set a short title for the surface.
This string may be used to identify the surface in a task bar,
window list, or other user interface elements provided by the
compositor.
The string must be encoded in UTF-8.
</description>
<arg name="title" type="string"/>
</request>
<request name="set_app_id">
<description summary="set application ID">
Set an application identifier for the surface.
The app ID identifies the general class of applications to which
the surface belongs. The compositor can use this to group multiple
applications together, or to determine how to launch a new
application.
See the desktop-entry specification [0] for more details on
application identifiers and how they relate to well-known DBus
names and .desktop files.
[0] http://standards.freedesktop.org/desktop-entry-spec/
</description>
<arg name="app_id" type="string"/>
</request>
<request name="show_window_menu">
<description summary="show the window menu">
Clients implementing client-side decorations might want to show
a context menu when right-clicking on the decorations, giving the
user a menu that they can use to maximize or minimize the window.
This request asks the compositor to pop up such a window menu at
the given position, relative to the local surface coordinates of
the parent surface. There are no guarantees as to what menu items
the window menu contains.
This request must be used in response to some sort of user action
like a button press, key press, or touch down event.
</description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/>
<arg name="x" type="int" summary="the x position to pop up the window menu at"/>
<arg name="y" type="int" summary="the y position to pop up the window menu at"/>
</request>
<request name="move">
<description summary="start an interactive move">
Start an interactive, user-driven move of the surface.
This request must be used in response to some sort of user action
like a button press, key press, or touch down event.
The server may ignore move requests depending on the state of
the surface (e.g. fullscreen or maximized).
</description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/>
</request>
<enum name="resize_edge">
<description summary="edge values for resizing">
These values are used to indicate which edge of a surface
is being dragged in a resize operation. The server may
use this information to adapt its behavior, e.g. choose
an appropriate cursor image.
</description>
<entry name="none" value="0"/>
<entry name="top" value="1"/>
<entry name="bottom" value="2"/>
<entry name="left" value="4"/>
<entry name="top_left" value="5"/>
<entry name="bottom_left" value="6"/>
<entry name="right" value="8"/>
<entry name="top_right" value="9"/>
<entry name="bottom_right" value="10"/>
</enum>
<request name="resize">
<description summary="start an interactive resize">
Start a user-driven, interactive resize of the surface.
This request must be used in response to some sort of user action
like a button press, key press, or touch down event.
The server may ignore resize requests depending on the state of
the surface (e.g. fullscreen or maximized).
</description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/>
<arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
</request>
<enum name="state">
<description summary="types of state on the surface">
The different state values used on the surface. This is designed for
state values like maximized, fullscreen. It is paired with the
configure event to ensure that both the client and the compositor
setting the state can be synchronized.
States set in this way are double-buffered. They will get applied on
the next commit.
Desktop environments may extend this enum by taking up a range of
values and documenting the range they chose in this description.
They are not required to document the values for the range that they
chose. Ideally, any good extensions from a desktop environment should
make its way into standardization into this enum.
The current reserved ranges are:
0x0000 - 0x0FFF: xdg-shell core values, documented below.
0x1000 - 0x1FFF: GNOME
</description>
<entry name="maximized" value="1" summary="the surface is maximized">
The surface is maximized. The window geometry specified in the configure
event must be obeyed by the client.
</entry>
<entry name="fullscreen" value="2" summary="the surface is fullscreen">
The surface is fullscreen. The window geometry specified in the configure
event must be obeyed by the client.
</entry>
<entry name="resizing" value="3">
The surface is being resized. The window geometry specified in the
configure event is a maximum; the client cannot resize beyond it.
Clients that have aspect ratio or cell sizing configuration can use
a smaller size, however.
</entry>
<entry name="activated" value="4">
Client window decorations should be painted as if the window is
active. Do not assume this means that the window actually has
keyboard or pointer focus.
</entry>
</enum>
<event name="configure">
<description summary="suggest a surface change">
The configure event asks the client to resize its surface or to
change its state.
The width and height arguments specify a hint to the window
about how its surface should be resized in window geometry
coordinates.
The states listed in the event specify how the width/height
arguments should be interpreted, and possibly how it should be
drawn.
Clients should arrange their surface for the new size and
states, and then send a ack_configure request with the serial
sent in this configure event at some point before committing
the new surface.
If the client receives multiple configure events before it
can respond to one, it is free to discard all but the last
event it received.
</description>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="states" type="array"/>
<arg name="serial" type="uint"/>
</event>
<request name="ack_configure">
<description summary="ack a configure event">
When a configure event is received, if a client commits the
surface in response to the configure event, then the client
must make a ack_configure request before the commit request,
passing along the serial of the configure event.
The compositor might use this information to move a surface
to the top left only when the client has drawn itself for
the maximized or fullscreen state.
If the client receives multiple configure events before it
can respond to one, it only has to ack the last configure event.
</description>
<arg name="serial" type="uint" summary="the serial from the configure event"/>
</request>
<request name="set_window_geometry">
<description summary="set the new window geometry">
The window geometry of a window is its "visible bounds" from the
user's perspective. Client-side decorations often have invisible
portions like drop-shadows which should be ignored for the
purposes of aligning, placing and constraining windows.
Once the window geometry of the surface is set once, it is not
possible to unset it, and it will remain the same until
set_window_geometry is called again, even if a new subsurface or
buffer is attached.
If never set, the value is the full bounds of the surface,
including any subsurfaces. This updates dynamically on every
commit. This unset mode is meant for extremely simple clients.
If responding to a configure event, the window geometry in here
must respect the sizing negotiations specified by the states in
the configure event.
The width and height must be greater than zero.
</description>
<arg name="x" type="int"/>
<arg name="y" type="int"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
</request>
<request name="set_maximized" />
<request name="unset_maximized" />
<request name="set_fullscreen">
<description summary="set the window as fullscreen on a monitor">
Make the surface fullscreen.
You can specify an output that you would prefer to be fullscreen.
If this value is NULL, it's up to the compositor to choose which
display will be used to map this surface.
</description>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
<request name="unset_fullscreen" />
<request name="set_minimized">
<description summary="set the window as minimized">
Request that the compositor minimize your surface. There is no
way to know if the surface is currently minimized, nor is there
any way to unset minimization on this surface.
If you are looking to throttle redrawing when minimized, please
instead use the wl_surface.frame event for this, as this will
also work with live previews on windows in Alt-Tab, Expose or
similar compositor features.
</description>
</request>
<event name="close">
<description summary="surface wants to be closed">
The close event is sent by the compositor when the user
wants the surface to be closed. This should be equivalent to
the user clicking the close button in client-side decorations,
if your application has any...
This is only a request that the user intends to close your
window. The client may choose to ignore this request, or show
a dialog to ask the user to save their data...
</description>
</event>
</interface>
<interface name="xdg_popup" version="1">
<description summary="short-lived, popup surfaces for menus">
A popup surface is a short-lived, temporary surface that can be
used to implement menus. It takes an explicit grab on the surface
that will be dismissed when the user dismisses the popup. This can
be done by the user clicking outside the surface, using the keyboard,
or even locking the screen through closing the lid or a timeout.
When the popup is dismissed, a popup_done event will be sent out,
and at the same time the surface will be unmapped. The xdg_popup
object is now inert and cannot be reactivated, so clients should
destroy it. Explicitly destroying the xdg_popup object will also
dismiss the popup and unmap the surface.
Clients will receive events for all their surfaces during this
grab (which is an "owner-events" grab in X11 parlance). This is
done so that users can navigate through submenus and other
"nested" popup windows without having to dismiss the topmost
popup.
Clients that want to dismiss the popup when another surface of
their own is clicked should dismiss the popup using the destroy
request.
The parent surface must have either an xdg_surface or xdg_popup
role.
Specifying an xdg_popup for the parent means that the popups are
nested, with this popup now being the topmost popup. Nested
popups must be destroyed in the reverse order they were created
in, e.g. the only popup you are allowed to destroy at all times
is the topmost one.
If there is an existing popup when creating a new popup, the
parent must be the current topmost popup.
A parent surface must be mapped before the new popup is mapped.
When compositors choose to dismiss a popup, they will likely
dismiss every nested popup as well.
The x and y arguments specify where the top left of the popup
should be placed, relative to the local surface coordinates of the
parent surface.
</description>
<enum name="error">
<description summary="xdg_popup error values">
These errors can be emitted in response to xdg_popup requests.
</description>
<entry name="not_the_topmost_popup" value="0" summary="The client tried to map or destroy a non-toplevel popup"/>
<entry name="invalid_parent" value="1" summary="The client specified an invalid parent surface"/>
</enum>
<request name="destroy" type="destructor">
<description summary="remove xdg_popup interface">
This destroys the popup. Explicitly destroying the xdg_popup
object will also dismiss the popup, and unmap the surface.
If this xdg_popup is not the "topmost" popup, a protocol error
will be sent.
</description>
</request>
<event name="popup_done">
<description summary="popup interaction is done">
The popup_done event is sent out when a popup is dismissed
by the compositor.
</description>
</event>
</interface>
</protocol>

View File

@@ -691,8 +691,7 @@ meta_spew_event_print (MetaDisplay *display,
static gboolean
handle_window_focus_event (MetaDisplay *display,
MetaWindow *window,
XIEnterEvent *event,
unsigned long serial)
XIEnterEvent *event)
{
MetaWindow *focus_window;
#ifdef WITH_VERBOSE_MODE
@@ -727,7 +726,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),
serial);
event->serial);
#endif
/* FIXME our pointer tracking is broken; see how
@@ -771,7 +770,7 @@ handle_window_focus_event (MetaDisplay *display,
if (event->evtype == XI_FocusIn)
{
display->server_focus_window = event->event;
display->server_focus_serial = serial;
display->server_focus_serial = event->serial;
focus_window = window;
}
else if (event->evtype == XI_FocusOut)
@@ -785,7 +784,7 @@ handle_window_focus_event (MetaDisplay *display,
}
display->server_focus_window = None;
display->server_focus_serial = serial;
display->server_focus_serial = event->serial;
focus_window = NULL;
}
else
@@ -830,9 +829,8 @@ crossing_serial_is_ignored (MetaDisplay *display,
}
static gboolean
handle_input_xevent (MetaDisplay *display,
XIEvent *input_event,
unsigned long serial)
handle_input_xevent (MetaDisplay *display,
XIEvent *input_event)
{
XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
Window modified;
@@ -869,7 +867,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, serial) &&
if (window && !crossing_serial_is_ignored (display, input_event->serial) &&
enter_event->mode != XINotifyGrab &&
enter_event->mode != XINotifyUngrab &&
enter_event->detail != XINotifyInferior &&
@@ -894,7 +892,7 @@ handle_input_xevent (MetaDisplay *display,
break;
case XI_FocusIn:
case XI_FocusOut:
if (handle_window_focus_event (display, window, enter_event, serial) &&
if (handle_window_focus_event (display, window, enter_event) &&
enter_event->event == enter_event->root)
{
if (enter_event->evtype == XI_FocusIn &&
@@ -1738,7 +1736,7 @@ meta_display_handle_xevent (MetaDisplay *display,
}
#endif /* HAVE_XI23 */
if (handle_input_xevent (display, input_event, event->xany.serial))
if (handle_input_xevent (display, input_event))
{
bypass_gtk = bypass_compositor = TRUE;
goto out;

View File

@@ -182,8 +182,6 @@ argbdata_to_surface (gulong *argb_data, int w, int h)
}
}
cairo_surface_mark_dirty (surface);
return surface;
}

View File

@@ -946,15 +946,7 @@ save_state (void)
/* Sticky */
if (window->on_all_workspaces_requested)
{
fputs (" <sticky/>\n", outfile);
} else {
int n;
n = meta_workspace_index (window->workspace);
fprintf (outfile,
" <workspace index=\"%d\"/>\n", n);
}
fputs (" <sticky/>\n", outfile);
/* Minimized */
if (window->minimized)
@@ -971,6 +963,14 @@ 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;

View File

@@ -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, LOAD_INIT | INCLUDE_OR },
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, NONE },
{ display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, LOAD_INIT | INCLUDE_OR },
{ 0 },
};

View File

@@ -389,7 +389,7 @@ meta_window_apply_session_info (MetaWindow *window,
"Restoring minimized state %d for window %s\n",
info->minimized, window->desc);
if (info->minimized)
if (window->has_minimize_func && info->minimized)
meta_window_minimize (window);
}
@@ -542,10 +542,13 @@ 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)
if (window->override_redirect)
{
priv->client_rect = window->rect;
window->buffer_rect = window->rect;
}
else
{
MetaRectangle rect;
MetaMoveResizeFlags flags;
@@ -860,7 +863,7 @@ meta_window_x11_grab_op_began (MetaWindow *window,
if (window->sync_request_counter != None)
meta_window_x11_create_sync_request_alarm (window);
if (window->size_hints.width_inc > 2 || window->size_hints.height_inc > 2)
if (window->size_hints.width_inc > 1 || window->size_hints.height_inc > 1)
{
priv->showing_resize_popup = TRUE;
meta_window_refresh_resize_popup (window);
@@ -1847,12 +1850,6 @@ meta_window_x11_update_shape_region (MetaWindow *window)
* this is simply the client area.
*/
cairo_region_intersect_rectangle (region, &client_area);
/* Some applications might explicitly set their bounding region
* to the client area. Detect these cases, and throw out the
* bounding region in this case. */
if (cairo_region_contains_rectangle (region, &client_area) == CAIRO_REGION_OVERLAP_IN)
g_clear_pointer (&region, cairo_region_destroy);
}
meta_window_set_shape_region (window, region);
@@ -2003,12 +2000,16 @@ meta_window_move_resize_request (MetaWindow *window,
if (flags & (META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION))
{
MetaRectangle rect, monitor_rect;
MetaRectangle old_frame_rect, old_buffer_rect;
gboolean legacy_fullscreen;
rect.x = x;
rect.y = y;
rect.width = width;
rect.height = height;
meta_window_get_frame_rect (window, &old_frame_rect);
meta_window_get_buffer_rect (window, &old_buffer_rect);
meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
/* Workaround braindead legacy apps that don't know how to
@@ -2018,12 +2019,14 @@ meta_window_move_resize_request (MetaWindow *window,
* if there are no struts making the workarea smaller than
* the monitor.
*/
if (meta_prefs_get_force_fullscreen() &&
!window->hide_titlebar_when_maximized &&
(window->decorated || !meta_window_is_client_decorated (window)) &&
meta_rectangle_equal (&rect, &monitor_rect) &&
window->has_fullscreen_func &&
!window->fullscreen)
legacy_fullscreen = (meta_prefs_get_force_fullscreen() &&
!window->hide_titlebar_when_maximized &&
(window->decorated || !meta_window_is_client_decorated (window)) &&
meta_rectangle_equal (&rect, &monitor_rect) &&
window->has_fullscreen_func &&
!window->fullscreen);
if (legacy_fullscreen)
{
/*
meta_topic (META_DEBUG_GEOMETRY,
@@ -2033,11 +2036,17 @@ meta_window_move_resize_request (MetaWindow *window,
"fullscreen request\n",
window->desc);
meta_window_make_fullscreen_internal (window);
flags |= META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR;
}
adjust_for_gravity (window, TRUE, gravity, &rect);
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
meta_window_move_resize_internal (window, flags, gravity, rect);
if (legacy_fullscreen)
meta_compositor_size_change_window (window->display->compositor,
window, META_SIZE_CHANGE_FULLSCREEN,
&old_frame_rect, &old_buffer_rect);
}
}
@@ -2444,7 +2453,8 @@ meta_window_x11_client_message (MetaWindow *window,
{
meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
event->xclient.data.l[0]);
if (event->xclient.data.l[0] == IconicState)
if (event->xclient.data.l[0] == IconicState &&
window->has_minimize_func)
meta_window_minimize (window);
return TRUE;

View File

@@ -194,7 +194,6 @@ async_get_property_finish (xcb_connection_t *xcb_conn,
{
xcb_get_property_reply_t *reply;
xcb_generic_error_t *error;
int length;
reply = xcb_get_property_reply (xcb_conn, cookie, &error);
if (error)
@@ -210,15 +209,8 @@ async_get_property_finish (xcb_connection_t *xcb_conn,
results->prop = NULL;
if (results->type != None)
{
length = xcb_get_property_value_length (reply);
/* Leave room for a trailing '\0' since xcb doesn't return null-terminated
* strings
*/
results->prop = g_malloc (length + 1);
memcpy (results->prop, xcb_get_property_value (reply), length);
results->prop[length] = '\0';
}
results->prop = g_memdup (xcb_get_property_value (reply),
xcb_get_property_value_length (reply));
free (reply);
return (results->prop != NULL);