mirror of
https://github.com/brl/mutter.git
synced 2024-11-30 12:00:44 -05:00
backends: Map tablet pad rings/strips to action settings
Just like we do for buttons, with a few twists. These have 2 directions mappable to different keycombos, and are affected by the current mode in their group. https://bugzilla.gnome.org/show_bug.cgi?id=782033
This commit is contained in:
parent
0159efe34b
commit
cdb5ead795
@ -140,8 +140,8 @@ gboolean meta_input_settings_is_pad_button_grabbed (MetaIn
|
|||||||
ClutterInputDevice *pad,
|
ClutterInputDevice *pad,
|
||||||
guint button);
|
guint button);
|
||||||
|
|
||||||
gboolean meta_input_settings_handle_pad_button (MetaInputSettings *input_settings,
|
gboolean meta_input_settings_handle_pad_event (MetaInputSettings *input_settings,
|
||||||
const ClutterPadButtonEvent *event);
|
const ClutterEvent *event);
|
||||||
gchar * meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_settings,
|
gchar * meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_settings,
|
||||||
ClutterInputDevice *pad,
|
ClutterInputDevice *pad,
|
||||||
guint button);
|
guint button);
|
||||||
|
@ -80,6 +80,14 @@ struct _MetaInputSettingsPrivate
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
GHashTable *two_finger_devices;
|
GHashTable *two_finger_devices;
|
||||||
|
|
||||||
|
/* Pad ring/strip emission */
|
||||||
|
struct {
|
||||||
|
ClutterInputDevice *pad;
|
||||||
|
MetaPadActionType action;
|
||||||
|
guint number;
|
||||||
|
gdouble value;
|
||||||
|
} last_pad_action_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings,
|
typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings,
|
||||||
@ -92,6 +100,14 @@ typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings,
|
|||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
guint value);
|
guint value);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
META_PAD_DIRECTION_NONE = -1,
|
||||||
|
META_PAD_DIRECTION_UP = 0,
|
||||||
|
META_PAD_DIRECTION_DOWN,
|
||||||
|
META_PAD_DIRECTION_CW,
|
||||||
|
META_PAD_DIRECTION_CCW,
|
||||||
|
} MetaPadDirection;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
|
||||||
|
|
||||||
static GSList *
|
static GSList *
|
||||||
@ -1167,20 +1183,58 @@ lookup_tool_settings (ClutterInputDeviceTool *tool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GSettings *
|
static GSettings *
|
||||||
lookup_pad_button_settings (ClutterInputDevice *device,
|
lookup_pad_action_settings (ClutterInputDevice *device,
|
||||||
guint button)
|
MetaPadActionType action,
|
||||||
|
guint number,
|
||||||
|
MetaPadDirection direction,
|
||||||
|
gint mode)
|
||||||
{
|
{
|
||||||
const gchar *vendor, *product;
|
const gchar *vendor, *product, *action_type, *detail_type = NULL;
|
||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
gchar *path;
|
GString *path;
|
||||||
|
gchar action_label;
|
||||||
|
|
||||||
vendor = clutter_input_device_get_vendor_id (device);
|
vendor = clutter_input_device_get_vendor_id (device);
|
||||||
product = clutter_input_device_get_product_id (device);
|
product = clutter_input_device_get_product_id (device);
|
||||||
path = g_strdup_printf ("/org/gnome/desktop/peripherals/tablets/%s:%s/button%c/",
|
|
||||||
vendor, product, 'A' + button);
|
action_label = 'A' + number;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case META_PAD_ACTION_BUTTON:
|
||||||
|
action_type = "button";
|
||||||
|
break;
|
||||||
|
case META_PAD_ACTION_RING:
|
||||||
|
g_assert (direction == META_PAD_DIRECTION_CW ||
|
||||||
|
direction == META_PAD_DIRECTION_CCW);
|
||||||
|
action_type = "ring";
|
||||||
|
detail_type = (direction == META_PAD_DIRECTION_CW) ? "cw" : "ccw";
|
||||||
|
break;
|
||||||
|
case META_PAD_ACTION_STRIP:
|
||||||
|
g_assert (direction == META_PAD_DIRECTION_UP ||
|
||||||
|
direction == META_PAD_DIRECTION_DOWN);
|
||||||
|
action_type = "strip";
|
||||||
|
detail_type = (direction == META_PAD_DIRECTION_UP) ? "up" : "down";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = g_string_new (NULL);
|
||||||
|
g_string_append_printf (path, "/org/gnome/desktop/peripherals/tablets/%s:%s/%s%c",
|
||||||
|
vendor, product, action_type, action_label);
|
||||||
|
|
||||||
|
if (detail_type)
|
||||||
|
g_string_append_printf (path, "-%s", detail_type);
|
||||||
|
|
||||||
|
if (mode >= 0)
|
||||||
|
g_string_append_printf (path, "-mode-%d", mode);
|
||||||
|
|
||||||
|
g_string_append_c (path, '/');
|
||||||
|
|
||||||
settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet.pad-button",
|
settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet.pad-button",
|
||||||
path);
|
path->str);
|
||||||
g_free (path);
|
g_string_free (path, TRUE);
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
@ -1612,7 +1666,8 @@ meta_input_settings_get_pad_button_action (MetaInputSettings *input_settings,
|
|||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad),
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad),
|
||||||
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
||||||
|
|
||||||
settings = lookup_pad_button_settings (pad, button);
|
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
|
||||||
|
button, META_PAD_DIRECTION_NONE, -1);
|
||||||
action = g_settings_get_enum (settings, "action");
|
action = g_settings_get_enum (settings, "action");
|
||||||
g_object_unref (settings);
|
g_object_unref (settings);
|
||||||
|
|
||||||
@ -1761,24 +1816,20 @@ emulate_modifiers (ClutterVirtualInputDevice *device,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
meta_input_settings_emulate_keybinding (MetaInputSettings *input_settings,
|
meta_input_settings_emulate_keybinding (MetaInputSettings *input_settings,
|
||||||
ClutterInputDevice *pad,
|
const gchar *accel,
|
||||||
guint button,
|
|
||||||
gboolean is_press)
|
gboolean is_press)
|
||||||
{
|
{
|
||||||
MetaInputSettingsPrivate *priv;
|
MetaInputSettingsPrivate *priv;
|
||||||
ClutterKeyState state;
|
ClutterKeyState state;
|
||||||
GSettings *settings;
|
|
||||||
guint key, mods;
|
guint key, mods;
|
||||||
gchar *accel;
|
|
||||||
|
if (!accel || !*accel)
|
||||||
|
return;
|
||||||
|
|
||||||
priv = meta_input_settings_get_instance_private (input_settings);
|
priv = meta_input_settings_get_instance_private (input_settings);
|
||||||
settings = lookup_pad_button_settings (pad, button);
|
|
||||||
accel = g_settings_get_string (settings, "keybinding");
|
|
||||||
g_object_unref (settings);
|
|
||||||
|
|
||||||
/* FIXME: This is appalling */
|
/* FIXME: This is appalling */
|
||||||
gtk_accelerator_parse (accel, &key, &mods);
|
gtk_accelerator_parse (accel, &key, &mods);
|
||||||
g_free (accel);
|
|
||||||
|
|
||||||
if (!priv->virtual_pad_keyboard)
|
if (!priv->virtual_pad_keyboard)
|
||||||
{
|
{
|
||||||
@ -1815,20 +1866,21 @@ meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings,
|
|||||||
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
meta_input_settings_handle_pad_button (MetaInputSettings *input_settings,
|
meta_input_settings_handle_pad_button (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
const ClutterPadButtonEvent *event)
|
const ClutterPadButtonEvent *event)
|
||||||
{
|
{
|
||||||
GDesktopPadButtonAction action;
|
GDesktopPadButtonAction action;
|
||||||
ClutterInputDevice *pad;
|
|
||||||
gint button, group, mode;
|
gint button, group, mode;
|
||||||
gboolean is_press;
|
gboolean is_press;
|
||||||
|
GSettings *settings;
|
||||||
|
gchar *accel;
|
||||||
|
|
||||||
g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE);
|
g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE);
|
||||||
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
||||||
event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE);
|
event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE);
|
||||||
|
|
||||||
pad = clutter_event_get_source_device ((ClutterEvent *) event);
|
|
||||||
button = event->button;
|
button = event->button;
|
||||||
mode = event->mode;
|
mode = event->mode;
|
||||||
group = clutter_input_device_get_mode_switch_button_group (pad, button);
|
group = clutter_input_device_get_mode_switch_button_group (pad, button);
|
||||||
@ -1865,8 +1917,12 @@ meta_input_settings_handle_pad_button (MetaInputSettings *input_settin
|
|||||||
meta_display_request_pad_osd (meta_get_display (), pad, FALSE);
|
meta_display_request_pad_osd (meta_get_display (), pad, FALSE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING:
|
case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING:
|
||||||
meta_input_settings_emulate_keybinding (input_settings, pad,
|
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
|
||||||
button, is_press);
|
button, META_PAD_DIRECTION_NONE, -1);
|
||||||
|
accel = g_settings_get_string (settings, "keybinding");
|
||||||
|
meta_input_settings_emulate_keybinding (input_settings, accel, is_press);
|
||||||
|
g_object_unref (settings);
|
||||||
|
g_free (accel);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
|
case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
|
||||||
default:
|
default:
|
||||||
@ -1874,6 +1930,125 @@ meta_input_settings_handle_pad_button (MetaInputSettings *input_settin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_input_settings_handle_pad_action (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
MetaPadActionType action,
|
||||||
|
guint number,
|
||||||
|
MetaPadDirection direction,
|
||||||
|
guint mode)
|
||||||
|
{
|
||||||
|
GSettings *settings;
|
||||||
|
gboolean handled = FALSE;
|
||||||
|
gchar *accel;
|
||||||
|
|
||||||
|
settings = lookup_pad_action_settings (pad, action, number, direction, mode);
|
||||||
|
accel = g_settings_get_string (settings, "keybinding");
|
||||||
|
|
||||||
|
if (accel && *accel)
|
||||||
|
{
|
||||||
|
meta_input_settings_emulate_keybinding (input_settings, accel, TRUE);
|
||||||
|
meta_input_settings_emulate_keybinding (input_settings, accel, FALSE);
|
||||||
|
handled = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (settings);
|
||||||
|
g_free (accel);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_input_settings_get_pad_action_direction (MetaInputSettings *input_settings,
|
||||||
|
const ClutterEvent *event,
|
||||||
|
MetaPadDirection *direction)
|
||||||
|
{
|
||||||
|
MetaInputSettingsPrivate *priv;
|
||||||
|
ClutterInputDevice *pad = clutter_event_get_device (event);
|
||||||
|
MetaPadActionType pad_action;
|
||||||
|
gboolean has_direction = FALSE;
|
||||||
|
MetaPadDirection inc_dir, dec_dir;
|
||||||
|
guint number;
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
priv = meta_input_settings_get_instance_private (input_settings);
|
||||||
|
*direction = META_PAD_DIRECTION_NONE;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_PAD_RING:
|
||||||
|
pad_action = META_PAD_ACTION_RING;
|
||||||
|
number = event->pad_ring.ring_number;
|
||||||
|
value = event->pad_ring.angle;
|
||||||
|
inc_dir = META_PAD_DIRECTION_CW;
|
||||||
|
dec_dir = META_PAD_DIRECTION_CCW;
|
||||||
|
break;
|
||||||
|
case CLUTTER_PAD_STRIP:
|
||||||
|
pad_action = META_PAD_ACTION_STRIP;
|
||||||
|
number = event->pad_strip.strip_number;
|
||||||
|
value = event->pad_strip.value;
|
||||||
|
inc_dir = META_PAD_DIRECTION_DOWN;
|
||||||
|
dec_dir = META_PAD_DIRECTION_UP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->last_pad_action_info.pad == pad &&
|
||||||
|
priv->last_pad_action_info.action == pad_action &&
|
||||||
|
priv->last_pad_action_info.number == number &&
|
||||||
|
value >= 0 && priv->last_pad_action_info.value >= 0)
|
||||||
|
{
|
||||||
|
*direction = (value - priv->last_pad_action_info.value) > 0 ?
|
||||||
|
inc_dir : dec_dir;
|
||||||
|
has_direction = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->last_pad_action_info.pad = pad;
|
||||||
|
priv->last_pad_action_info.action = pad_action;
|
||||||
|
priv->last_pad_action_info.number = number;
|
||||||
|
priv->last_pad_action_info.value = value;
|
||||||
|
return has_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_input_settings_handle_pad_event (MetaInputSettings *input_settings,
|
||||||
|
const ClutterEvent *event)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *pad;
|
||||||
|
MetaPadDirection direction = META_PAD_DIRECTION_NONE;
|
||||||
|
|
||||||
|
pad = clutter_event_get_source_device ((ClutterEvent *) event);
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_PAD_BUTTON_PRESS:
|
||||||
|
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||||
|
return meta_input_settings_handle_pad_button (input_settings, pad,
|
||||||
|
&event->pad_button);
|
||||||
|
case CLUTTER_PAD_RING:
|
||||||
|
if (!meta_input_settings_get_pad_action_direction (input_settings,
|
||||||
|
event, &direction))
|
||||||
|
return FALSE;
|
||||||
|
return meta_input_settings_handle_pad_action (input_settings, pad,
|
||||||
|
META_PAD_ACTION_RING,
|
||||||
|
event->pad_ring.ring_number,
|
||||||
|
direction,
|
||||||
|
event->pad_ring.mode);
|
||||||
|
case CLUTTER_PAD_STRIP:
|
||||||
|
if (!meta_input_settings_get_pad_action_direction (input_settings,
|
||||||
|
event, &direction))
|
||||||
|
return FALSE;
|
||||||
|
return meta_input_settings_handle_pad_action (input_settings, pad,
|
||||||
|
META_PAD_ACTION_STRIP,
|
||||||
|
event->pad_strip.strip_number,
|
||||||
|
direction,
|
||||||
|
event->pad_strip.mode);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_settings,
|
meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_settings,
|
||||||
ClutterInputDevice *pad,
|
ClutterInputDevice *pad,
|
||||||
@ -1906,7 +2081,8 @@ meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_setti
|
|||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
gchar *accel;
|
gchar *accel;
|
||||||
|
|
||||||
settings = lookup_pad_button_settings (pad, button);
|
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
|
||||||
|
button, META_PAD_DIRECTION_NONE, -1);
|
||||||
accel = g_settings_get_string (settings, "keybinding");
|
accel = g_settings_get_string (settings, "keybinding");
|
||||||
g_object_unref (settings);
|
g_object_unref (settings);
|
||||||
|
|
||||||
|
@ -220,10 +220,12 @@ meta_display_handle_event (MetaDisplay *display,
|
|||||||
|
|
||||||
if (!display->current_pad_osd &&
|
if (!display->current_pad_osd &&
|
||||||
(event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
(event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
||||||
event->type == CLUTTER_PAD_BUTTON_RELEASE))
|
event->type == CLUTTER_PAD_BUTTON_RELEASE ||
|
||||||
|
event->type == CLUTTER_PAD_RING ||
|
||||||
|
event->type == CLUTTER_PAD_STRIP))
|
||||||
{
|
{
|
||||||
if (meta_input_settings_handle_pad_button (meta_backend_get_input_settings (backend),
|
if (meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
|
||||||
&event->pad_button))
|
event))
|
||||||
{
|
{
|
||||||
bypass_wayland = bypass_clutter = TRUE;
|
bypass_wayland = bypass_clutter = TRUE;
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
Reference in New Issue
Block a user