Compare commits

...

22 Commits

Author SHA1 Message Date
Florian Müllner
4c3e166469 Bump version to 3.24.4
Update NEWS.
2017-07-19 20:49:41 +02:00
Jonas Ådahl
9d0b49439e monitor-unit-tests: Check tiled monitors with non-origin main output
Test that a tiled monitor with tile (0, 0) as the non-main output,
where main output is defined as the output that is active as long as
the monitor is active.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-07-19 17:08:23 +08:00
Jonas Ådahl
eb6f74987e monitor-manager: Let the MetaMonitor derive the whole layout
Instead of letting MetaMonitor derive the logical monitor size, then
using the main monitor for the position, just let MetaMonitor derive
the whole layout including the position. This means it can deal with
tiled monitors better, for example when the main output (the output
always active when the monitor is active) is not the origin output (the
output with tile position (0, 0)).

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-07-19 17:08:23 +08:00
Jason Gerecke
726296f022 wayland: Provide basic tablet wheel event support
Adds basic support for the "wheel" event from the Wayland tablet protocol.
Ideally we would accumulate the angle and report a wheel event with an
appropriate value for "clicks". We can get away with a much cruder method
for the time being, however, since no Wacom tablet puck actually provides
a smooth scrollwheel. Checking whether the angle in CLUTTER_INPUT_AXIS_WHEEL
exceeds a nominally-small threshold is sufficient to determine that the
wheel has advanced by at least one physical click.

https://bugzilla.gnome.org/show_bug.cgi?id=783716
2017-07-17 21:23:30 +02:00
Carlos Garnacho
901490545c backends: Extend pad action label checks to rings/strips
This way the pad OSD can obtain the keycombos that are mapped to these
for labeling purposes.

https://bugzilla.gnome.org/show_bug.cgi?id=782033
2017-07-17 19:43:48 +02:00
Carlos Garnacho
8478d8a002 clutter/x11: Emit CLUTTER_PAD_RING/STRIP events on X11
These events will be useful on gnome-shell UI, so translate the
4-5 button events with exotic axes to those. Also use the
XI_Motion event received when first touching those to reset
the ring/strip state, so we don't receive spurious direction
changes in the upper layers.

https://bugzilla.gnome.org/show_bug.cgi?id=782033
2017-07-17 19:43:48 +02:00
Carlos Garnacho
81dd9aa1da clutter: Add clutter_event_get_pad_event_details()
This function extracts pad event information, and more importantly
exposes it for gobject introspection.

https://bugzilla.gnome.org/show_bug.cgi?id=782033
2017-07-17 19:43:48 +02:00
Jonas Ådahl
5d7b94abb8 wayland/window: Update toplevel main monitor before non-toplevel
When updating the main monitor, make sure to update the toplevel main
monitor before trying to use that as the main monitor for non-toplevel
windows (such as popups). Without this, when the main monitor is
updated as a side effect to monitors being changed (for example due to
a hot plug event, or coming back from being suspended) the
main monitor pointer may, after 'monitors-changed' has completed, point to
freed memory resulting in undefined behaviour.

https://bugzilla.gnome.org/show_bug.cgi?id=784867
2017-07-17 09:58:01 +08:00
Carlos Garnacho
cdb5ead795 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
2017-07-14 22:31:34 +02:00
Carlos Garnacho
0159efe34b backends: Set error when opening /sys file fails
The caller in clutter really expects an error if fd==-1, so make
sure we set one here. Otherwise we get a nice crash in addition to
the failure to open the /sys file. Also, retry on EINTR.

https://bugzilla.gnome.org/show_bug.cgi?id=784881
2017-07-14 12:34:29 +02:00
Jason Gerecke
9f68507f0c wayland: Store and retrieve implicit grab information for tablet tools
Window moving and resizing depends on the `meta_wayland_seat_get_grab_info`
function succeeding. At the moment, tablet tools do not generate implicit
grabs like the pointer and touch. This commit adds the necessary elements
to track implicit grabs and retrieve their information.

https://bugzilla.gnome.org/show_bug.cgi?id=777333
2017-07-13 19:12:35 +02:00
Carlos Garnacho
e52408d259 backends: Fix dangling callback not being disconnected
This fixes possible crashes if configuration is changed on a device that
was added and then removed.

https://bugzilla.gnome.org/show_bug.cgi?id=784881
2017-07-13 18:53:40 +02:00
Carlos Garnacho
45014a27a4 clutter/x11: Set master device on pad button events
These should be set one, but just set the master to be the slave
pad device. We are passively grabbing the pad device, so this is
consistent with active grabs on slave devices. Besides, pads are
paired to the VCP, which is not really truthful.

Fixes inoffensive warnings when trying to check whether motion
throttling applies for these events.

https://bugzilla.gnome.org/show_bug.cgi?id=784881
2017-07-13 18:53:40 +02:00
Carlos Garnacho
d4e02527d3 backend: Set mapping-mode on X11 pen/eraser devices
And use it in the generic code for the checks about whether mapping to
an specific display applies or not.

https://bugzilla.gnome.org/show_bug.cgi?id=784402
2017-07-12 23:45:31 +02:00
Carlos Garnacho
7f594bbe46 clutter: Extend mapping-mode to pen/eraser devices
This just used to apply to CLUTTER_TABLET_DEVICE on wayland, allow using
it on pen/eraser devices (as X11 sees tablets) for consistency.

https://bugzilla.gnome.org/show_bug.cgi?id=784402
2017-07-12 23:45:31 +02:00
Jonas Ådahl
e66091d8aa window: Don't crash when moving across non-adjecent logical monitors
When moving a window between two non-adjecent logical monitors, don't
try to tile a window when the window position is outside of any logical
monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=783630
2017-07-12 12:34:28 +08:00
Jordi Mas
d538016ce7 Update Catalan translation 2017-07-10 02:06:59 +02:00
Florian Müllner
6d34b2e7dd screen: Remove stray assert
When the number of (static) workspaces decreases, we relocate windows
from extra workspaces before removing them. As removing a non-empty
workspace is not allowed, we assert that it doesn't contain any windows
before removing it.

However that assert is

 - pointless, because meta_workspace_remove() already asserts that
   the workspace is empty

 - wrong, because even empty workspaces contain windows that are set
   to show on all workspaces

Simply drop the assert to avoid a crash when trying to remove a workspace
while on-all-workspaces windows are present.

https://bugzilla.gnome.org/show_bug.cgi?id=784223
2017-07-05 16:53:26 +02:00
Carlos Garnacho
f0b758b891 backends: Apply tablet settings on all tablet device types during startup
This skipped the device types that are in use on X11.

https://bugzilla.gnome.org/show_bug.cgi?id=782027
2017-07-03 14:07:21 +02:00
Carlos Garnacho
a150225a59 wayland: Base tablet tool coordinates on the current event
Instead of the last device position. This was copied a little bit too
straight from MetaWaylandPointer.

https://bugzilla.gnome.org/show_bug.cgi?id=783535
2017-07-03 14:07:21 +02:00
Carlos Garnacho
2df1bd3dda clutter: Do not throttle motion events on tablet tools
Events from tablets must not be filtered out, as the event coalescing
results in precision loss.

https://bugzilla.gnome.org/show_bug.cgi?id=783535
2017-07-03 14:07:20 +02:00
Jason Gerecke
c02638e614 backends/x11: Account for non-zero device origin when setting tablet area
Wacom's display tablets typically do not have (0,0) coincident with the top
left corner of the screen. This "outbound" area must be taken into account
when setting the area or else an unexpected offset of the pointer will
occur.

https://bugzilla.gnome.org/show_bug.cgi?id=784009
2017-07-03 14:07:20 +02:00
28 changed files with 1106 additions and 257 deletions

19
NEWS
View File

@@ -1,3 +1,22 @@
3.24.4
======
* Fix wacom cursor offset on wayland [Jason; #784009]
* Do not throttle motion events on tablet tools [Carlos; #783535]
* Handle left-handed mode on pen/eraser devices [Carlos; #782027]
* Fix crash when decreasing number of workspaces [Florian; #784223]
* Fix crash when moving across on-adjacent monitors [Jonas; #783630]
* Fix window moving/resizing via tablet tools [Jason; #777333]
* Improve stability of tablet plugs/unplugs [Carlos; #784881]
* Implement tablet rings/strips configuration [Carlos; #782033]
* Support tablet wheel events on wayland [Jason; #783716]
* Misc. bug fixes [Carlos, Jonas; #784402, #784867, #781723]
Contributors:
Jonas Ådahl, Carlos Garnacho, Jason Gerecke, Florian Müllner
Translations:
Jordi Mas [ca]
3.24.3
======
* Fix handling of tiled monitors [Jonas; #781723]

View File

@@ -2179,3 +2179,61 @@ clutter_event_get_mode_group (const ClutterEvent *event)
return 0;
}
}
/**
* clutter_event_get_pad_event_details:
* @event: a pad event
* @number: (out) (optional): ring/strip/button number
* @mode: (out) (optional): pad mode as per the event
* @value: (out) (optional): event axis value
*
* Returns the details of a pad event.
*
* Returns: #TRUE if event details could be obtained
**/
gboolean
clutter_event_get_pad_event_details (const ClutterEvent *event,
guint *number,
guint *mode,
gdouble *value)
{
guint n, m;
gdouble v;
g_return_val_if_fail (event != NULL, FALSE);
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
event->type == CLUTTER_PAD_BUTTON_RELEASE ||
event->type == CLUTTER_PAD_RING ||
event->type == CLUTTER_PAD_STRIP, FALSE);
switch (event->type)
{
case CLUTTER_PAD_BUTTON_PRESS:
case CLUTTER_PAD_BUTTON_RELEASE:
n = event->pad_button.button;
m = event->pad_button.mode;
v = 0.0;
break;
case CLUTTER_PAD_RING:
n = event->pad_ring.ring_number;
m = event->pad_ring.mode;
v = event->pad_ring.angle;
break;
case CLUTTER_PAD_STRIP:
n = event->pad_strip.strip_number;
m = event->pad_strip.mode;
v = event->pad_strip.value;
break;
default:
return FALSE;
}
if (number)
*number = n;
if (mode)
*mode = m;
if (value)
*value = v;
return TRUE;
}

View File

@@ -778,6 +778,12 @@ ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const Clut
CLUTTER_AVAILABLE_IN_ALL
guint clutter_event_get_mode_group (const ClutterEvent *event);
CLUTTER_AVAILABLE_IN_MUTTER
gboolean clutter_event_get_pad_event_details (const ClutterEvent *event,
guint *number,
guint *mode,
gdouble *value);
G_END_DECLS

View File

@@ -2243,10 +2243,15 @@ clutter_input_device_get_device_node (ClutterInputDevice *device)
ClutterInputDeviceMapping
clutter_input_device_get_mapping_mode (ClutterInputDevice *device)
{
ClutterInputDeviceType device_type;
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
CLUTTER_TABLET_DEVICE,
device_type = clutter_input_device_get_device_type (device);
g_return_val_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE ||
device_type == CLUTTER_ERASER_DEVICE,
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
return device->mapping_mode;
@@ -2256,9 +2261,14 @@ void
clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
ClutterInputDeviceMapping mapping)
{
ClutterInputDeviceType device_type;
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
g_return_if_fail (clutter_input_device_get_device_type (device) ==
CLUTTER_TABLET_DEVICE);
device_type = clutter_input_device_get_device_type (device);
g_return_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE ||
device_type == CLUTTER_ERASER_DEVICE);
if (device->mapping_mode == mapping)
return;

View File

@@ -971,6 +971,7 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
ClutterEvent *next_event;
ClutterInputDevice *device;
ClutterInputDevice *next_device;
ClutterInputDeviceType device_type;
gboolean check_device = FALSE;
event = l->data;
@@ -986,8 +987,16 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
if (device != NULL && next_device != NULL)
check_device = TRUE;
/* Skip consecutive motion events coming from the same device */
if (priv->throttle_motion_events && next_event != NULL)
device_type = clutter_input_device_get_device_type (device);
/* Skip consecutive motion events coming from the same device,
* except those of tablet tools, since users of these events
* want no precision loss.
*/
if (priv->throttle_motion_events && next_event != NULL &&
device_type != CLUTTER_TABLET_DEVICE &&
device_type != CLUTTER_PEN_DEVICE &&
device_type != CLUTTER_ERASER_DEVICE)
{
if (event->type == CLUTTER_MOTION &&
(next_event->type == CLUTTER_MOTION ||

View File

@@ -163,6 +163,9 @@ clutter_input_device_evdev_update_from_tool (ClutterInputDevice *device,
if (libinput_tablet_tool_has_slider (evdev_tool->tool))
_clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_SLIDER, -1, 1, 0);
if (libinput_tablet_tool_has_wheel (evdev_tool->tool))
_clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_WHEEL, -180, 180, 0);
g_object_thaw_notify (G_OBJECT (device));
}

View File

@@ -66,6 +66,14 @@ static const char *clutter_input_axis_atom_names[] = {
#define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names)
enum {
PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */
PAD_AXIS_STRIP1 = PAD_AXIS_FIRST,
PAD_AXIS_STRIP2,
PAD_AXIS_RING1,
PAD_AXIS_RING2,
};
static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, };
static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
@@ -359,6 +367,36 @@ get_device_node_path (ClutterBackendX11 *backend_x11,
return node_path;
}
static void
get_pad_features (XIDeviceInfo *info,
guint *n_rings,
guint *n_strips)
{
gint i, rings = 0, strips = 0;
for (i = PAD_AXIS_FIRST; i < info->num_classes; i++)
{
XIValuatorClassInfo *valuator = (XIValuatorClassInfo*) info->classes[i];
int axis = valuator->number;
if (valuator->type != XIValuatorClass)
continue;
if (valuator->max <= 1)
continue;
/* Ring/strip axes are fixed in pad devices as handled by the
* wacom driver. Match those to detect pad features.
*/
if (axis == PAD_AXIS_STRIP1 || axis == PAD_AXIS_STRIP2)
strips++;
else if (axis == PAD_AXIS_RING1 || axis == PAD_AXIS_RING2)
rings++;
}
*n_rings = rings;
*n_strips = strips;
}
static ClutterInputDevice *
create_device (ClutterDeviceManagerXI2 *manager_xi2,
ClutterBackendX11 *backend_x11,
@@ -368,7 +406,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
ClutterInputDevice *retval;
ClutterInputMode mode;
gboolean is_enabled;
guint num_touches = 0;
guint num_touches = 0, num_rings = 0, num_strips = 0;
gchar *vendor_id = NULL, *product_id = NULL, *node_path = NULL;
if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard)
@@ -436,6 +474,12 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
node_path = get_device_node_path (backend_x11, info);
}
if (source == CLUTTER_PAD_DEVICE)
{
is_enabled = TRUE;
get_pad_features (info, &num_rings, &num_strips);
}
retval = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_XI2,
"name", info->name,
"id", info->deviceid,
@@ -448,6 +492,8 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
"vendor-id", vendor_id,
"product-id", product_id,
"device-node", node_path,
"n-rings", num_rings,
"n-strips", num_strips,
NULL);
translate_device_classes (backend_x11->xdpy, retval,
@@ -847,6 +893,54 @@ translate_axes (ClutterInputDevice *device,
return retval;
}
static gboolean
translate_pad_axis (ClutterInputDevice *device,
XIValuatorState *valuators,
ClutterEventType *evtype,
guint *number,
gdouble *value)
{
double *values;
gint i;
values = valuators->values;
for (i = PAD_AXIS_FIRST; i < valuators->mask_len * 8; i++)
{
gdouble val;
guint axis_number = 0;
if (!XIMaskIsSet (valuators->mask, i))
continue;
val = *values++;
if (val <= 0)
continue;
_clutter_input_device_translate_axis (device, i, val, value);
if (i == PAD_AXIS_RING1 || i == PAD_AXIS_RING2)
{
*evtype = CLUTTER_PAD_RING;
(*value) *= 360.0;
}
else if (i == PAD_AXIS_STRIP1 || i == PAD_AXIS_STRIP2)
{
*evtype = CLUTTER_PAD_STRIP;
}
else
continue;
if (i == PAD_AXIS_STRIP2 || i == PAD_AXIS_RING2)
axis_number++;
*number = axis_number;
return TRUE;
}
return FALSE;
}
static void
translate_coords (ClutterStageX11 *stage_x11,
gdouble event_x,
@@ -1025,6 +1119,54 @@ handle_property_event (ClutterDeviceManagerXI2 *manager_xi2,
}
}
static gboolean
translate_pad_event (ClutterEvent *event,
XIDeviceEvent *xev,
ClutterInputDevice *device)
{
gdouble value;
guint number;
if (!translate_pad_axis (device, &xev->valuators,
&event->any.type,
&number, &value))
return FALSE;
/* When touching a ring/strip a first XI_Motion event
* is generated. Use it to reset the pad state, so
* later events actually have a directionality.
*/
if (xev->evtype == XI_Motion)
value = -1;
if (event->any.type == CLUTTER_PAD_RING)
{
event->pad_ring.ring_number = number;
event->pad_ring.angle = value;
}
else
{
event->pad_strip.strip_number = number;
event->pad_strip.value = value;
}
event->any.time = xev->time;
clutter_event_set_device (event, device);
clutter_event_set_source_device (event, device);
CLUTTER_NOTE (EVENT,
"%s: win:0x%x, device:%d '%s', time:%d "
"(value:%f)",
event->any.type == CLUTTER_PAD_RING
? "pad ring "
: "pad strip",
(unsigned int) stage_x11->xwin,
device->id,
device->device_name,
event->any.time, value);
return TRUE;
}
static ClutterTranslateReturn
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
gpointer native,
@@ -1206,15 +1348,23 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
XIAsyncDevice,
xev->time);
/* Ignore 4-7 buttons */
if (xev->detail >= 4 && xev->detail <= 7)
return CLUTTER_TRANSLATE_REMOVE;
event->any.stage = stage;
event->pad_button.type =
if (xev->detail >= 4 && xev->detail <= 7)
{
retval = CLUTTER_TRANSLATE_REMOVE;
if (xi_event->evtype == XI_ButtonPress &&
translate_pad_event (event, xev, source_device))
retval = CLUTTER_TRANSLATE_QUEUE;
break;
}
event->any.type =
(xi_event->evtype == XI_ButtonPress) ? CLUTTER_PAD_BUTTON_PRESS
: CLUTTER_PAD_BUTTON_RELEASE;
event->pad_button.time = xev->time;
event->pad_button.stage = stage;
event->any.time = xev->time;
/* The 4-7 button range is taken as non-existent on pad devices,
* let the buttons above that take over this range.
@@ -1224,6 +1374,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
/* Pad buttons are 0-indexed */
event->pad_button.button = xev->detail - 1;
clutter_event_set_device (event, device);
clutter_event_set_source_device (event, source_device);
CLUTTER_NOTE (EVENT,
@@ -1380,6 +1531,15 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
device = g_hash_table_lookup (manager_xi2->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
{
event->any.stage = stage;
if (translate_pad_event (event, xev, source_device))
retval = CLUTTER_TRANSLATE_QUEUE;
break;
}
/* Set the stage for core events coming out of nowhere (see bug #684509) */
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER &&
clutter_input_device_get_pointer_stage (device) == NULL &&

View File

@@ -2,7 +2,7 @@ AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [24])
m4_define([mutter_micro_version], [3])
m4_define([mutter_micro_version], [4])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])

126
po/ca.po
View File

@@ -13,16 +13,16 @@ msgstr ""
"Project-Id-Version: metacity 2.24\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-04-28 15:40+0000\n"
"PO-Revision-Date: 2016-03-13 14:45+0100\n"
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
"POT-Creation-Date: 2017-07-07 04:21+0000\n"
"PO-Revision-Date: 2017-07-10 02:05+0200\n"
"Last-Translator: Jordi Mas <jmas@softcatala.org>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bits\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Gtranslator 2.91.6\n"
"X-Generator: Poedit 2.0.1\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@@ -105,10 +105,8 @@ msgid "Switch to previous window of an application"
msgstr "Canvia a la finestra anterior d'una aplicació"
#: data/50-mutter-navigation.xml:76
#, fuzzy
#| msgid "Switch system controls directly"
msgid "Switch system controls"
msgstr "Canvia immediatament entre els controls del sistema"
msgstr "Canvia els controls del sistema"
#: data/50-mutter-navigation.xml:81
msgid "Switch to previous system control"
@@ -279,12 +277,6 @@ msgstr ""
"finestres"
#: data/org.gnome.mutter.gschema.xml.in:8
#, fuzzy
#| msgid ""
#| "This key will initiate the \"overlay\", which is a combination window "
#| "overview and application launching system. The default is intended to be "
#| "the \"Windows key\" on PC hardware. It's expected that this binding "
#| "either the default or set to the empty string."
msgid ""
"This key will initiate the “overlay”, which is a combination window overview "
"and application launching system. The default is intended to be the “Windows "
@@ -333,11 +325,6 @@ msgid "Workspaces are managed dynamically"
msgstr "Els espais de treball es gestionen dinàmicament"
#: data/org.gnome.mutter.gschema.xml.in:41
#, fuzzy
#| msgid ""
#| "Determines whether workspaces are managed dynamically or whether there's "
#| "a static number of workspaces (determined by the num-workspaces key in "
#| "org.gnome.desktop.wm.preferences)."
msgid ""
"Determines whether workspaces are managed dynamically or whether theres a "
"static number of workspaces (determined by the num-workspaces key in org."
@@ -376,11 +363,6 @@ msgid "Delay focus changes until the pointer stops moving"
msgstr "Retarda el canvi del focus fins que s'aturi el punter"
#: data/org.gnome.mutter.gschema.xml.in:69
#, fuzzy
#| msgid ""
#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
#| "the focus will not be changed immediately when entering a window, but "
#| "only after the pointer stops moving."
msgid ""
"If set to true, and the focus mode is either “sloppy” or “mouse” then the "
"focus will not be changed immediately when entering a window, but only after "
@@ -395,10 +377,6 @@ msgid "Draggable border width"
msgstr "Amplada del contorn arrossegable"
#: data/org.gnome.mutter.gschema.xml.in:80
#, fuzzy
#| msgid ""
#| "The amount of total draggable borders. If the theme's visible borders are "
#| "not enough, invisible borders will be added to meet this value."
msgid ""
"The amount of total draggable borders. If the themes visible borders are "
"not enough, invisible borders will be added to meet this value."
@@ -433,11 +411,31 @@ msgstr ""
"Si és «true» (cert), les finestres noves seran posicionades al centre de la "
"pantalla activa del monitor."
#: data/org.gnome.mutter.gschema.xml.in:120
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Habilita les funcionalitats experimentals"
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “monitor-config-manager” — use the new "
"monitor configuration system, aimed to replace the old one. This enables a "
"higher level configuration API to be used by configuration applications, as "
"well as the ability to configure per logical monitor scale. • “scale-monitor-"
"framebuffer” — makes mutter default to layout logical monitors in a logical "
"pixel coordinate space, while scaling monitor framebuffers instead of window "
"content, to manage HiDPI monitors. Does not require a restart. Also enabling "
"“monitor-config-manager” is required for this feature to be enabled."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:151
msgid "Select window from tab popup"
msgstr "Selecció de finestra entre les emergents d'una pestanya"
#: data/org.gnome.mutter.gschema.xml.in:125
#: data/org.gnome.mutter.gschema.xml.in:156
msgid "Cancel tab popup"
msgstr "Cancel·lació de les finestres emergents a les pestanyes"
@@ -492,7 +490,7 @@ msgstr "Canvia al terminal virtual 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1848
#: src/backends/meta-input-settings.c:1871
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Mode de commutació (grup %d)"
@@ -500,37 +498,37 @@ msgstr "Mode de commutació (grup %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1870
#: src/backends/meta-input-settings.c:1893
msgid "Switch monitor"
msgstr "Commuta el monitor"
#: src/backends/meta-input-settings.c:1872
#: src/backends/meta-input-settings.c:1895
msgid "Show on-screen help"
msgstr "Mostra l'ajuda en pantalla"
#: src/backends/meta-monitor-manager.c:630
#: src/backends/meta-monitor-manager.c:879
msgid "Built-in display"
msgstr "Pantalla integrada"
#: src/backends/meta-monitor-manager.c:653
#: src/backends/meta-monitor-manager.c:902
msgid "Unknown"
msgstr "Desconeguda"
#: src/backends/meta-monitor-manager.c:655
#: src/backends/meta-monitor-manager.c:904
msgid "Unknown Display"
msgstr "Pantalla desconeguda"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:663
#: src/backends/meta-monitor-manager.c:912
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:474
#: src/compositor/compositor.c:476
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@@ -542,32 +540,6 @@ msgstr ""
msgid "Bell event"
msgstr "Esdeveniment de campana"
#. Translators: %s is a window title
#: src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "«%s» no està responent."
#: src/core/delete.c:129
msgid "Application is not responding."
msgstr "L'aplicació no està responent."
#: src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida "
"completa."
#: src/core/delete.c:141
msgid "_Force Quit"
msgstr "_Força'n la sortida"
#: src/core/delete.c:141
msgid "_Wait"
msgstr "_Espera"
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
@@ -615,6 +587,32 @@ msgstr "Funciona com a compositor imbricat"
msgid "Run as a full display server, rather than nested"
msgstr "Funciona com a servidor de pantalla completa, en comptes d'imbricat"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#, c-format
msgid "“%s” is not responding."
msgstr "«%s» no està responent."
#: src/core/meta-close-dialog-default.c:149
msgid "Application is not responding."
msgstr "L'aplicació no està responent."
#: src/core/meta-close-dialog-default.c:154
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida "
"completa."
#: src/core/meta-close-dialog-default.c:161
msgid "_Force Quit"
msgstr "_Força'n la sortida"
#: src/core/meta-close-dialog-default.c:161
msgid "_Wait"
msgstr "_Espera"
#: src/core/mutter.c:39
#, c-format
msgid ""

View File

@@ -140,11 +140,12 @@ gboolean meta_input_settings_is_pad_button_grabbed (MetaIn
ClutterInputDevice *pad,
guint button);
gboolean meta_input_settings_handle_pad_button (MetaInputSettings *input_settings,
const ClutterPadButtonEvent *event);
gchar * meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
guint button);
gboolean meta_input_settings_handle_pad_event (MetaInputSettings *input_settings,
const ClutterEvent *event);
gchar * meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
MetaPadActionType action,
guint number);
#ifdef HAVE_LIBWACOM
WacomDevice * meta_input_settings_get_tablet_wacom_device (MetaInputSettings *settings,

View File

@@ -53,9 +53,11 @@ struct _DeviceMappingInfo
MetaInputSettings *input_settings;
ClutterInputDevice *device;
GSettings *settings;
guint changed_id;
#ifdef HAVE_LIBWACOM
WacomDevice *wacom_device;
#endif
guint *group_modes;
};
struct _MetaInputSettingsPrivate
@@ -79,6 +81,14 @@ struct _MetaInputSettingsPrivate
#endif
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,
@@ -91,6 +101,14 @@ typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings,
ClutterInputDevice *device,
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)
static GSList *
@@ -863,7 +881,7 @@ update_device_display (MetaInputSettings *input_settings,
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
/* If mapping is relative, the device can move on all displays */
if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE ||
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE ||
clutter_input_device_get_mapping_mode (device) ==
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE)
logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
@@ -1075,10 +1093,15 @@ static void
apply_mappable_device_settings (MetaInputSettings *input_settings,
DeviceMappingInfo *info)
{
update_device_display (input_settings, info->settings, info->device);
ClutterInputDeviceType device_type;
if (clutter_input_device_get_device_type (info->device) == CLUTTER_TABLET_DEVICE ||
clutter_input_device_get_device_type (info->device) == CLUTTER_PAD_DEVICE)
update_device_display (input_settings, info->settings, info->device);
device_type = clutter_input_device_get_device_type (info->device);
if (device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE ||
device_type == CLUTTER_ERASER_DEVICE ||
device_type == CLUTTER_PAD_DEVICE)
{
update_tablet_mapping (input_settings, info->settings, info->device);
update_tablet_area (input_settings, info->settings, info->device);
@@ -1161,20 +1184,58 @@ lookup_tool_settings (ClutterInputDeviceTool *tool,
}
static GSettings *
lookup_pad_button_settings (ClutterInputDevice *device,
guint button)
lookup_pad_action_settings (ClutterInputDevice *device,
MetaPadActionType action,
guint number,
MetaPadDirection direction,
gint mode)
{
const gchar *vendor, *product;
const gchar *vendor, *product, *action_type, *detail_type = NULL;
GSettings *settings;
gchar *path;
GString *path;
gchar action_label;
vendor = clutter_input_device_get_vendor_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",
path);
g_free (path);
path->str);
g_string_free (path, TRUE);
return settings;
}
@@ -1203,7 +1264,9 @@ device_mapping_info_free (DeviceMappingInfo *info)
if (info->wacom_device)
libwacom_destroy (info->wacom_device);
#endif
g_signal_handler_disconnect (info->settings, info->changed_id);
g_object_unref (info->settings);
g_free (info->group_modes);
g_slice_free (DeviceMappingInfo, info);
}
@@ -1247,8 +1310,15 @@ check_add_mappable_device (MetaInputSettings *input_settings,
}
#endif
g_signal_connect (settings, "changed",
G_CALLBACK (mapped_device_changed_cb), info);
if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
{
info->group_modes =
g_new0 (guint, clutter_input_device_get_n_mode_groups (device));
}
info->changed_id = g_signal_connect (settings, "changed",
G_CALLBACK (mapped_device_changed_cb),
info);
g_hash_table_insert (priv->mappable_devices, device, info);
@@ -1604,7 +1674,8 @@ meta_input_settings_get_pad_button_action (MetaInputSettings *input_settings,
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad),
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");
g_object_unref (settings);
@@ -1753,24 +1824,20 @@ emulate_modifiers (ClutterVirtualInputDevice *device,
static void
meta_input_settings_emulate_keybinding (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
guint button,
const gchar *accel,
gboolean is_press)
{
MetaInputSettingsPrivate *priv;
ClutterKeyState state;
GSettings *settings;
guint key, mods;
gchar *accel;
if (!accel || !*accel)
return;
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 */
gtk_accelerator_parse (accel, &key, &mods);
g_free (accel);
if (!priv->virtual_pad_keyboard)
{
@@ -1807,20 +1874,21 @@ meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings,
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
}
gboolean
static gboolean
meta_input_settings_handle_pad_button (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
const ClutterPadButtonEvent *event)
{
GDesktopPadButtonAction action;
ClutterInputDevice *pad;
gint button, group, mode;
gboolean is_press;
GSettings *settings;
gchar *accel;
g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE);
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE);
pad = clutter_event_get_source_device ((ClutterEvent *) event);
button = event->button;
mode = event->mode;
group = clutter_input_device_get_mode_switch_button_group (pad, button);
@@ -1830,18 +1898,19 @@ meta_input_settings_handle_pad_button (MetaInputSettings *input_settin
{
guint n_modes = clutter_input_device_get_group_n_modes (pad, group);
const gchar *pretty_name = NULL;
#ifdef HAVE_LIBWACOM
MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
priv = meta_input_settings_get_instance_private (input_settings);
info = g_hash_table_lookup (priv->mappable_devices, pad);
#ifdef HAVE_LIBWACOM
if (info && info->wacom_device)
pretty_name = libwacom_get_name (info->wacom_device);
#endif
meta_display_notify_pad_group_switch (meta_get_display (), pad,
pretty_name, group, mode, n_modes);
info->group_modes[group] = mode;
}
action = meta_input_settings_get_pad_button_action (input_settings, pad, button);
@@ -1857,8 +1926,12 @@ meta_input_settings_handle_pad_button (MetaInputSettings *input_settin
meta_display_request_pad_osd (meta_get_display (), pad, FALSE);
return TRUE;
case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING:
meta_input_settings_emulate_keybinding (input_settings, pad,
button, is_press);
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
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;
case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
default:
@@ -1866,10 +1939,189 @@ meta_input_settings_handle_pad_button (MetaInputSettings *input_settin
}
}
gchar *
meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
guint button)
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;
}
}
static gchar *
compose_directional_action_label (GSettings *direction1,
GSettings *direction2)
{
gchar *accel1, *accel2, *str = NULL;
accel1 = g_settings_get_string (direction1, "keybinding");
accel2 = g_settings_get_string (direction2, "keybinding");
if (accel1 && *accel1 && accel2 && *accel2)
str = g_strdup_printf ("%s / %s", accel1, accel2);
g_free (accel1);
g_free (accel2);
return str;
}
static gchar *
meta_input_settings_get_ring_label (MetaInputSettings *settings,
ClutterInputDevice *pad,
guint number,
guint mode)
{
GSettings *settings1, *settings2;
gchar *label;
/* We only allow keybinding actions with those */
settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number,
META_PAD_DIRECTION_CW, mode);
settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number,
META_PAD_DIRECTION_CCW, mode);
label = compose_directional_action_label (settings1, settings2);
g_object_unref (settings1);
g_object_unref (settings2);
return label;
}
static gchar *
meta_input_settings_get_strip_label (MetaInputSettings *settings,
ClutterInputDevice *pad,
guint number,
guint mode)
{
GSettings *settings1, *settings2;
gchar *label;
/* We only allow keybinding actions with those */
settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number,
META_PAD_DIRECTION_UP, mode);
settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number,
META_PAD_DIRECTION_DOWN, mode);
label = compose_directional_action_label (settings1, settings2);
g_object_unref (settings1);
g_object_unref (settings2);
return label;
}
static gchar *
meta_input_settings_get_button_label (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
guint button)
{
GDesktopPadButtonAction action;
gint group;
@@ -1898,7 +2150,8 @@ meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_setti
GSettings *settings;
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");
g_object_unref (settings);
@@ -1916,3 +2169,55 @@ meta_input_settings_get_pad_button_action_label (MetaInputSettings *input_setti
return NULL;
}
}
static guint
get_current_pad_mode (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
MetaPadActionType action_type,
guint number)
{
MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
guint group = 0, n_groups;
priv = meta_input_settings_get_instance_private (input_settings);
info = g_hash_table_lookup (priv->mappable_devices, pad);
n_groups = clutter_input_device_get_n_mode_groups (pad);
if (!info->group_modes || n_groups == 0)
return 0;
if (action_type == META_PAD_ACTION_RING ||
action_type == META_PAD_ACTION_STRIP)
{
/* Assume features are evenly distributed in groups */
group = number % n_groups;
}
return info->group_modes[group];
}
gchar *
meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings,
ClutterInputDevice *pad,
MetaPadActionType action_type,
guint number)
{
guint mode;
switch (action_type)
{
case META_PAD_ACTION_BUTTON:
return meta_input_settings_get_button_label (input_settings, pad, number);
case META_PAD_ACTION_RING:
mode = get_current_pad_mode (input_settings, pad, action_type, number);
return meta_input_settings_get_ring_label (input_settings, pad,
number, mode);
case META_PAD_ACTION_STRIP:
mode = get_current_pad_mode (input_settings, pad, action_type, number);
return meta_input_settings_get_strip_label (input_settings, pad,
number, mode);
}
return NULL;
}

View File

@@ -147,19 +147,6 @@ meta_monitor_manager_rebuild_logical_monitors (MetaMonitorManager *manager,
primary_logical_monitor);
}
static void
derive_monitor_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
MetaOutput *main_output;
main_output = meta_monitor_get_main_output (monitor);
layout->x = main_output->crtc->rect.x;
layout->y = main_output->crtc->rect.y;
meta_monitor_derive_dimensions (monitor, &layout->width, &layout->height);
}
static void
meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manager)
{
@@ -179,7 +166,7 @@ meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manag
if (!meta_monitor_is_active (monitor))
continue;
derive_monitor_layout (monitor, &layout);
meta_monitor_derive_layout (monitor, &layout);
logical_monitor = logical_monitor_from_layout (manager, logical_monitors,
&layout);
if (logical_monitor)

View File

@@ -232,11 +232,10 @@ meta_monitor_get_current_resolution (MetaMonitor *monitor,
}
void
meta_monitor_derive_dimensions (MetaMonitor *monitor,
int *width,
int *height)
meta_monitor_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
META_MONITOR_GET_CLASS (monitor)->derive_dimensions (monitor, width, height);
META_MONITOR_GET_CLASS (monitor)->derive_layout (monitor, layout);
}
void
@@ -382,15 +381,18 @@ meta_monitor_normal_get_main_output (MetaMonitor *monitor)
}
static void
meta_monitor_normal_derive_dimensions (MetaMonitor *monitor,
int *width,
int *height)
meta_monitor_normal_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
*width = output->crtc->rect.width;
*height = output->crtc->rect.height;
*layout = (MetaRectangle) {
.x = output->crtc->rect.x,
.y = output->crtc->rect.y,
.width = output->crtc->rect.width,
.height = output->crtc->rect.height
};
}
static gboolean
@@ -421,7 +423,7 @@ meta_monitor_normal_class_init (MetaMonitorNormalClass *klass)
MetaMonitorClass *monitor_class = META_MONITOR_CLASS (klass);
monitor_class->get_main_output = meta_monitor_normal_get_main_output;
monitor_class->derive_dimensions = meta_monitor_normal_derive_dimensions;
monitor_class->derive_layout = meta_monitor_normal_derive_layout;
monitor_class->get_suggested_position = meta_monitor_normal_get_suggested_position;
}
@@ -958,9 +960,8 @@ meta_monitor_tiled_get_main_output (MetaMonitor *monitor)
}
static void
meta_monitor_tiled_derive_dimensions (MetaMonitor *monitor,
int *out_width,
int *out_height)
meta_monitor_derived_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
@@ -984,8 +985,12 @@ meta_monitor_tiled_derive_dimensions (MetaMonitor *monitor,
max_y = MAX (output->crtc->rect.y + output->crtc->rect.height, max_y);
}
*out_width = max_x - min_x;
*out_height = max_y - min_y;
*layout = (MetaRectangle) {
.x = min_x,
.y = min_y,
.width = max_x - min_x,
.height = max_y - min_y
};
}
static gboolean
@@ -1021,7 +1026,7 @@ meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass)
object_class->finalize = meta_monitor_tiled_finalize;
monitor_class->get_main_output = meta_monitor_tiled_get_main_output;
monitor_class->derive_dimensions = meta_monitor_tiled_derive_dimensions;
monitor_class->derive_layout = meta_monitor_derived_derive_layout;
monitor_class->get_suggested_position = meta_monitor_tiled_get_suggested_position;
}

View File

@@ -65,9 +65,8 @@ struct _MetaMonitorClass
GObjectClass parent_class;
MetaOutput * (* get_main_output) (MetaMonitor *monitor);
void (* derive_dimensions) (MetaMonitor *monitor,
int *width,
int *height);
void (* derive_layout) (MetaMonitor *monitor,
MetaRectangle *layout);
gboolean (* get_suggested_position) (MetaMonitor *monitor,
int *width,
int *height);
@@ -107,9 +106,8 @@ void meta_monitor_get_current_resolution (MetaMonitor *monitor,
int *width,
int *height);
void meta_monitor_derive_dimensions (MetaMonitor *monitor,
int *width,
int *height);
void meta_monitor_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout);
void meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
int *width_mm,

View File

@@ -188,9 +188,22 @@ on_evdev_device_open (const char *path,
/* Allow readonly access to sysfs */
if (g_str_has_prefix (path, "/sys/"))
{
fd = open (path, flags);
if (fd >= 0)
g_hash_table_add (self->sysfs_fds, GINT_TO_POINTER (fd));
do
{
fd = open (path, flags);
}
while (fd < 0 && errno == EINTR);
if (fd < 0)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"Could not open /sys file: %s: %m", path);
return -1;
}
g_hash_table_add (self->sysfs_fds, GINT_TO_POINTER (fd));
return fd;
}

View File

@@ -551,10 +551,21 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings,
g_warning ("Could not set tablet mapping for %s",
clutter_input_device_get_device_name (device));
}
else
{
ClutterInputDeviceMapping dev_mapping;
dev_mapping = (mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE) ?
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE :
CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE;
clutter_input_device_set_mapping_mode (device, dev_mapping);
}
}
static gboolean
device_query_area (ClutterInputDevice *device,
gint *x,
gint *y,
gint *width,
gint *height)
{
@@ -580,9 +591,15 @@ device_query_area (ClutterInputDevice *device,
if (valuator->type != XIValuatorClass)
continue;
if (valuator->label == abs_x)
*width = valuator->max - valuator->min;
{
*x = valuator->min;
*width = valuator->max - valuator->min;
}
else if (valuator->label == abs_y)
*height = valuator->max - valuator->min;
{
*y = valuator->min;
*height = valuator->max - valuator->min;
}
}
XIFreeDeviceInfo (info);
@@ -606,15 +623,15 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings,
gdouble padding_top,
gdouble padding_bottom)
{
gint32 width, height, area[4] = { 0 };
gint32 x, y, width, height, area[4] = { 0 };
if (!device_query_area (device, &width, &height))
if (!device_query_area (device, &x, &y, &width, &height))
return;
area[0] = width * padding_left;
area[1] = height * padding_top;
area[2] = width - (width * padding_right);
area[3] = height - (height * padding_bottom);
area[0] = (width * padding_left) + x;
area[1] = (height * padding_top) + y;
area[2] = width - (width * padding_right) + x;
area[3] = height - (height * padding_bottom) + y;
update_tablet_area (settings, device, area);
}
@@ -624,9 +641,9 @@ meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
MetaLogicalMonitor *logical_monitor,
gboolean keep_aspect)
{
gint32 width, height, dev_width, dev_height, area[4] = { 0 };
gint32 width, height, dev_x, dev_y, dev_width, dev_height, area[4] = { 0 };
if (!device_query_area (device, &dev_width, &dev_height))
if (!device_query_area (device, &dev_x, &dev_y, &dev_width, &dev_height))
return;
if (keep_aspect)
@@ -658,8 +675,10 @@ meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
dev_height = dev_width / aspect_ratio;
}
area[2] = dev_width;
area[3] = dev_height;
area[0] = dev_x;
area[1] = dev_y;
area[2] = dev_width + dev_x;
area[3] = dev_height + dev_y;
update_tablet_area (settings, device, area);
}

View File

@@ -3160,18 +3160,14 @@ meta_display_get_pad_action_label (MetaDisplay *display,
MetaPadActionType action_type,
guint action_number)
{
MetaInputSettings *settings;
gchar *label;
/* First, lookup the action, as imposed by settings */
if (action_type == META_PAD_ACTION_BUTTON)
{
MetaInputSettings *settings;
settings = meta_backend_get_input_settings (meta_get_backend ());
label = meta_input_settings_get_pad_button_action_label (settings, pad, action_number);
if (label)
return label;
}
settings = meta_backend_get_input_settings (meta_get_backend ());
label = meta_input_settings_get_pad_action_label (settings, pad, action_type, action_number);
if (label)
return label;
#ifdef HAVE_WAYLAND
/* Second, if this wayland, lookup the actions set by the clients */

View File

@@ -220,10 +220,12 @@ meta_display_handle_event (MetaDisplay *display,
if (!display->current_pad_osd &&
(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),
&event->pad_button))
if (meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
event))
{
bypass_wayland = bypass_clutter = TRUE;
goto out;

View File

@@ -1260,7 +1260,6 @@ update_num_workspaces (MetaScreen *screen,
{
MetaWorkspace *w = l->data;
g_assert (w->windows == NULL);
meta_workspace_remove (w);
}

View File

@@ -530,7 +530,8 @@ struct _MetaWindowClass
cairo_surface_t **icon,
cairo_surface_t **mini_icon);
uint32_t (*get_client_pid) (MetaWindow *window);
void (*update_main_monitor) (MetaWindow *window);
void (*update_main_monitor) (MetaWindow *window,
gboolean user_op);
void (*main_monitor_changed) (MetaWindow *window,
const MetaLogicalMonitor *old);
};

View File

@@ -3592,7 +3592,7 @@ meta_window_update_monitor (MetaWindow *window,
const MetaLogicalMonitor *old;
old = window->monitor;
META_WINDOW_GET_CLASS (window)->update_main_monitor (window);
META_WINDOW_GET_CLASS (window)->update_main_monitor (window, user_op);
if (old != window->monitor)
{
meta_window_on_all_workspaces_changed (window);
@@ -5581,6 +5581,60 @@ update_move_timeout (gpointer data)
return FALSE;
}
static void
update_move_maybe_tile (MetaWindow *window,
int shake_threshold,
int x,
int y)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor;
MetaRectangle work_area;
/* For side-by-side tiling we are interested in the inside vertical
* edges of the work area of the monitor where the pointer is located,
* and in the outside top edge for maximized tiling.
*
* For maximized tiling we use the outside edge instead of the
* inside edge, because we don't want to force users to maximize
* windows they are placing near the top of their screens.
*
* The "current" idea of meta_window_get_work_area_current_monitor() and
* meta_screen_get_current_monitor() is slightly different: the former
* refers to the monitor which contains the largest part of the window,
* the latter to the one where the pointer is located.
*/
logical_monitor =
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
if (!logical_monitor)
return;
meta_window_get_work_area_for_monitor (window,
logical_monitor->number,
&work_area);
/* Check if the cursor is in a position which triggers tiling
* and set tile_mode accordingly.
*/
if (meta_window_can_tile_side_by_side (window) &&
x >= logical_monitor->rect.x && x < (work_area.x + shake_threshold))
window->tile_mode = META_TILE_LEFT;
else if (meta_window_can_tile_side_by_side (window) &&
x >= work_area.x + work_area.width - shake_threshold &&
x < (logical_monitor->rect.x + logical_monitor->rect.width))
window->tile_mode = META_TILE_RIGHT;
else if (meta_window_can_tile_maximized (window) &&
y >= logical_monitor->rect.y && y <= work_area.y)
window->tile_mode = META_TILE_MAXIMIZED;
else
window->tile_mode = META_TILE_NONE;
if (window->tile_mode != META_TILE_NONE)
window->tile_monitor_number = logical_monitor->number;
}
static void
update_move (MetaWindow *window,
gboolean snap,
@@ -5636,49 +5690,7 @@ update_move (MetaWindow *window,
!META_WINDOW_MAXIMIZED (window) &&
!META_WINDOW_TILED_SIDE_BY_SIDE (window))
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
const MetaLogicalMonitor *monitor;
MetaRectangle work_area;
/* For side-by-side tiling we are interested in the inside vertical
* edges of the work area of the monitor where the pointer is located,
* and in the outside top edge for maximized tiling.
*
* For maximized tiling we use the outside edge instead of the
* inside edge, because we don't want to force users to maximize
* windows they are placing near the top of their screens.
*
* The "current" idea of meta_window_get_work_area_current_monitor() and
* meta_screen_get_current_monitor() is slightly different: the former
* refers to the monitor which contains the largest part of the window,
* the latter to the one where the pointer is located.
*/
monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager,
x, y);
meta_window_get_work_area_for_monitor (window,
monitor->number,
&work_area);
/* Check if the cursor is in a position which triggers tiling
* and set tile_mode accordingly.
*/
if (meta_window_can_tile_side_by_side (window) &&
x >= monitor->rect.x && x < (work_area.x + shake_threshold))
window->tile_mode = META_TILE_LEFT;
else if (meta_window_can_tile_side_by_side (window) &&
x >= work_area.x + work_area.width - shake_threshold &&
x < (monitor->rect.x + monitor->rect.width))
window->tile_mode = META_TILE_RIGHT;
else if (meta_window_can_tile_maximized (window) &&
y >= monitor->rect.y && y <= work_area.y)
window->tile_mode = META_TILE_MAXIMIZED;
else
window->tile_mode = META_TILE_NONE;
if (window->tile_mode != META_TILE_NONE)
window->tile_monitor_number = monitor->number;
update_move_maybe_tile (window, shake_threshold, x, y);
}
/* shake loose (unmaximize) maximized or tiled window if dragged beyond

View File

@@ -1433,6 +1433,153 @@ meta_test_monitor_tiled_non_preferred_linear_config (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_tiled_non_main_origin_linear_config (void)
{
MonitorTestCase test_case = {
.setup = {
.modes = {
{
.width = 400,
.height = 600,
.refresh_rate = 60.0
},
{
.width = 800,
.height = 600,
.refresh_rate = 30.0
},
},
.n_modes = 2,
.outputs = {
{
.crtc = -1,
.modes = { 0, 1 },
.n_modes = 2,
.preferred_mode = 0,
.possible_crtcs = { 0 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 1,
.loc_v_tile = 0,
.tile_w = 400,
.tile_h = 600
}
},
{
.crtc = -1,
.modes = { 0 },
.n_modes = 1,
.preferred_mode = 0,
.possible_crtcs = { 1 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 0,
.loc_v_tile = 0,
.tile_w = 400,
.tile_h = 600
}
}
},
.n_outputs = 2,
.crtcs = {
{
.current_mode = -1
},
{
.current_mode = -1
}
},
.n_crtcs = 2
},
.expect = {
.monitors = {
{
.outputs = { 0, 1 },
.n_outputs = 2,
.modes = {
{
.width = 800,
.height = 600,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 0,
.x = 400,
.y = 0
},
{
.output = 1,
.crtc_mode = 0,
}
}
},
{
.width = 800,
.height = 600,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 1
},
{
.output = 1,
.crtc_mode = -1,
}
}
},
},
.n_modes = 2,
.current_mode = 0,
.width_mm = 222,
.height_mm = 125,
}
},
.n_monitors = 1,
.logical_monitors = {
{
.monitors = { 0 },
.n_monitors = 1,
.layout = { .x = 0, .y = 0, .width = 800, .height = 600 },
.scale = 1
},
},
.n_logical_monitors = 1,
.primary_logical_monitor = 0,
.n_outputs = 2,
.crtcs = {
{
.current_mode = 0,
},
{
.current_mode = 0,
}
},
.n_crtcs = 2,
.n_tiled_monitors = 1,
.screen_width = 800,
.screen_height = 600,
}
};
MetaMonitorTestSetup *test_setup;
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_hidpi_linear_config (void)
{
@@ -3007,6 +3154,8 @@ init_monitor_tests (void)
meta_test_monitor_tiled_linear_config);
g_test_add_func ("/backends/monitor/tiled-non-preferred-linear-config",
meta_test_monitor_tiled_non_preferred_linear_config);
g_test_add_func ("/backends/monitor/tiled-non-main-origin-linear-config",
meta_test_monitor_tiled_non_main_origin_linear_config);
g_test_add_func ("/backends/monitor/hidpi-linear-config",
meta_test_monitor_hidpi_linear_config);
g_test_add_func ("/backends/monitor/suggested-config",

View File

@@ -411,36 +411,58 @@ meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
gfloat *x,
gfloat *y)
{
ClutterEventSequence *sequence = NULL;
gboolean can_grab_surface = FALSE;
MetaWaylandCompositor *compositor;
MetaWaylandTabletSeat *tablet_seat;
GList *tools, *l;
compositor = meta_wayland_compositor_get_default ();
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
tools = g_hash_table_get_values (tablet_seat->tools);
if (meta_wayland_seat_has_touch (seat))
sequence = meta_wayland_touch_find_grab_sequence (seat->touch,
surface,
serial);
if (sequence)
{
meta_wayland_touch_get_press_coords (seat->touch, sequence, x, y);
ClutterEventSequence *sequence;
sequence = meta_wayland_touch_find_grab_sequence (seat->touch,
surface,
serial);
if (sequence)
{
meta_wayland_touch_get_press_coords (seat->touch, sequence, x, y);
return TRUE;
}
}
else
{
if (meta_wayland_seat_has_pointer (seat) &&
(!require_pressed || seat->pointer->button_count > 0))
can_grab_surface = meta_wayland_pointer_can_grab_surface (seat->pointer,
surface,
serial);
if (can_grab_surface)
if (meta_wayland_seat_has_pointer (seat))
{
if ((!require_pressed || seat->pointer->button_count > 0) &&
meta_wayland_pointer_can_grab_surface (seat->pointer, surface, serial))
{
if (x)
*x = seat->pointer->grab_x;
if (y)
*y = seat->pointer->grab_y;
return TRUE;
}
}
return sequence || can_grab_surface;
for (l = tools; l; l = l->next)
{
MetaWaylandTabletTool *tool = l->data;
if ((!require_pressed || tool->button_count > 0) &&
meta_wayland_tablet_tool_can_grab_surface (tool, surface, serial))
{
if (x)
*x = tool->grab_x;
if (y)
*y = tool->grab_y;
return TRUE;
}
}
return FALSE;
}
gboolean

View File

@@ -31,6 +31,7 @@
#include "meta-wayland-keyboard.h"
#include "meta-wayland-touch.h"
#include "meta-wayland-data-device.h"
#include "meta-wayland-tablet-tool.h"
struct _MetaWaylandSeat
{

View File

@@ -572,9 +572,15 @@ meta_wayland_tablet_tool_account_button (MetaWaylandTabletTool *tool,
const ClutterEvent *event)
{
if (event->type == CLUTTER_BUTTON_PRESS)
tool->pressed_buttons |= 1 << (event->button.button - 1);
{
tool->pressed_buttons |= 1 << (event->button.button - 1);
tool->button_count++;
}
else if (event->type == CLUTTER_BUTTON_RELEASE)
tool->pressed_buttons &= ~(1 << (event->button.button - 1));
{
tool->pressed_buttons &= ~(1 << (event->button.button - 1));
tool->button_count--;
}
}
static void
@@ -621,17 +627,16 @@ repick_for_event (MetaWaylandTabletTool *tool,
static void
meta_wayland_tablet_tool_get_relative_coordinates (MetaWaylandTabletTool *tool,
ClutterInputDevice *device,
const ClutterEvent *event,
MetaWaylandSurface *surface,
wl_fixed_t *sx,
wl_fixed_t *sy)
{
float xf = 0.0f, yf = 0.0f;
ClutterPoint pos;
float xf, yf;
clutter_input_device_get_coords (device, NULL, &pos);
clutter_event_get_coords (event, &xf, &yf);
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
pos.x, pos.y, &xf, &yf);
xf, yf, &xf, &yf);
*sx = wl_fixed_from_double (xf) / surface->scale;
*sy = wl_fixed_from_double (yf) / surface->scale;
@@ -642,11 +647,9 @@ broadcast_motion (MetaWaylandTabletTool *tool,
const ClutterEvent *event)
{
struct wl_resource *resource;
ClutterInputDevice *device;
wl_fixed_t sx, sy;
device = clutter_event_get_source_device (event);
meta_wayland_tablet_tool_get_relative_coordinates (tool, device,
meta_wayland_tablet_tool_get_relative_coordinates (tool, event,
tool->focus_surface,
&sx, &sy);
@@ -797,6 +800,38 @@ broadcast_rotation (MetaWaylandTabletTool *tool,
}
}
static void
broadcast_wheel (MetaWaylandTabletTool *tool,
const ClutterEvent *event)
{
struct wl_resource *resource;
ClutterInputDevice *source;
gdouble angle;
gint32 clicks = 0;
source = clutter_event_get_source_device (event);
if (!clutter_input_device_get_axis_value (source, event->motion.axes,
CLUTTER_INPUT_AXIS_WHEEL,
&angle))
return;
/* FIXME: Perform proper angle-to-clicks accumulation elsewhere */
if (angle > 0.01)
clicks = 1;
else if (angle < -0.01)
clicks = -1;
else
return;
wl_resource_for_each (resource, &tool->focus_resource_list)
{
zwp_tablet_tool_v2_send_wheel (resource,
wl_fixed_from_double (angle),
clicks);
}
}
static void
broadcast_axes (MetaWaylandTabletTool *tool,
const ClutterEvent *event)
@@ -820,8 +855,8 @@ broadcast_axes (MetaWaylandTabletTool *tool,
broadcast_rotation (tool, event);
if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER))
broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_SLIDER);
/* FIXME: Missing wp_tablet_tool.wheel */
if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL))
broadcast_wheel (tool, event);
}
static void
@@ -843,6 +878,9 @@ handle_button_event (MetaWaylandTabletTool *tool,
if (!tool->focus_surface)
return;
if (event->type == CLUTTER_BUTTON_PRESS && tool->button_count == 1)
clutter_event_get_coords (event, &tool->grab_x, &tool->grab_y);
if (event->type == CLUTTER_BUTTON_PRESS && event->button.button == 1)
broadcast_down (tool, event);
else if (event->type == CLUTTER_BUTTON_RELEASE && event->button.button == 1)
@@ -921,3 +959,32 @@ meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool,
if (tool->cursor_renderer)
meta_cursor_renderer_set_position (tool->cursor_renderer, new_x, new_y);
}
static gboolean
tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
MetaWaylandSurface *surface)
{
GList *l;
if (tool->focus_surface == surface)
return TRUE;
for (l = surface->subsurfaces; l; l = l->next)
{
MetaWaylandSurface *subsurface = l->data;
if (tablet_tool_can_grab_surface (tool, subsurface))
return TRUE;
}
return FALSE;
}
gboolean
meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
MetaWaylandSurface *surface,
uint32_t serial)
{
return ((tool->down_serial == serial || tool->button_serial == serial) &&
tablet_tool_can_grab_surface (tool, surface));
}

View File

@@ -48,11 +48,14 @@ struct _MetaWaylandTabletTool
MetaWaylandSurface *current;
guint32 pressed_buttons;
guint32 button_count;
guint32 proximity_serial;
guint32 down_serial;
guint32 button_serial;
float grab_x, grab_y;
MetaWaylandTablet *current_tablet;
};
@@ -79,5 +82,8 @@ void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *t
int new_x,
int new_y);
gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
MetaWaylandSurface *surface,
uint32_t serial);
#endif /* META_WAYLAND_TABLET_TOOL_H */

View File

@@ -334,7 +334,8 @@ scale_rect_size (MetaRectangle *rect,
}
static void
meta_window_wayland_update_main_monitor (MetaWindow *window)
meta_window_wayland_update_main_monitor (MetaWindow *window,
gboolean user_op)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
@@ -353,6 +354,7 @@ meta_window_wayland_update_main_monitor (MetaWindow *window)
toplevel_window = meta_wayland_surface_get_toplevel_window (window->surface);
if (toplevel_window != window)
{
meta_window_update_monitor (toplevel_window, user_op);
window->monitor = toplevel_window->monitor;
return;
}

View File

@@ -1456,7 +1456,8 @@ meta_window_x11_update_icon (MetaWindow *window,
}
static void
meta_window_x11_update_main_monitor (MetaWindow *window)
meta_window_x11_update_main_monitor (MetaWindow *window,
gboolean user_op)
{
window->monitor = meta_window_calculate_main_logical_monitor (window);
}