backends: Expose InputMapping D-Bus path to determine tablet mapping

Currently, the peripheral "output" setting will be unset if Mutter is
deciding automatically the mapped output of a tablet device. In that
case, gnome-control-center will have a hard time figuring out itself
the better output to show the tablet calibration UI, unless it's hand
held by Mutter.

Add this private D-Bus interface so that gnome-control-center can look
up the output as determined by Mutter to bring the missing harmony
between both. This interface consists of a simple method to get the
mapped output for a input device node.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2605>
This commit is contained in:
Carlos Garnacho 2022-09-01 13:51:40 +02:00 committed by Marge Bot
parent 60b382c4e3
commit 7a1beb817d
4 changed files with 153 additions and 3 deletions

View File

@ -0,0 +1,19 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Mutter.InputMapper:
@short_description: input mapper interface
This interface is used by gnome-control-center to implement
tablet calibration.
-->
<interface name="org.gnome.Mutter.InputMapping">
<method name="GetDeviceMapping">
<arg name="device_node" direction="in" type="o" />
<arg name="rect" direction="out" type="(iiii)" />
</method>
</interface>
</node>

View File

@ -26,10 +26,13 @@
#include "backends/meta-backend-types.h"
#include "meta-dbus-input-mapping.h"
#define META_TYPE_INPUT_MAPPER (meta_input_mapper_get_type ())
G_DECLARE_FINAL_TYPE (MetaInputMapper, meta_input_mapper,
META, INPUT_MAPPER, GObject)
META, INPUT_MAPPER,
MetaDBusInputMappingSkeleton)
MetaInputMapper * meta_input_mapper_new (void);

View File

@ -30,6 +30,11 @@
#include "meta-logical-monitor.h"
#include "meta-backend-private.h"
#include "meta-dbus-input-mapping.h"
#define META_INPUT_MAPPING_DBUS_SERVICE "org.gnome.Mutter.InputMapping"
#define META_INPUT_MAPPING_DBUS_PATH "/org/gnome/Mutter/InputMapping"
#define MAX_SIZE_MATCH_DIFF 0.05
typedef struct _MetaMapperInputInfo MetaMapperInputInfo;
@ -40,7 +45,7 @@ typedef struct _DeviceMatch DeviceMatch;
struct _MetaInputMapper
{
GObject parent_instance;
MetaDBusInputMappingSkeleton parent_instance;
MetaMonitorManager *monitor_manager;
ClutterSeat *seat;
GHashTable *input_devices; /* ClutterInputDevice -> MetaMapperInputInfo */
@ -48,6 +53,7 @@ struct _MetaInputMapper
#ifdef HAVE_LIBGUDEV
GUdevClient *udev_client;
#endif
guint dbus_name_id;
};
typedef enum
@ -112,7 +118,12 @@ static void mapper_output_info_remove_input (MetaMapperOutputInfo *output,
static void mapper_recalculate_input (MetaInputMapper *mapper,
MetaMapperInputInfo *input);
G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT)
static void meta_input_mapping_init_iface (MetaDBusInputMappingIface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaInputMapper, meta_input_mapper,
META_DBUS_TYPE_INPUT_MAPPING_SKELETON,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_INPUT_MAPPING,
meta_input_mapping_init_iface))
static GSettings *
get_device_settings (ClutterInputDevice *device)
@ -709,6 +720,8 @@ meta_input_mapper_finalize (GObject *object)
{
MetaInputMapper *mapper = META_INPUT_MAPPER (object);
g_clear_handle_id (&mapper->dbus_name_id, g_bus_unown_name);
g_signal_handlers_disconnect_by_func (mapper->monitor_manager,
input_mapper_monitors_changed_cb,
mapper);
@ -792,6 +805,39 @@ meta_input_mapper_class_init (MetaInputMapperClass *klass)
G_TYPE_DOUBLE);
}
static void
on_bus_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
MetaRemoteDesktop *remote_desktop = user_data;
GDBusInterfaceSkeleton *interface_skeleton =
G_DBUS_INTERFACE_SKELETON (remote_desktop);
g_autoptr (GError) error = NULL;
if (!g_dbus_interface_skeleton_export (interface_skeleton,
connection,
META_INPUT_MAPPING_DBUS_PATH,
&error))
g_warning ("Failed to export input mapping object: %s", error->message);
}
static void
on_name_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_info ("Acquired name %s", name);
}
static void
on_name_lost (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_info ("Lost or failed to acquire name %s", name);
}
static void
meta_input_mapper_init (MetaInputMapper *mapper)
{
@ -801,8 +847,83 @@ meta_input_mapper_init (MetaInputMapper *mapper)
mapper->output_devices =
g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) mapper_output_info_free);
mapper->dbus_name_id =
g_bus_own_name (G_BUS_TYPE_SESSION,
META_INPUT_MAPPING_DBUS_SERVICE,
G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
mapper,
NULL);
}
static gboolean
handle_get_device_mapping (MetaDBusInputMapping *skeleton,
GDBusMethodInvocation *invocation,
const char *device_node)
{
MetaInputMapper *input_mapper = META_INPUT_MAPPER (skeleton);
ClutterInputDevice *device = NULL;
g_autoptr (GList) devices = NULL;
MetaLogicalMonitor *logical_monitor;
GList *l;
devices = clutter_seat_list_devices (input_mapper->seat);
for (l = devices; l; l = l->next)
{
if (g_strcmp0 (clutter_input_device_get_device_node (l->data),
device_node) == 0)
{
device = l->data;
break;
}
}
if (!device)
{
g_dbus_method_invocation_return_error (invocation,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"Device does not exist");
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
logical_monitor =
meta_input_mapper_get_device_logical_monitor (input_mapper, device);
if (logical_monitor)
{
MetaRectangle rect;
rect = meta_logical_monitor_get_layout (logical_monitor);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("((iiii))",
rect.x,
rect.y,
rect.width,
rect.height));
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
else
{
g_dbus_method_invocation_return_error (invocation,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Device is not mapped to any output");
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
}
static void
meta_input_mapping_init_iface (MetaDBusInputMappingIface *iface)
{
iface->handle_get_device_mapping = handle_get_device_mapping;
}
MetaInputMapper *
meta_input_mapper_new (void)
{

View File

@ -868,6 +868,13 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
)
mutter_built_sources += dbus_idle_monitor_built_sources
dbus_input_mapping_built_sources = gnome.gdbus_codegen('meta-dbus-input-mapping',
join_paths(dbus_interfaces_dir, 'org.gnome.Mutter.InputMapping.xml'),
interface_prefix: 'org.gnome.Mutter.',
namespace: 'MetaDBus',
)
mutter_built_sources += dbus_input_mapping_built_sources
if have_profiler
mutter_sources += [
'backends/meta-profiler.c',