Commit b8aa2bdb authored by Carlos Garnacho's avatar Carlos Garnacho Committed by Bastien Nocera
Browse files

cursor: Remove cursor plugin

Bug 712775 adds this logic to Mutter for both wayland and X11, so remove
the now redundant handling from here.

https://bugzilla.gnome.org/show_bug.cgi?id=744343
parent 2e685274
......@@ -56,7 +56,6 @@ plugins/a11y-settings/gsd-test-a11y-settings
plugins/background/test-background
plugins/common/gsd-test-input-helper
plugins/common/test-egg-key-parsing
plugins/cursor/gsd-test-cursor
plugins/datetime/gsd-test-datetime
plugins/datetime/geoclue.c
plugins/datetime/geoclue.h
......
......@@ -180,12 +180,6 @@ dnl ---------------------------------------------------------------------------
PKG_CHECK_MODULES(MOUSE, x11 xi)
dnl ---------------------------------------------------------------------------
dnl - cursor
dnl ---------------------------------------------------------------------------
PKG_CHECK_MODULES(CURSOR, xfixes gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
dnl ---------------------------------------------------------------------------
dnl - xsettings
dnl ---------------------------------------------------------------------------
......@@ -521,7 +515,6 @@ plugins/a11y-settings/Makefile
plugins/clipboard/Makefile
plugins/color/Makefile
plugins/common/Makefile
plugins/cursor/Makefile
plugins/datetime/Makefile
plugins/dummy/Makefile
plugins/power/Makefile
......
......@@ -13,7 +13,6 @@
<child name="a11y-settings" schema="org.gnome.settings-daemon.plugins.a11y-settings"/>
<child name="clipboard" schema="org.gnome.settings-daemon.plugins.clipboard"/>
<child name="color" schema="org.gnome.settings-daemon.plugins.color"/>
<child name="cursor" schema="org.gnome.settings-daemon.plugins.cursor"/>
<child name="datetime" schema="org.gnome.settings-daemon.plugins.datetime"/>
<child name="gsdwacom" schema="org.gnome.settings-daemon.plugins.gsdwacom"/>
<child name="housekeeping" schema="org.gnome.settings-daemon.plugins.housekeeping"/>
......@@ -66,18 +65,6 @@
<_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
</key>
</schema>
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.cursor" path="/org/gnome/settings-daemon/plugins/cursor/">
<key name="active" type="b">
<default>true</default>
<_summary>Activation of this plugin</_summary>
<_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
</key>
<key name="priority" type="i">
<default>0</default>
<_summary>Priority to use for this plugin</_summary>
<_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
</key>
</schema>
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.mouse" path="/org/gnome/settings-daemon/plugins/mouse/">
<key name="active" type="b">
<default>true</default>
......
......@@ -5,7 +5,6 @@ enabled_plugins = \
a11y-settings \
clipboard \
color \
cursor \
datetime \
dummy \
power \
......
plugin_name = cursor
plugin_LTLIBRARIES = \
libcursor.la
libcursor_la_SOURCES = \
gsd-cursor-manager.c \
gsd-cursor-manager.h \
gsd-cursor-plugin.c
libcursor_la_CPPFLAGS = \
-I$(top_srcdir)/gnome-settings-daemon \
-I$(top_builddir)/gnome-settings-daemon \
-I$(top_srcdir)/plugins/common/ \
-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
$(AM_CPPFLAGS)
libcursor_la_CFLAGS = \
$(PLUGIN_CFLAGS) \
$(CURSOR_CFLAGS) \
$(SETTINGS_PLUGIN_CFLAGS) \
$(AM_CFLAGS)
libcursor_la_LDFLAGS = \
$(GSD_PLUGIN_LDFLAGS)
libcursor_la_LIBADD = \
$(top_builddir)/plugins/common/libcommon.la \
$(CURSOR_LIBS) \
$(SETTINGS_PLUGIN_LIBS)
libexec_PROGRAMS = gsd-test-cursor
gsd_test_cursor_SOURCES = \
test-cursor.c \
gsd-cursor-manager.c \
gsd-cursor-manager.h
gsd_test_cursor_CPPFLAGS = \
-I$(top_srcdir)/data/ \
-I$(top_srcdir)/gnome-settings-daemon \
-I$(top_builddir)/gnome-settings-daemon \
-I$(top_srcdir)/plugins/common \
-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
-DLIBEXECDIR=\""$(libexecdir)"\" \
$(AM_CPPFLAGS)
gsd_test_cursor_CFLAGS = \
$(PLUGIN_CFLAGS) \
$(SETTINGS_PLUGIN_CFLAGS) \
$(CURSOR_CFLAGS) \
$(AM_CFLAGS)
gsd_test_cursor_LDADD = \
$(top_builddir)/gnome-settings-daemon/libgsd.la \
$(top_builddir)/plugins/common/libcommon.la \
$(SETTINGS_DAEMON_LIBS) \
$(SETTINGS_PLUGIN_LIBS) \
$(CURSOR_LIBS) \
-lm
plugin_in_files = \
cursor.gnome-settings-plugin.in
plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
EXTRA_DIST = \
$(plugin_in_files)
CLEANFILES = \
$(plugin_DATA)
DISTCLEANFILES = \
$(plugin_DATA)
@GSD_INTLTOOL_PLUGIN_RULE@
[GNOME Settings Plugin]
Module=cursor
IAge=0
# Default Priority
# Priority=100
_Name=Cursor
_Description=Show/hide cursor on tablet devices
Authors=Bastien Nocera <hadess@hadess.net>
Copyright=Copyright © 2011 Red Hat, Inc.
Website=
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2011-2013 Bastien Nocera <hadess@hadess.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <locale.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xfixes.h>
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-idle-monitor.h>
#include "gnome-settings-bus.h"
#include "gnome-settings-profile.h"
#include "gsd-cursor-manager.h"
#include "gsd-input-helper.h"
#define XFIXES_CURSOR_HIDING_MAJOR 4
#define GSD_CURSOR_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_CURSOR_MANAGER, GsdCursorManagerPrivate))
#define GSD_CURSOR_DBUS_NAME "org.gnome.SettingsDaemon.Cursor"
#define GSD_CURSOR_DBUS_PATH "/org/gnome/SettingsDaemon/Cursor"
#define GSD_CURSOR_DBUS_INTERFACE "org.gnome.SettingsDaemon.Cursor"
struct GsdCursorManagerPrivate
{
guint added_id;
guint removed_id;
guint changed_id;
gboolean cursor_shown;
GHashTable *monitors;
gboolean show_osk;
guint dbus_own_name_id;
guint dbus_register_object_id;
GCancellable *cancellable;
GDBusConnection *dbus_connection;
GDBusNodeInfo *dbus_introspection;
};
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.gnome.SettingsDaemon.Cursor'>"
" <property name='ShowOSK' type='b' access='read'/>"
" </interface>"
"</node>";
static void gsd_cursor_manager_class_init (GsdCursorManagerClass *klass);
static void gsd_cursor_manager_init (GsdCursorManager *cursor_manager);
G_DEFINE_TYPE (GsdCursorManager, gsd_cursor_manager, G_TYPE_OBJECT)
static gpointer manager_object = NULL;
static gboolean add_all_devices (GsdCursorManager *manager, GdkDevice *exception, GError **error);
static void
set_cursor_visibility (GsdCursorManager *manager,
gboolean visible)
{
GdkWindow *root;
Display *xdisplay;
g_debug ("Attempting to %s the cursor", visible ? "show" : "hide");
if (manager->priv->cursor_shown == visible)
return;
gdk_error_trap_push ();
root = gdk_screen_get_root_window (gdk_screen_get_default ());
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
if (visible)
XFixesShowCursor (xdisplay, GDK_WINDOW_XID (root));
else
XFixesHideCursor (xdisplay, GDK_WINDOW_XID (root));
if (gdk_error_trap_pop ()) {
g_warning ("An error occurred trying to %s the cursor",
visible ? "show" : "hide");
}
manager->priv->cursor_shown = visible;
}
static void
set_osk_enabled (GsdCursorManager *manager,
gboolean enabled)
{
GError *error = NULL;
GVariantBuilder *builder;
if (manager->priv->show_osk == enabled)
return;
g_debug ("Switching the OSK to %s", enabled ? "enabled" : "disabled");
manager->priv->show_osk = enabled;
if (manager->priv->dbus_connection == NULL)
return;
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
g_variant_builder_add (builder,
"{sv}",
"ShowOSK",
g_variant_new_boolean (enabled));
g_dbus_connection_emit_signal (manager->priv->dbus_connection,
NULL,
GSD_CURSOR_DBUS_PATH,
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
g_variant_new ("(sa{sv}as)",
GSD_CURSOR_DBUS_INTERFACE,
builder,
NULL),
&error);
if (error)
g_warning ("Error while emitting D-Bus signal: %s", error->message);
}
static void
monitor_became_active (GnomeIdleMonitor *monitor,
guint watch_id,
gpointer user_data)
{
GdkDevice *device;
GsdCursorManager *manager = GSD_CURSOR_MANAGER (user_data);
/* Oh, so you're active? */
g_object_get (G_OBJECT (monitor), "device", &device, NULL);
g_debug ("Device %d '%s' became active", gdk_x11_device_get_id (device), gdk_device_get_name (device));
set_cursor_visibility (manager,
gdk_device_get_source (device) != GDK_SOURCE_TOUCHSCREEN);
set_osk_enabled (manager,
gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN);
/* Remove the device from the watch */
g_hash_table_remove (manager->priv->monitors, device);
/* Make sure that all the other devices are watched
* (but not the one we just stopped monitoring */
add_all_devices (manager, device, NULL);
g_object_unref (device);
}
static gboolean
add_device (GdkDeviceManager *device_manager,
GdkDevice *device,
GsdCursorManager *manager,
GError **error)
{
GnomeIdleMonitor *monitor;
if (g_hash_table_lookup (manager->priv->monitors, device) != NULL)
return TRUE;
if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE)
return TRUE;
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
return TRUE;
if (strstr (gdk_device_get_name (device), "XTEST") != NULL)
return TRUE;
/* Create IdleMonitors for each pointer device */
monitor = gnome_idle_monitor_new_for_device (device, error);
if (!monitor)
return FALSE;
g_hash_table_insert (manager->priv->monitors,
device,
monitor);
gnome_idle_monitor_add_user_active_watch (monitor,
monitor_became_active,
manager,
NULL);
return TRUE;
}
static void
device_added_cb (GdkDeviceManager *device_manager,
GdkDevice *device,
GsdCursorManager *manager)
{
add_device (device_manager, device, manager, NULL);
}
static void
device_removed_cb (GdkDeviceManager *device_manager,
GdkDevice *device,
GsdCursorManager *manager)
{
g_hash_table_remove (manager->priv->monitors,
device);
}
static void
device_changed_cb (GdkDeviceManager *device_manager,
GdkDevice *device,
GsdCursorManager *manager)
{
if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_FLOATING)
device_removed_cb (device_manager, device, manager);
else
device_added_cb (device_manager, device, manager);
}
static gboolean
supports_xfixes (void)
{
gint op_code, event, error;
return XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
"XFIXES",
&op_code,
&event,
&error);
}
static gboolean
supports_cursor_xfixes (void)
{
int major = XFIXES_CURSOR_HIDING_MAJOR;
int minor = 0;
gdk_error_trap_push ();
if (!supports_xfixes ()) {
gdk_error_trap_pop_ignored ();
return FALSE;
}
if (!XFixesQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor)) {
gdk_error_trap_pop_ignored ();
return FALSE;
}
gdk_error_trap_pop_ignored ();
if (major >= XFIXES_CURSOR_HIDING_MAJOR)
return TRUE;
return FALSE;
}
static gboolean
add_all_devices (GsdCursorManager *manager,
GdkDevice *exception,
GError **error)
{
GdkDeviceManager *device_manager;
GList *devices, *l;
gboolean ret = TRUE;
device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE);
for (l = devices; l != NULL; l = l->next) {
GdkDevice *device = l->data;
if (device == exception)
continue;
if (!add_device (device_manager, device, manager, error)) {
ret = FALSE;
break;
}
}
g_list_free (devices);
return ret;
}
static GVariant *
handle_dbus_get_property (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
GsdCursorManager *manager)
{
GVariant *ret;
ret = NULL;
if (g_strcmp0 (property_name, "ShowOSK") == 0)
ret = g_variant_new_boolean (manager->priv->show_osk);
return ret;
}
static void
got_session_bus (GObject *source,
GAsyncResult *res,
GsdCursorManager *manager)
{
GsdCursorManagerPrivate *priv;
GDBusConnection *connection;
GError *error = NULL;
const GDBusInterfaceVTable vtable = {
NULL,
(GDBusInterfaceGetPropertyFunc)handle_dbus_get_property,
NULL,
};
connection = g_bus_get_finish (res, &error);
if (!connection) {
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_warning ("Couldn't get session bus: %s", error->message);
g_error_free (error);
return;
}
priv = manager->priv;
priv->dbus_connection = connection;
priv->dbus_register_object_id = g_dbus_connection_register_object (priv->dbus_connection,
GSD_CURSOR_DBUS_PATH,
priv->dbus_introspection->interfaces[0],
&vtable,
manager,
NULL,
&error);
if (!priv->dbus_register_object_id) {
g_warning ("Error registering object: %s", error->message);
g_error_free (error);
return;
}
priv->dbus_own_name_id = g_bus_own_name_on_connection (priv->dbus_connection,
GSD_CURSOR_DBUS_NAME,
G_BUS_NAME_OWNER_FLAGS_NONE,
NULL,
NULL,
NULL,
NULL);
}
static void
register_manager_dbus (GsdCursorManager *manager)
{
GError *error = NULL;
manager->priv->dbus_introspection = g_dbus_node_info_new_for_xml (introspection_xml, &error);
if (error) {
g_warning ("Error creating introspection data: %s", error->message);
g_error_free (error);
return;
}
g_bus_get (G_BUS_TYPE_SESSION,
manager->priv->cancellable,
(GAsyncReadyCallback) got_session_bus,
manager);
}
gboolean
gsd_cursor_manager_start (GsdCursorManager *manager,
GError **error)
{
GdkDeviceManager *device_manager;
if (gnome_settings_is_wayland ()) {
g_debug ("Running under a wayland compositor, disabling");
return TRUE;
}
g_debug ("Starting cursor manager");
gnome_settings_profile_start (NULL);
manager->priv->monitors = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
g_object_unref);
if (supports_cursor_xfixes () == FALSE) {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"XFixes cursor extension not available");
return FALSE;
}
if (supports_xinput_devices () == FALSE) {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"XInput support not available");
return FALSE;
}
device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
manager->priv->added_id = g_signal_connect (G_OBJECT (device_manager), "device-added",
G_CALLBACK (device_added_cb), manager);
manager->priv->removed_id = g_signal_connect (G_OBJECT (device_manager), "device-removed",
G_CALLBACK (device_removed_cb), manager);
manager->priv->changed_id = g_signal_connect (G_OBJECT (device_manager), "device-changed",
G_CALLBACK (device_changed_cb), manager);
if (!add_all_devices (manager, NULL, error)) {
g_debug ("Per-device idletime monitor not available, will not hide the cursor");
gnome_settings_profile_end (NULL);
return FALSE;
}
/* Start by hiding the cursor */
set_cursor_visibility (manager, FALSE);
manager->priv->cancellable = g_cancellable_new ();
register_manager_dbus (manager);
gnome_settings_profile_end (NULL);
return TRUE;
}
void
gsd_cursor_manager_stop (GsdCursorManager *manager)
{
GdkDeviceManager *device_manager;
g_debug ("Stopping cursor manager");
device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
if (manager->priv->added_id > 0) {
g_signal_handler_disconnect (G_OBJECT (device_manager), manager->priv->added_id);
manager->priv->added_id = 0;
}
if (manager->priv->removed_id > 0) {
g_signal_handler_disconnect (G_OBJECT (device_manager), manager->priv->removed_id);
manager->priv->removed_id = 0;
}
if (manager->priv->changed_id > 0) {
g_signal_handler_disconnect (G_OBJECT (device_manager), manager->priv->changed_id);
manager->priv->changed_id = 0;
}
if (manager->priv->cursor_shown == FALSE) {
set_cursor_visibility (manager, TRUE);