After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 650603 - Handle automatic orientation switches
Handle automatic orientation switches
Status: RESOLVED FIXED
Product: gnome-settings-daemon
Classification: Core
Component: xrandr
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gnome-settings-daemon-maint
gnome-settings-daemon-maint
Depends on:
Blocks: 651792
 
 
Reported: 2011-05-19 16:04 UTC by Bastien Nocera
Modified: 2011-06-06 17:25 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
xrandr: Switch touchscreen rotation as well (12.20 KB, patch)
2011-05-31 11:27 UTC, Bastien Nocera
none Details | Review
xrandr: Switch touchscreen rotation as well (13.69 KB, patch)
2011-05-31 14:03 UTC, Bastien Nocera
none Details | Review

Description Bastien Nocera 2011-05-19 16:04:22 UTC
1. Get a device with an accelerometer
2. Make it work (the one in the WeTab uses reports X/Y/Z axis through the input layer, and in evtest), it also sends out a kevent for coarse orientation changes.
3. Make it appear as an input device in X, one that wouldn't attach underneath the core virtual devices (Peter, how do we do that?)
4. gnome-settings-daemon module listens to udev events, notices coarse changes
5. g-s-d opens X input device, checks the new orientation, closes
6. if the orientation changed, g-s-d will send out a signal to the shell before changing the orientation, change it, and send out another signal

enum {
  ORIENTATION_0,
  ORIENTATION_90,
  ORIENTATION_180,
  ORIENTATION_270
} Orientation;
enum {
  ORIENTATION_NOTIFICATION_PRE,
  ORIENTATION_NOTIFICATION_POST
} OrientationNotification;

void ScreenOrientationChanged (Orientation new_orientation,
                               Orientation old_orientation,
                               OrientationNotification type);

The possible problems would be orientation locking by the user and by applications.

We could use a simple GSettings boolean for the user orientation lock. The application orientation lock would be more complicated. If X allows us to open exclusive access to the accelerometer, then we can dismiss the changes if we fail to open the device in 5. Otherwise we'd need an inhibit D-Bus API.
Comment 1 William Jon McCann 2011-05-19 23:45:54 UTC
And probably want a signal in the toolkit to allow the app to change appearance when orientation changes.  Basically, portrait vs landscape.
Comment 2 Peter Hutterer 2011-05-19 23:57:18 UTC
(In reply to comment #0)
> 3. Make it appear as an input device in X, one that wouldn't attach underneath
> the core virtual devices (Peter, how do we do that?)

float the device. XIChangeHierarchy() or even better add Option "Floating" "on" in an xorg.conf snippet to have it floating out-of-the-box.

> If X allows us to open exclusive access to the accelerometer, then we can 
> dismiss the changes if we fail to open the device in 5.

XIGrabDevice() will grab the device and you have exclusive access.



What are you planning to do with other input devices?
Touchpads and tablets matter here (well, any absolute device, really), especially built-in ones.
Comment 3 Bastien Nocera 2011-05-20 00:13:40 UTC
(In reply to comment #2)
> (In reply to comment #0)
> > 3. Make it appear as an input device in X, one that wouldn't attach underneath
> > the core virtual devices (Peter, how do we do that?)
> 
> float the device. XIChangeHierarchy() or even better add Option "Floating" "on"
> in an xorg.conf snippet to have it floating out-of-the-box.

If you have a snippet at hand, I can send you one to include upstream for my device.

> > If X allows us to open exclusive access to the accelerometer, then we can 
> > dismiss the changes if we fail to open the device in 5.
> 
> XIGrabDevice() will grab the device and you have exclusive access.

I'm guessing that applications that are interested in that (such as games, or utilities that would make use of the accelerometer) would already be using that to access the devices.

> What are you planning to do with other input devices?
> Touchpads and tablets matter here (well, any absolute device, really),
> especially built-in ones.

I didn't have any plans per se. I would have thought XRandR would automatically handle switching the orientation for the input devices as well.
Comment 4 Bastien Nocera 2011-05-20 00:14:20 UTC
(In reply to comment #1)
> And probably want a signal in the toolkit to allow the app to change appearance
> when orientation changes.  Basically, portrait vs landscape.

Before, after, both?
Comment 5 Peter Hutterer 2011-05-20 00:33:42 UTC
(In reply to comment #3)
> If you have a snippet at hand, I can send you one to include upstream for my
> device.

check your /usr/share/X11/xorg.conf.d/10-quirks.conf:
Section "InputClass"
        Identifier "ThinkPad HDAPS accelerometer blacklist"
        MatchProduct "ThinkPad HDAPS accelerometer data"
        Option "Ignore" "on"
EndSection

Replace Ignore with Floating and the MatchProduct with your device. Note
that Floating is a relatively new option, server 1.10/F15 only IIRC.

> > > If X allows us to open exclusive access to the accelerometer, then we can 
> > > dismiss the changes if we fail to open the device in 5.
> > 
> > XIGrabDevice() will grab the device and you have exclusive access.
> 
> I'm guessing that applications that are interested in that (such as games, or
> utilities that would make use of the accelerometer) would already be using that
> to access the devices.

yes, this is a problem, only one client can grab the device. you can still
listen for events normally while it's floating though, that way you don't
interfere or listen for RawEvents from that device.

> > What are you planning to do with other input devices?
> > Touchpads and tablets matter here (well, any absolute device, really),
> > especially built-in ones.
> 
> I didn't have any plans per se. I would have thought XRandR would automatically
> handle switching the orientation for the input devices as well.

no, you need a client to trigger it for those devices that need to be
rotated. we can't implement an always-rotate policy in the server because
there's too many cases where it isn't the right one.
Comment 6 Bastien Nocera 2011-05-27 17:34:19 UTC
(In reply to comment #1)
> And probably want a signal in the toolkit to allow the app to change appearance
> when orientation changes.  Basically, portrait vs landscape.

That data is already available in GDK, as you can check the orientation (portait or landscape) of the screen your application is in through the "monitors-changed"). Adding a simple helper on top of that should be easy enough, if necessary to cut down on the cut'n'paste.
Comment 7 Bastien Nocera 2011-05-27 17:52:45 UTC
(In reply to comment #5)
> (In reply to comment #3)
> > If you have a snippet at hand, I can send you one to include upstream for my
> > device.
> 
> check your /usr/share/X11/xorg.conf.d/10-quirks.conf:
> Section "InputClass"
>         Identifier "ThinkPad HDAPS accelerometer blacklist"
>         MatchProduct "ThinkPad HDAPS accelerometer data"
>         Option "Ignore" "on"
> EndSection
> 
> Replace Ignore with Floating and the MatchProduct with your device. Note
> that Floating is a relatively new option, server 1.10/F15 only IIRC.

Done, will file a bug when the stack of stuff is done properly.

> > > > If X allows us to open exclusive access to the accelerometer, then we can 
> > > > dismiss the changes if we fail to open the device in 5.
> > > 
> > > XIGrabDevice() will grab the device and you have exclusive access.
> > 
> > I'm guessing that applications that are interested in that (such as games, or
> > utilities that would make use of the accelerometer) would already be using that
> > to access the devices.
> 
> yes, this is a problem, only one client can grab the device. you can still
> listen for events normally while it's floating though, that way you don't
> interfere or listen for RawEvents from that device.

Well, I'd actually _want_ the device not to be available to gnome-settings-daemon (that way I could say "nope, an app is already using it for other things, so I'm not even trying to rotate this screen").

> > > What are you planning to do with other input devices?
> > > Touchpads and tablets matter here (well, any absolute device, really),
> > > especially built-in ones.
> > 
> > I didn't have any plans per se. I would have thought XRandR would automatically
> > handle switching the orientation for the input devices as well.
> 
> no, you need a client to trigger it for those devices that need to be
> rotated. we can't implement an always-rotate policy in the server because
> there's too many cases where it isn't the right one.

Do you have any example code for that? I'd like to do this whenever the orientation is changed, for all the "XI_TOUCHSCREEN" devices.
Comment 8 Peter Hutterer 2011-05-30 05:47:30 UTC
(In reply to comment #7)
> Do you have any example code for that? I'd like to do this whenever the
> orientation is changed, for all the "XI_TOUCHSCREEN" devices.

I don't have any code ready but I'm sure g-s-d listens for xrandr events already, so you can steal the code from there. The grab works with XIGrabDevice(3) with the XI_Motion mask set. The real problem is input device rotation because there is no standardised method (yet). evdev and wacom have properties that are slightly different, so you need XListDeviceProperties to test for which ones exist and then tweak them accordingly. I'll see if I can sort out the rotation issues somehow upstream.
Comment 9 Bastien Nocera 2011-05-31 11:27:09 UTC
Created attachment 188929 [details] [review]
xrandr: Switch touchscreen rotation as well

When switching rotation of a screen in tablet/laptop mode (one
screen), also switch the orientation of the touchscreen input
device so it keep being useful.

NOTE: values for rotation not checked
NOTE: wacom rotation not implemented
Comment 10 Bastien Nocera 2011-05-31 11:29:04 UTC
First pass at the xrandr patch. This should allow using the xrandr extension, or the display panel to switch orientation, and have the input device follow.

It also adds the "RotateTo" D-Bus method so that the plugin taking care of listening to the accelerometer can do its work.
Comment 11 Bastien Nocera 2011-05-31 14:03:46 UTC
2nd patch, this time tested. You can use this API, replace X with 1, 2, 4 or 8 (see http://git.gnome.org/browse/gnome-desktop/tree/libgnome-desktop/gnome-rr.h#n53 for values):
gdbus call --session --dest  org.gnome.SettingsDaemon --object-path /org/gnome/SettingsDaemon/XRANDR --method org.gnome.SettingsDaemon.XRANDR_2.RotateTo X 0

If you're testing with a non-laptop machine, you might also need to tweak is_laptop(). I added:
+       if (g_strcmp0 ("DVI-0", gnome_rr_output_info_get_name (output)) == 0)
+               return TRUE;
for testing on my touchscreen desktop machine.

Bug fixes include:
- fix missing symbol from libcommon.la
- fix rotation type in D-Bus API
- fix args order for gsd_xrandr_manager_2_rotate_to()
- test and use correct values in evdev_rotations[], and stop out-of-bounds access
- add more debug output
Comment 12 Bastien Nocera 2011-05-31 14:03:56 UTC
Created attachment 188941 [details] [review]
xrandr: Switch touchscreen rotation as well

When switching rotation of a screen in tablet/laptop mode (one
screen), also switch the orientation of the touchscreen input
device so it keep being useful.

NOTE: wacom rotation not implemented
Comment 13 Bastien Nocera 2011-05-31 14:48:37 UTC
Comment on attachment 188941 [details] [review]
xrandr: Switch touchscreen rotation as well

Added a single "settings" call to set the wacom tablet's orientation.

Peter, what do you think the interaction should be for wacom touchscreens? I'm thinking that the orientation setting in the wacom plugin should never be touched for touchscreens, and let the xrandr plugin do the rotation instead (will need to copy some code for that).

Could you also file a new bug about that?
Comment 14 Owen Taylor 2011-05-31 15:49:46 UTC
> 6. if the orientation changed, g-s-d will send out a signal to the shell before
> changing the orientation, change it, and send out another signal
> 
> enum {
>   ORIENTATION_0,
>   ORIENTATION_90,
>   ORIENTATION_180,
>   ORIENTATION_270
> } Orientation;
> enum {
>   ORIENTATION_NOTIFICATION_PRE,
>   ORIENTATION_NOTIFICATION_POST
> } OrientationNotification;
> 
> void ScreenOrientationChanged (Orientation new_orientation,
>                                Orientation old_orientation,
>                                OrientationNotification type);

- Given this API, how does g-s-d know it's safe to proceed after sending out the "PRE" signals?

- How do you see this differing from a more generic "monitor layout change"? Are there specific things that you would expect the shell to do to move windows around on orientation change that wouldn't happen if you changed the resolution?

- Does it make sense to try to implement the generic "layout change" at the same time?

- I assume that the long-term desired visual effect is that you turn the table, and then the screen atomically updates to a new state. This API would allow us to fade/flash to black, then fade/flash back at the shell's convenience  once windows are validated, but isn't sufficient for an actual atomic screen update. Do we want to future proof against that? Do we have any idea what that would involve?

Roughly speaking, the atomic change seems to involve being able to disconnect the selected front buffer being displayed from the front buffer used from rendering - i.e., you'd tell xrandr "OK, allocate buffers and redirect drawing for this new setup, but keep scanning out the old way" and then at some point "change the scanout and discard the old front buffers".

(Added Adam Jackson to the Cc: of the bug in case he wants to comment)

Which implies that there is a need for the compositor to say back to g-s-d "OK, I'm done redrawing"  .... sort of relating to the first question above - how do you know when the "PRE" is done - we seem to also need to know when "POST" is done. So, perhaps this shouldn't be signals but rather methods on a compositor D-Bus object?
Comment 15 Bastien Nocera 2011-05-31 17:11:17 UTC
I moved the discussion about XRandR transitions to bug 644230, where we already started discussing this some time ago.

What's left is figuring out the implementation, and interface of the actual orientation bits.

Implementation:
- Look for accelerometers supported by X (floating device with X/Y/Z info)
- We have one, listen on udev events (FIXME, filter by sysfs path, needs xinput to export this information)
- When uevent is received for the device, open floating accel device, and figure out orientation (see also http://gitorious.org/sensorfw/sensorfw/blobs/master/tests/contextfw/orientation/testorientation.py for example data and results)
- If opening the device fails, don't do anything (it's used by another app)
- Call out to XRandR plugin to rotate to a particular orientation

D-Bus properties:
- enum Orientation
- boolean OrientationLocked

Locking the orientation would only be used by gnome-shell/the user to stop automatic orientation changes. We might need to add an inhibit style API if we cannot rely on applications grabbing exclusive use of the accelerometer device.
Comment 16 Bastien Nocera 2011-06-06 17:25:51 UTC
Committed the latest pass at this to master. We now use udev solely to discover the device orientation.

Screen locking is only available through GSettings. gnome-shell should check for the presence of the org.gnome.SettingsDaemon.Orientation interface on D-Bus to know whether or not to show an orientation locking button.

commit 17f86e87269ff7f424d35c998801d3fbd105d504
Author: Bastien Nocera <hadess@hadess.net>
Date:   Mon Jun 6 18:20:05 2011 +0100

    orientation: Use new orientation property from udev
    
    Instead of needing to poke at X devices ourselves.
    
    Now we just read the new orientation from the
    ID_INPUT_ACCELEROMETER_ORIENTATION property, and rotate the
    screen if it's changed from the previous value.
    
    This requires a newer version of udev, currently only in git,
    but shortly in version 172. See also:
    http://git.kernel.org/?p=linux/hotplug/udev.git;a=commit;h=24569e24dc94a7cffb8031eb0055e8d06cbdcb72
    
    https://bugzilla.gnome.org/show_bug.cgi?id=650603