Merge lp:~jderose/ubuntu/saucy/gnome-settings-daemon/tune-syndaemon2 into lp:ubuntu/saucy/gnome-settings-daemon

Proposed by Jason Gerard DeRose
Status: Needs review
Proposed branch: lp:~jderose/ubuntu/saucy/gnome-settings-daemon/tune-syndaemon2
Merge into: lp:ubuntu/saucy/gnome-settings-daemon
Diff against target: 4202 lines (+1384/-2531)
9 files modified
.pc/applied-patches (+1/-0)
.pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in (+0/-212)
.pc/sync_input_sources_to_accountsservice.patch/configure.ac (+0/-609)
.pc/sync_input_sources_to_accountsservice.patch/plugins/keyboard/gsd-keyboard-manager.c (+0/-1708)
.pc/tune-syndaemon.patch/plugins/mouse/gsd-mouse-manager.c (+1354/-0)
debian/changelog (+7/-0)
debian/patches/series (+1/-0)
debian/patches/tune-syndaemon.patch (+20/-0)
plugins/mouse/gsd-mouse-manager.c (+1/-2)
To merge this branch: bzr merge lp:~jderose/ubuntu/saucy/gnome-settings-daemon/tune-syndaemon2
Reviewer Review Type Date Requested Status
Luke Yelavich (community) Needs Information
Review via email: mp+181565@code.launchpad.net

Description of the change

See https://bugs.launchpad.net/ubuntu/+source/gnome-settings-daemon/+bug/1215463

On a modern laptop with a large touchpad/clickpad, your palms tend to brush the touch surface as you type. The problem is that on Ubuntu, this creates an annoying amount of cursor wiggle. Competing platforms don't have this problem, so this needs to be improved on Ubuntu.

Part of the problem is the is that `xserver-xorg-input-synaptics` driver doesn't do effective palm detection (it seems), and part of the problem is that `gnome-settings-daemon` launches `syndaemon` such that it *never* disables cursor movement.

Currently syndaemon is launched like this:

  syndaemon -i 1.0 -t -K -R

The "-t" option tells syndaemon to never block cursor movement. It will only block accidental vertical scrolling (which is darn near impossible to do on a modern system with two finger scrolling), and block accidental tap-to-click (which seems unlikely something you can do by mistake with your palms). So from a user perspective, "Disable while typing" currently does nothing.

I'm proposing that syndaemon instead be launched like this:

  syndaemon -i 0.5 -K -R

Without the "-t" option, syndaemon will block cursor movement, vertical scrolling, and tap-to-click. And the "-i 0.5" means it will block it for 500ms (half a second).

System76 has been shipping a patched `gnome-settings-daemon` (Raring) on all our products for the last two months, and we've received no support issues about it (if this caused noticeable usability issues, I'm confident we'd have heard about it).

We've also done a lot of testing and tuning on the timeout threshold, and 500ms seems like about the sweet spot. It's long enough to be decently effective for most typists, but not so long that the user will catch the trackpad still disabled when they move from typing back to "cursoring" :P

Note that this isn't a prefect solution, and you really can't do this especially well with a static timeout anyway (would be better to be dynamic based on typing speed). For slow typists, 500ms often isn't long enough. But for now, I feel it's better to find that sweet spot where it at least gives some improvement for most users, without causing any negative impact for any users.

To post a comment you must log in.
Revision history for this message
Jason Gerard DeRose (jderose) wrote :

Question: as far as I know, you're supposed to add changes in the .pc directory for UDD workflow. Just wanted to double check as this diff looks like such a mess :)

Revision history for this message
Luke Yelavich (themuso) wrote :

Given this is the upstrea default, I wonder whether its worth discussing it upstream. WHilst this is a trivial patch, it is yet another patch that Ubuntu has to carry, and we already carry a lot of patches against this package.

I suggest filing a bug upstream and discussing the desire to remove the -t flag, and indeed discuss why upstream decided to use the -t flag in the first place.

review: Needs Information
Revision history for this message
Jason Gerard DeRose (jderose) wrote :

Thanks for the feedback, Luke!

Yes, I plan on discussing this upstream, but I'd first like to get consensus from Ubuntu on this change, as it doesn't help System76 if the change is accepted upstream but Ubuntu disagrees with it.

Also as Ubuntu isn't tracking the upstream gnome-settings-daemon releases closely anymore, it will likely take more than one full cycle by the time the change would land in Ubuntu. Based on the current pattern, if we got this change accepted into gnome-settings-daemon 3.10, it wouldn't land in Ubuntu till Ubuntu 14.10.

For what it's worth, it would really help System76 if this change could be accepted into Saucy, as then we don't have to maintained a patched version in our PPA.

254. By Jason Gerard DeRose

Merged 3.6.4-0ubuntu17 from lp:ubuntu/saucy/gnome-settings-daemon

255. By Jason Gerard DeRose

Added 3.6.4-0ubuntu18 entry in changelog

256. By Jason Gerard DeRose

Added DEP-3 headers to tune-syndaemon.patch

257. By Jason Gerard DeRose

Clearer

258. By Jason Gerard DeRose

Merged from 3.6.4-0ubuntu19 lp:ubuntu/saucy/gnome-settings-daemon

259. By Jason Gerard DeRose

Add changelog entry for 3.6.4-0ubuntu20

Revision history for this message
Doug McMahon (mc3man) wrote :

hope you all aren't going around in circles on this
The current settings are the result of this bug, caused when g-s-d went to 2 sec
https://bugs.launchpad.net/ubuntu/+source/gnome-settings-daemon/+bug/801763

That resulted in this bug, maybe others
https://bugs.launchpad.net/ubuntu/+source/gnome-settings-daemon/+bug/962958

And the current settings from
https://bugzilla.gnome.org/show_bug.cgi?id=673055

Unmerged revisions

259. By Jason Gerard DeRose

Add changelog entry for 3.6.4-0ubuntu20

258. By Jason Gerard DeRose

Merged from 3.6.4-0ubuntu19 lp:ubuntu/saucy/gnome-settings-daemon

257. By Jason Gerard DeRose

Clearer

256. By Jason Gerard DeRose

Added DEP-3 headers to tune-syndaemon.patch

255. By Jason Gerard DeRose

Added 3.6.4-0ubuntu18 entry in changelog

254. By Jason Gerard DeRose

Merged 3.6.4-0ubuntu17 from lp:ubuntu/saucy/gnome-settings-daemon

253. By Jason Gerard DeRose

Updated changelog

252. By Jason Gerard DeRose

Added tune-syndaemon.patch so that syndaemon is called with '-i 0.5 -K -R'

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.pc/applied-patches'
2--- .pc/applied-patches 2013-08-29 16:10:41 +0000
3+++ .pc/applied-patches 2013-08-29 18:58:42 +0000
4@@ -31,3 +31,4 @@
5 git_keyboard_Adapt_to_gnome_xkb_info_API_change.patch
6 git_keyboard_Adapt_to_gnome_xkb_info_API_change_2.patch
7 git_keybindings_add_screen_reader_toggle.patch
8+tune-syndaemon.patch
9
10=== added directory '.pc/git_keybindings_add_screen_reader_toggle.patch'
11=== removed directory '.pc/git_keybindings_add_screen_reader_toggle.patch'
12=== added directory '.pc/git_keybindings_add_screen_reader_toggle.patch/data'
13=== removed directory '.pc/git_keybindings_add_screen_reader_toggle.patch/data'
14=== added file '.pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in'
15--- .pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in 1970-01-01 00:00:00 +0000
16+++ .pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in 2013-08-29 18:58:42 +0000
17@@ -0,0 +1,212 @@
18+<schemalist>
19+ <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys" path="/org/gnome/settings-daemon/plugins/media-keys/">
20+ <key name="active" type="b">
21+ <default>true</default>
22+ <_summary>Activation of this plugin</_summary>
23+ <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
24+ </key>
25+ <key name="custom-keybindings" type="as">
26+ <default>[]</default>
27+ <_summary>Custom keybindings</_summary>
28+ <_description>List of custom keybindings</_description>
29+ </key>
30+ <key name="calculator" type="s">
31+ <default>'XF86Calculator'</default>
32+ <_summary>Launch calculator</_summary>
33+ <_description>Binding to launch the calculator.</_description>
34+ </key>
35+ <key name="email" type="s">
36+ <default>'XF86Mail'</default>
37+ <_summary>Launch email client</_summary>
38+ <_description>Binding to launch the email client.</_description>
39+ </key>
40+ <key name="eject" type="s">
41+ <default>'XF86Eject'</default>
42+ <_summary>Eject</_summary>
43+ <_description>Binding to eject an optical disc.</_description>
44+ </key>
45+ <key name="help" type="s">
46+ <default>''</default>
47+ <_summary>Launch help browser</_summary>
48+ <_description>Binding to launch the help browser.</_description>
49+ </key>
50+ <key name="home" type="s">
51+ <default>'XF86Explorer'</default>
52+ <_summary>Home folder</_summary>
53+ <_description>Binding to open the Home folder.</_description>
54+ </key>
55+ <key name="media" type="s">
56+ <default>'XF86AudioMedia'</default>
57+ <_summary>Launch media player</_summary>
58+ <_description>Binding to launch the media player.</_description>
59+ </key>
60+ <key name="next" type="s">
61+ <default>'XF86AudioNext'</default>
62+ <_summary>Next track</_summary>
63+ <_description>Binding to skip to next track.</_description>
64+ </key>
65+ <key name="pause" type="s">
66+ <default>'XF86AudioPause'</default>
67+ <_summary>Pause playback</_summary>
68+ <_description>Binding to pause playback.</_description>
69+ </key>
70+ <key name="play" type="s">
71+ <default>'XF86AudioPlay'</default>
72+ <_summary>Play (or play/pause)</_summary>
73+ <_description>Binding to start playback (or toggle play/pause).</_description>
74+ </key>
75+ <key name="logout" type="s">
76+ <default>'&lt;Control&gt;&lt;Alt&gt;Delete'</default>
77+ <_summary>Log out</_summary>
78+ <_description>Binding to log out.</_description>
79+ </key>
80+ <key name="previous" type="s">
81+ <default>'XF86AudioPrev'</default>
82+ <_summary>Previous track</_summary>
83+ <_description>Binding to skip to previous track.</_description>
84+ </key>
85+ <key name="priority" type="i">
86+ <default>98</default>
87+ <_summary>Priority to use for this plugin</_summary>
88+ <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
89+ </key>
90+ <key name="screensaver" type="s">
91+ <default>'&lt;Control&gt;&lt;Alt&gt;l'</default>
92+ <_summary>Lock screen</_summary>
93+ <_description>Binding to lock the screen.</_description>
94+ </key>
95+ <key name="search" type="s">
96+ <default>'XF86Search'</default>
97+ <_summary>Search</_summary>
98+ <_description>Binding to launch the search tool.</_description>
99+ </key>
100+ <key name="stop" type="s">
101+ <default>'XF86AudioStop'</default>
102+ <_summary>Stop playback</_summary>
103+ <_description>Binding to stop playback.</_description>
104+ </key>
105+ <key name="volume-down" type="s">
106+ <default>'XF86AudioLowerVolume'</default>
107+ <_summary>Volume down</_summary>
108+ <_description>Binding to lower the system volume.</_description>
109+ </key>
110+ <key name="volume-mute" type="s">
111+ <default>'XF86AudioMute'</default>
112+ <_summary>Volume mute</_summary>
113+ <_description>Binding to mute the system volume.</_description>
114+ </key>
115+ <key name="volume-up" type="s">
116+ <default>'XF86AudioRaiseVolume'</default>
117+ <_summary>Volume up</_summary>
118+ <_description>Binding to raise the system volume.</_description>
119+ </key>
120+ <key name="screenshot" type="s">
121+ <default>'Print'</default>
122+ <_summary>Take a screenshot</_summary>
123+ <_description>Binding to take a screenshot.</_description>
124+ </key>
125+ <key name="window-screenshot" type="s">
126+ <default>'&lt;Alt&gt;Print'</default>
127+ <_summary>Take a screenshot of a window</_summary>
128+ <_description>Binding to take a screenshot of a window.</_description>
129+ </key>
130+ <key name="area-screenshot" type="s">
131+ <default>'&lt;Shift&gt;Print'</default>
132+ <_summary>Take a screenshot of an area</_summary>
133+ <_description>Binding to take a screenshot of an area.</_description>
134+ </key>
135+ <key name="screenshot-clip" type="s">
136+ <default>'&lt;Ctrl&gt;Print'</default>
137+ <_summary>Copy a screenshot to clipboard</_summary>
138+ <_description>Binding to copy a screenshot to clipboard.</_description>
139+ </key>
140+ <key name="window-screenshot-clip" type="s">
141+ <default>'&lt;Ctrl&gt;&lt;Alt&gt;Print'</default>
142+ <_summary>Copy a screenshot of a window to clipboard</_summary>
143+ <_description>Binding to copy a screenshot of a window to clipboard.</_description>
144+ </key>
145+ <key name="area-screenshot-clip" type="s">
146+ <default>'&lt;Ctrl&gt;&lt;Shift&gt;Print'</default>
147+ <_summary>Copy a screenshot of an area to clipboard</_summary>
148+ <_description>Binding to copy a screenshot of an area to clipboard.</_description>
149+ </key>
150+ <key name="terminal" type="s">
151+ <default>'&lt;Primary&gt;&lt;Alt&gt;t'</default>
152+ <_summary>Launch terminal</_summary>
153+ <_description>Binding to launch the terminal.</_description>
154+ </key>
155+ <key name="www" type="s">
156+ <default>'XF86WWW'</default>
157+ <_summary>Launch web browser</_summary>
158+ <_description>Binding to launch the web browser.</_description>
159+ </key>
160+ <key name="magnifier" type="s">
161+ <default>'&lt;Alt&gt;&lt;Super&gt;8'</default>
162+ <_summary>Toggle magnifier</_summary>
163+ <_description>Binding to show the screen magnifier</_description>
164+ </key>
165+ <key name="screenreader" type="s">
166+ <default>''</default>
167+ <_summary>Toggle screen reader</_summary>
168+ <_description>Binding to start the screen reader</_description>
169+ </key>
170+ <key name="on-screen-keyboard" type="s">
171+ <default>''</default>
172+ <_summary>Toggle on-screen keyboard</_summary>
173+ <_description>Binding to show the on-screen keyboard</_description>
174+ </key>
175+ <key name="increase-text-size" type="s">
176+ <default>''</default>
177+ <_summary>Increase text size</_summary>
178+ <_description>Binding to increase the text size</_description>
179+ </key>
180+ <key name="decrease-text-size" type="s">
181+ <default>''</default>
182+ <_summary>Decrease text size</_summary>
183+ <_description>Binding to decrease the text size</_description>
184+ </key>
185+ <key name="toggle-contrast" type="s">
186+ <default>''</default>
187+ <_summary>Toggle contrast</_summary>
188+ <_description>Binding to toggle the interface contrast</_description>
189+ </key>
190+ <key name="magnifier-zoom-in" type="s">
191+ <default>'&lt;Alt&gt;&lt;Super&gt;equal'</default>
192+ <_summary>Magnifier zoom in</_summary>
193+ <_description>Binding for the magnifier to zoom in</_description>
194+ </key>
195+ <key name="magnifier-zoom-out" type="s">
196+ <default>'&lt;Alt&gt;&lt;Super&gt;minus'</default>
197+ <_summary>Magnifier zoom out</_summary>
198+ <_description>Binding for the magnifier to zoom out</_description>
199+ </key>
200+ <key name="switch-input-source" type="s">
201+ <default>''</default>
202+ <_summary>Switch input source</_summary>
203+ <_description>Binding to select the next input source</_description>
204+ </key>
205+ <key name="switch-input-source-backward" type="s">
206+ <default>''</default>
207+ <_summary>Switch input source backward</_summary>
208+ <_description>Binding to select the previous input source</_description>
209+ </key>
210+ </schema>
211+
212+ <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys.custom-keybinding">
213+ <key name="name" type="s">
214+ <default>''</default>
215+ <_summary>Name</_summary>
216+ <_description>Name of the custom binding</_description>
217+ </key>
218+ <key name="binding" type="s">
219+ <default>''</default>
220+ <_summary>Binding</_summary>
221+ <_description>Binding for the custom binding</_description>
222+ </key>
223+ <key name="command" type="s">
224+ <default>''</default>
225+ <_summary>Command</_summary>
226+ <_description>Command to run when the binding is invoked</_description>
227+ </key>
228+ </schema>
229+</schemalist>
230
231=== removed file '.pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in'
232--- .pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in 2013-08-23 16:08:29 +0000
233+++ .pc/git_keybindings_add_screen_reader_toggle.patch/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in 1970-01-01 00:00:00 +0000
234@@ -1,212 +0,0 @@
235-<schemalist>
236- <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys" path="/org/gnome/settings-daemon/plugins/media-keys/">
237- <key name="active" type="b">
238- <default>true</default>
239- <_summary>Activation of this plugin</_summary>
240- <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
241- </key>
242- <key name="custom-keybindings" type="as">
243- <default>[]</default>
244- <_summary>Custom keybindings</_summary>
245- <_description>List of custom keybindings</_description>
246- </key>
247- <key name="calculator" type="s">
248- <default>'XF86Calculator'</default>
249- <_summary>Launch calculator</_summary>
250- <_description>Binding to launch the calculator.</_description>
251- </key>
252- <key name="email" type="s">
253- <default>'XF86Mail'</default>
254- <_summary>Launch email client</_summary>
255- <_description>Binding to launch the email client.</_description>
256- </key>
257- <key name="eject" type="s">
258- <default>'XF86Eject'</default>
259- <_summary>Eject</_summary>
260- <_description>Binding to eject an optical disc.</_description>
261- </key>
262- <key name="help" type="s">
263- <default>''</default>
264- <_summary>Launch help browser</_summary>
265- <_description>Binding to launch the help browser.</_description>
266- </key>
267- <key name="home" type="s">
268- <default>'XF86Explorer'</default>
269- <_summary>Home folder</_summary>
270- <_description>Binding to open the Home folder.</_description>
271- </key>
272- <key name="media" type="s">
273- <default>'XF86AudioMedia'</default>
274- <_summary>Launch media player</_summary>
275- <_description>Binding to launch the media player.</_description>
276- </key>
277- <key name="next" type="s">
278- <default>'XF86AudioNext'</default>
279- <_summary>Next track</_summary>
280- <_description>Binding to skip to next track.</_description>
281- </key>
282- <key name="pause" type="s">
283- <default>'XF86AudioPause'</default>
284- <_summary>Pause playback</_summary>
285- <_description>Binding to pause playback.</_description>
286- </key>
287- <key name="play" type="s">
288- <default>'XF86AudioPlay'</default>
289- <_summary>Play (or play/pause)</_summary>
290- <_description>Binding to start playback (or toggle play/pause).</_description>
291- </key>
292- <key name="logout" type="s">
293- <default>'&lt;Control&gt;&lt;Alt&gt;Delete'</default>
294- <_summary>Log out</_summary>
295- <_description>Binding to log out.</_description>
296- </key>
297- <key name="previous" type="s">
298- <default>'XF86AudioPrev'</default>
299- <_summary>Previous track</_summary>
300- <_description>Binding to skip to previous track.</_description>
301- </key>
302- <key name="priority" type="i">
303- <default>98</default>
304- <_summary>Priority to use for this plugin</_summary>
305- <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
306- </key>
307- <key name="screensaver" type="s">
308- <default>'&lt;Control&gt;&lt;Alt&gt;l'</default>
309- <_summary>Lock screen</_summary>
310- <_description>Binding to lock the screen.</_description>
311- </key>
312- <key name="search" type="s">
313- <default>'XF86Search'</default>
314- <_summary>Search</_summary>
315- <_description>Binding to launch the search tool.</_description>
316- </key>
317- <key name="stop" type="s">
318- <default>'XF86AudioStop'</default>
319- <_summary>Stop playback</_summary>
320- <_description>Binding to stop playback.</_description>
321- </key>
322- <key name="volume-down" type="s">
323- <default>'XF86AudioLowerVolume'</default>
324- <_summary>Volume down</_summary>
325- <_description>Binding to lower the system volume.</_description>
326- </key>
327- <key name="volume-mute" type="s">
328- <default>'XF86AudioMute'</default>
329- <_summary>Volume mute</_summary>
330- <_description>Binding to mute the system volume.</_description>
331- </key>
332- <key name="volume-up" type="s">
333- <default>'XF86AudioRaiseVolume'</default>
334- <_summary>Volume up</_summary>
335- <_description>Binding to raise the system volume.</_description>
336- </key>
337- <key name="screenshot" type="s">
338- <default>'Print'</default>
339- <_summary>Take a screenshot</_summary>
340- <_description>Binding to take a screenshot.</_description>
341- </key>
342- <key name="window-screenshot" type="s">
343- <default>'&lt;Alt&gt;Print'</default>
344- <_summary>Take a screenshot of a window</_summary>
345- <_description>Binding to take a screenshot of a window.</_description>
346- </key>
347- <key name="area-screenshot" type="s">
348- <default>'&lt;Shift&gt;Print'</default>
349- <_summary>Take a screenshot of an area</_summary>
350- <_description>Binding to take a screenshot of an area.</_description>
351- </key>
352- <key name="screenshot-clip" type="s">
353- <default>'&lt;Ctrl&gt;Print'</default>
354- <_summary>Copy a screenshot to clipboard</_summary>
355- <_description>Binding to copy a screenshot to clipboard.</_description>
356- </key>
357- <key name="window-screenshot-clip" type="s">
358- <default>'&lt;Ctrl&gt;&lt;Alt&gt;Print'</default>
359- <_summary>Copy a screenshot of a window to clipboard</_summary>
360- <_description>Binding to copy a screenshot of a window to clipboard.</_description>
361- </key>
362- <key name="area-screenshot-clip" type="s">
363- <default>'&lt;Ctrl&gt;&lt;Shift&gt;Print'</default>
364- <_summary>Copy a screenshot of an area to clipboard</_summary>
365- <_description>Binding to copy a screenshot of an area to clipboard.</_description>
366- </key>
367- <key name="terminal" type="s">
368- <default>'&lt;Primary&gt;&lt;Alt&gt;t'</default>
369- <_summary>Launch terminal</_summary>
370- <_description>Binding to launch the terminal.</_description>
371- </key>
372- <key name="www" type="s">
373- <default>'XF86WWW'</default>
374- <_summary>Launch web browser</_summary>
375- <_description>Binding to launch the web browser.</_description>
376- </key>
377- <key name="magnifier" type="s">
378- <default>'&lt;Alt&gt;&lt;Super&gt;8'</default>
379- <_summary>Toggle magnifier</_summary>
380- <_description>Binding to show the screen magnifier</_description>
381- </key>
382- <key name="screenreader" type="s">
383- <default>''</default>
384- <_summary>Toggle screen reader</_summary>
385- <_description>Binding to start the screen reader</_description>
386- </key>
387- <key name="on-screen-keyboard" type="s">
388- <default>''</default>
389- <_summary>Toggle on-screen keyboard</_summary>
390- <_description>Binding to show the on-screen keyboard</_description>
391- </key>
392- <key name="increase-text-size" type="s">
393- <default>''</default>
394- <_summary>Increase text size</_summary>
395- <_description>Binding to increase the text size</_description>
396- </key>
397- <key name="decrease-text-size" type="s">
398- <default>''</default>
399- <_summary>Decrease text size</_summary>
400- <_description>Binding to decrease the text size</_description>
401- </key>
402- <key name="toggle-contrast" type="s">
403- <default>''</default>
404- <_summary>Toggle contrast</_summary>
405- <_description>Binding to toggle the interface contrast</_description>
406- </key>
407- <key name="magnifier-zoom-in" type="s">
408- <default>'&lt;Alt&gt;&lt;Super&gt;equal'</default>
409- <_summary>Magnifier zoom in</_summary>
410- <_description>Binding for the magnifier to zoom in</_description>
411- </key>
412- <key name="magnifier-zoom-out" type="s">
413- <default>'&lt;Alt&gt;&lt;Super&gt;minus'</default>
414- <_summary>Magnifier zoom out</_summary>
415- <_description>Binding for the magnifier to zoom out</_description>
416- </key>
417- <key name="switch-input-source" type="s">
418- <default>''</default>
419- <_summary>Switch input source</_summary>
420- <_description>Binding to select the next input source</_description>
421- </key>
422- <key name="switch-input-source-backward" type="s">
423- <default>''</default>
424- <_summary>Switch input source backward</_summary>
425- <_description>Binding to select the previous input source</_description>
426- </key>
427- </schema>
428-
429- <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys.custom-keybinding">
430- <key name="name" type="s">
431- <default>''</default>
432- <_summary>Name</_summary>
433- <_description>Name of the custom binding</_description>
434- </key>
435- <key name="binding" type="s">
436- <default>''</default>
437- <_summary>Binding</_summary>
438- <_description>Binding for the custom binding</_description>
439- </key>
440- <key name="command" type="s">
441- <default>''</default>
442- <_summary>Command</_summary>
443- <_description>Command to run when the binding is invoked</_description>
444- </key>
445- </schema>
446-</schemalist>
447
448=== removed directory '.pc/sync_input_sources_to_accountsservice.patch'
449=== removed file '.pc/sync_input_sources_to_accountsservice.patch/configure.ac'
450--- .pc/sync_input_sources_to_accountsservice.patch/configure.ac 2013-08-29 16:10:41 +0000
451+++ .pc/sync_input_sources_to_accountsservice.patch/configure.ac 1970-01-01 00:00:00 +0000
452@@ -1,609 +0,0 @@
453-AC_PREREQ([2.60])
454-
455-AC_INIT([gnome-settings-daemon],
456- [3.6.4],
457- [http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-settings-daemon])
458-
459-AC_CONFIG_SRCDIR([gnome-settings-daemon/gnome-settings-manager.c])
460-
461-AM_INIT_AUTOMAKE([1.9 tar-ustar dist-xz no-dist-gzip check-news])
462-AM_MAINTAINER_MODE([enable])
463-
464-m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
465-
466-m4_define([gsd_api_version_major],[3])
467-m4_define([gsd_api_version_minor],[0])
468-m4_define([gsd_api_version],[gsd_api_version_major.gsd_api_version_minor])
469-GSD_API_VERSION="gsd_api_version"
470-AC_SUBST(GSD_API_VERSION)
471-
472-AC_STDC_HEADERS
473-AC_PROG_CXX
474-AM_PROG_CC_C_O
475-AC_PROG_LIBTOOL
476-
477-AC_HEADER_STDC
478-
479-AC_SUBST(VERSION)
480-
481-AC_CONFIG_HEADERS([config.h])
482-
483-IT_PROG_INTLTOOL([0.37.1])
484-
485-GETTEXT_PACKAGE=gnome-settings-daemon
486-AC_SUBST(GETTEXT_PACKAGE)
487-AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Name of default gettext domain])
488-
489-AM_GLIB_GNU_GETTEXT
490-
491-GSD_INTLTOOL_PLUGIN_RULE='%.gnome-settings-plugin: %.gnome-settings-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
492-AC_SUBST([GSD_INTLTOOL_PLUGIN_RULE])
493-
494-dnl ---------------------------------------------------------------------------
495-dnl - Dependencies
496-dnl ---------------------------------------------------------------------------
497-
498-GLIB_REQUIRED_VERSION=2.31.0
499-GTK_REQUIRED_VERSION=3.3.18
500-GCONF_REQUIRED_VERSION=2.6.1
501-GIO_REQUIRED_VERSION=2.26.0
502-GNOME_DESKTOP_REQUIRED_VERSION=3.5.3
503-LIBNOTIFY_REQUIRED_VERSION=0.7.3
504-UPOWER_GLIB_REQUIRED_VERSION=0.9.1
505-PA_REQUIRED_VERSION=0.9.16
506-LIBWACOM_REQUIRED_VERSION=0.6
507-UPOWER_REQUIRED_VERSION=0.9.11
508-APPINDICATOR_REQUIRED_VERSION=0.3.0
509-IBUS_REQUIRED_VERSION=1.4.99
510-
511-EXTRA_COMPILE_WARNINGS(yes)
512-
513-PKG_CHECK_MODULES(SETTINGS_DAEMON,
514- glib-2.0 >= $GLIB_REQUIRED_VERSION
515- gtk+-3.0 >= $GTK_REQUIRED_VERSION
516- gio-2.0 >= $GIO_REQUIRED_VERSION
517- gmodule-2.0
518- gthread-2.0
519- gsettings-desktop-schemas >= 3.5.90
520-)
521-
522-PKG_CHECK_MODULES(SETTINGS_PLUGIN,
523- gtk+-3.0 >= $GTK_REQUIRED_VERSION
524- gio-2.0 >= $GIO_REQUIRED_VERSION
525- libnotify >= $LIBNOTIFY_REQUIRED_VERSION
526- gsettings-desktop-schemas
527- x11
528-)
529-
530-GSD_PLUGIN_LDFLAGS="-export_dynamic -module -avoid-version -no-undefined"
531-case $host_os in
532- darwin*)
533- GSD_PLUGIN_LDFLAGS="${GSD_PLUGIN_LDFLAGS} -Wl,-bundle_loader,\$(top_builddir)/gnome-settings-daemon/gnome-settings-daemon"
534- ;;
535-esac
536-AC_SUBST([GSD_PLUGIN_LDFLAGS])
537-
538-AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
539-
540-dnl ================================================================
541-dnl GSettings stuff
542-dnl ================================================================
543-
544-GLIB_GSETTINGS
545-
546-dnl ---------------------------------------------------------------------------
547-dnl - Check for gnome-desktop
548-dnl ---------------------------------------------------------------------------
549-PKG_CHECK_MODULES(GNOME_DESKTOP, gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
550-
551-dnl ---------------------------------------------------------------------------
552-dnl - Check for LCMS2
553-dnl ---------------------------------------------------------------------------
554-PKG_CHECK_MODULES(LCMS, lcms2 >= 2.2, have_new_lcms=yes, have_new_lcms=no)
555-if test x$have_new_lcms = xyes; then
556- AC_DEFINE(HAVE_NEW_LCMS,1,[Got new lcms2])
557-else
558- PKG_CHECK_MODULES(LCMS, lcms2)
559-fi
560-
561-dnl ---------------------------------------------------------------------------
562-dnl - Check for libnotify
563-dnl ---------------------------------------------------------------------------
564-
565-PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED_VERSION,
566- [have_libnotify=yes], have_libnotify=no)
567-if test "x$have_libnotify" = xno ; then
568- AC_MSG_ERROR([libnotify is required to build gnome-settings-daemon])
569-fi
570-AC_SUBST(LIBNOTIFY_CFLAGS)
571-AC_SUBST(LIBNOTIFY_LIBS)
572-
573-dnl ---------------------------------------------------------------------------
574-dnl - GUdev integration (default enabled)
575-dnl ---------------------------------------------------------------------------
576-GUDEV_PKG=""
577-AC_ARG_ENABLE(gudev, AS_HELP_STRING([--disable-gudev],[Disable GUdev support (not optional on Linux platforms)]), enable_gudev=$enableval)
578-if test x$enable_gudev != xno; then
579- PKG_CHECK_MODULES(GUDEV, gudev-1.0, have_gudev="yes", have_gudev="no")
580- if test "x$have_gudev" = "xyes"; then
581- AC_DEFINE(HAVE_GUDEV, 1, [define if GUdev is available])
582- GUDEV_PKG="gudev-1.0"
583- else
584- if test x$enable_gudev = xyes; then
585- AC_MSG_ERROR([GUdev enabled but not found])
586- fi
587- fi
588-else
589- have_gudev=no
590-fi
591-AM_CONDITIONAL(HAVE_GUDEV, test x$have_gudev = xyes)
592-
593-dnl ---------------------------------------------------------------------------
594-dnl - common
595-dnl ---------------------------------------------------------------------------
596-
597-PKG_CHECK_MODULES(COMMON, x11 kbproto xi)
598-
599-dnl ---------------------------------------------------------------------------
600-dnl - automount
601-dnl ---------------------------------------------------------------------------
602-
603-PKG_CHECK_MODULES(AUTOMOUNT, x11 kbproto)
604-
605-dnl ---------------------------------
606-dnl - Application indicator
607-dnl ---------------------------------
608-
609-AC_ARG_ENABLE([appindicator],
610- AS_HELP_STRING([--enable-appindicator[=@<:@no/auto/yes@:>@]],[Build support for application indicators]),
611- [enable_appindicator=$enableval],
612- [enable_appindicator="auto"])
613-
614-
615-if test x$enable_appindicator = xauto ; then
616- PKG_CHECK_EXISTS(appindicator3-0.1 >= $APPINDICATOR_REQUIRED_VERSION,
617- [enable_appindicator="yes"],
618- [enable_appindicator="no"])
619-fi
620-
621-if test x$enable_appindicator = xyes ; then
622- PKG_CHECK_MODULES(APPINDICATOR,
623- [appindicator3-0.1 >= $APPINDICATOR_REQUIRED_VERSION],
624- [AC_DEFINE(HAVE_APPINDICATOR, 1, [Have AppIndicator])])
625-fi
626-
627-AM_CONDITIONAL(HAVE_APPINDICATOR, test x$enable_appindicator = xyes)
628-AC_SUBST(APPINDICATOR_CFLAGS)
629-AC_SUBST(APPINDICATOR_LIBS)
630-
631-dnl ---------------------------------------------------------------------------
632-dnl - background
633-dnl ---------------------------------------------------------------------------
634-
635-PKG_CHECK_MODULES(BACKGROUND, x11 gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
636-
637-dnl ---------------------------------------------------------------------------
638-dnl - mouse
639-dnl ---------------------------------------------------------------------------
640-
641-PKG_CHECK_MODULES(MOUSE, x11 xi)
642-
643-dnl ---------------------------------------------------------------------------
644-dnl - cursor
645-dnl ---------------------------------------------------------------------------
646-
647-PKG_CHECK_MODULES(CURSOR, xfixes)
648-
649-dnl ---------------------------------------------------------------------------
650-dnl - xsettings
651-dnl ---------------------------------------------------------------------------
652-
653-PKG_CHECK_MODULES(XSETTINGS, fontconfig)
654-
655-dnl ---------------------------------------------------------------------------
656-dnl - Keyboard plugin stuff
657-dnl ---------------------------------------------------------------------------
658-
659-AC_ARG_ENABLE(ibus,
660- AS_HELP_STRING([--disable-ibus],
661- [Disable IBus support]),
662- enable_ibus=$enableval,
663- enable_ibus=yes)
664-
665-if test "x$enable_ibus" = "xyes" ; then
666- IBUS_MODULE="ibus-1.0 >= $IBUS_REQUIRED_VERSION"
667- AC_DEFINE(HAVE_IBUS, 1, [Defined if IBus support is enabled])
668-else
669- IBUS_MODULE=
670-fi
671-AM_CONDITIONAL(HAVE_IBUS, test "x$enable_ibus" == "xyes")
672-
673-PKG_CHECK_MODULES(KEYBOARD, xkbfile $IBUS_MODULE gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
674-
675-dnl ---------------------------------------------------------------------------
676-dnl - Housekeeping plugin stuff
677-dnl ---------------------------------------------------------------------------
678-
679-PKG_CHECK_MODULES(GIOUNIX, [gio-unix-2.0])
680-
681-dnl ---------------------------------------------------------------------------
682-dnl - media-keys plugin stuff
683-dnl ---------------------------------------------------------------------------
684-
685-PKG_CHECK_MODULES(MEDIA_KEYS, [gio-unix-2.0 libpulse >= $PA_REQUIRED_VERSION $GUDEV_PKG libpulse-mainloop-glib >= $PA_REQUIRED_VERSION libcanberra libnotify])
686-
687-dnl ---------------------------------------------------------------------------
688-dnl - xrandr plugin stuff
689-dnl ---------------------------------------------------------------------------
690-
691-PKG_CHECK_MODULES(XRANDR, [gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION upower-glib >= $UPOWER_REQUIRED_VERSION])
692-
693-dnl ---------------------------------------------------------------------------
694-dnl - orientation plugin stuff
695-dnl ---------------------------------------------------------------------------
696-
697-if test x$have_gudev != xno; then
698- PKG_CHECK_MODULES(ORIENTATION, [gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION gudev-1.0])
699-fi
700-
701-dnl ---------------------------------------------------------------------------
702-dnl - sound plugin stuff
703-dnl ---------------------------------------------------------------------------
704-
705-PKG_CHECK_MODULES(SOUND, [libpulse >= $PA_REQUIRED_VERSION $GUDEV_PKG libpulse-mainloop-glib >= $PA_REQUIRED_VERSION])
706-
707-# ---------------------------------------------------------------------------
708-# Power
709-# ---------------------------------------------------------------------------
710-PKG_CHECK_MODULES(POWER, upower-glib >= $UPOWER_REQUIRED_VERSION gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION libcanberra-gtk3 libnotify x11 xext)
711-
712-if test x$have_gudev != xno; then
713- PKG_CHECK_MODULES(BACKLIGHT_HELPER,
714- glib-2.0 >= $GLIB_REQUIRED_VERSION
715- gudev-1.0
716- )
717-fi
718-
719-dnl ---------------------------------------------------------------------------
720-dnl - color
721-dnl ---------------------------------------------------------------------------
722-
723-PKG_CHECK_MODULES(COLOR, [colord >= 0.1.9 gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION libcanberra-gtk3])
724-
725-dnl ---------------------------------------------------------------------------
726-dnl - wacom (disabled for s390/s390x and non Linux platforms)
727-dnl ---------------------------------------------------------------------------
728-
729-case $host_os in
730- linux*)
731- if test "$host_cpu" = s390 -o "$host_cpu" = s390x; then
732- have_wacom=no
733- else
734- if test x$enable_gudev != xno; then
735- PKG_CHECK_MODULES(WACOM, [libwacom >= $LIBWACOM_REQUIRED_VERSION x11 xi xtst gudev-1.0 gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION xorg-wacom])
736- else
737- AC_MSG_ERROR([GUdev is necessary to compile Wacom support])
738- fi
739- have_wacom=yes
740- fi
741- ;;
742- *)
743- have_wacom=no
744- ;;
745-esac
746-AM_CONDITIONAL(HAVE_WACOM, test x$have_wacom = xyes)
747-
748-dnl ==============================================
749-dnl PackageKit section
750-dnl ==============================================
751-
752-have_packagekit=false
753-AC_ARG_ENABLE(packagekit,
754- AC_HELP_STRING([--disable-packagekit],
755- [turn off PackageKit support]),
756- [case "${enableval}" in
757- yes) WANT_PACKAGEKIT=yes ;;
758- no) WANT_PACKAGEKIT=no ;;
759- *) AC_MSG_ERROR(bad value ${enableval} for --disable-packagekit) ;;
760- esac],
761- [WANT_PACKAGEKIT=yes]) dnl Default value
762-
763-if test x$WANT_PACKAGEKIT = xyes ; then
764- PK_REQUIRED_VERSION=0.7.4
765- PKG_CHECK_MODULES(PACKAGEKIT, glib-2.0 packagekit-glib2 >= $PK_REQUIRED_VERSION upower-glib >= $UPOWER_REQUIRED_VERSION gudev-1.0 libnotify >= $LIBNOTIFY_REQUIRED_VERSION,
766- [have_packagekit=true
767- AC_DEFINE(HAVE_PACKAGEKIT, 1, [Define if PackageKit should be used])],
768- [have_packagekit=false])
769-fi
770-AM_CONDITIONAL(HAVE_PACKAGEKIT, test "x$have_packagekit" = "xtrue")
771-
772-AC_SUBST(PACKAGEKIT_CFLAGS)
773-AC_SUBST(PACKAGEKIT_LIBS)
774-
775-dnl ==============================================
776-dnl smartcard section
777-dnl ==============================================
778-have_smartcard_support=false
779-AC_ARG_ENABLE(smartcard-support,
780- AC_HELP_STRING([--disable-smartcard-support],
781- [turn off smartcard support]),
782- [case "${enableval}" in
783- yes) WANT_SMARTCARD_SUPPORT=yes ;;
784- no) WANT_SMARTCARD_SUPPORT=no ;;
785- *) AC_MSG_ERROR(bad value ${enableval} for --disable-smartcard-support) ;;
786- esac],
787- [WANT_SMARTCARD_SUPPORT=yes])
788-
789-if test x$WANT_SMARTCARD_SUPPORT = xyes ; then
790- NSS_REQUIRED_VERSION=3.11.2
791- PKG_CHECK_MODULES(NSS, nss >= $NSS_REQUIRED_VERSION,
792- [have_smartcard_support=true
793- AC_DEFINE(SMARTCARD_SUPPORT, 1, [Define if smartcard support should be enabled])],
794- [have_smartcard_support=false])
795-fi
796-AM_CONDITIONAL(SMARTCARD_SUPPORT, test "x$have_smartcard_support" = "xtrue")
797-
798-AC_SUBST(NSS_CFLAGS)
799-AC_SUBST(NSS_LIBS)
800-
801-AC_ARG_WITH(nssdb,
802- AC_HELP_STRING([--with-nssdb],
803- [where system NSS database is]))
804-
805-NSS_DATABASE=""
806-if test "x$have_smartcard_support" = "xtrue"; then
807- if ! test -z "$with_nssdb" ; then
808- NSS_DATABASE="$with_nssdb"
809- else
810- NSS_DATABASE="${sysconfdir}/pki/nssdb"
811- fi
812-else
813- if ! test -z "$with_nssdb" ; then
814- AC_MSG_WARN([nssdb specified when smartcard support is disabled])
815- fi
816-fi
817-
818-AC_SUBST(NSS_DATABASE)
819-
820-
821-dnl ==============================================
822-dnl systemd check
823-dnl ==============================================
824-
825-AC_ARG_ENABLE([systemd],
826- AS_HELP_STRING([--enable-systemd], [Use systemd for session tracking]),
827- [with_systemd=$enableval],
828- [with_systemd=no])
829-if test "$with_systemd" = "yes" ; then
830- PKG_CHECK_MODULES(SYSTEMD, [libsystemd-login])
831- AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is used for session tracking])
832- SESSION_TRACKING=systemd
833-else
834- SESSION_TRACKING=ConsoleKit
835-fi
836-
837-AC_SUBST(SYSTEMD_CFLAGS)
838-AC_SUBST(SYSTEMD_LIBS)
839-
840-AM_CONDITIONAL(WITH_SYSTEMD, [test "$with_systemd" = "yes"], [Using systemd])
841-
842-# ---------------------------------------------------------------------------
843-# CUPS
844-# ---------------------------------------------------------------------------
845-
846-AC_ARG_ENABLE(cups,
847- AS_HELP_STRING([--disable-cups], [disable CUPS support (default: enabled)]),,
848- enable_cups=yes)
849-
850-if test x"$enable_cups" != x"no" ; then
851- AC_PROG_SED
852-
853- AC_PATH_PROG(CUPS_CONFIG, cups-config)
854-
855- if test x$CUPS_CONFIG = x; then
856- AC_MSG_ERROR([cups-config not found but CUPS support requested])
857- fi
858-
859- CUPS_API_VERSION=`$CUPS_CONFIG --api-version`
860- CUPS_API_MAJOR=`echo $ECHO_N $CUPS_API_VERSION | cut -d . -f 1`
861- CUPS_API_MINOR=`echo $ECHO_N $CUPS_API_VERSION | cut -d . -f 2`
862-
863- AC_CHECK_HEADERS([cups/cups.h cups/http.h cups/ipp.h],,
864- AC_MSG_ERROR([CUPS headers not found but CUPS support requested]))
865-
866- if ! test $CUPS_API_MAJOR -gt 1 -o \
867- $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -ge 4 ; then
868- AC_MSG_ERROR([CUPS 1.4 or newer not found, but CUPS support requested])
869- fi
870-
871- CUPS_CFLAGS=`$CUPS_CONFIG --cflags | $SED -e 's/-O\w*//g' -e 's/-m\w*//g'`
872- CUPS_LIBS=`$CUPS_CONFIG --libs`
873- AC_SUBST(CUPS_CFLAGS)
874- AC_SUBST(CUPS_LIBS)
875-fi
876-
877-AM_CONDITIONAL(BUILD_PRINT_NOTIFICATIONS, [test x"$enable_cups" = x"yes"])
878-
879-# ---------------------------------------------------------------------------
880-# Enable Profiling
881-# ---------------------------------------------------------------------------
882-AC_ARG_ENABLE(profiling,
883- [AC_HELP_STRING([--enable-profiling],
884- [turn on profiling])],
885- , enable_profiling=no)
886-if test "x$enable_profiling" = "xyes"; then
887- AC_DEFINE(ENABLE_PROFILING,1,[enable profiling])
888-fi
889-
890-
891-# ---------------------------------------------------------------------------
892-# Plugins
893-# ---------------------------------------------------------------------------
894-
895-plugindir='$(libdir)/gnome-settings-daemon-gsd_api_version'
896-AC_SUBST([plugindir])
897-
898-PLUGIN_CFLAGS="-DG_LOG_DOMAIN=\"\\\"\$(plugin_name)-plugin\\\"\" -DPLUGIN_NAME=\"\\\"\$(plugin_name)\\\"\" "
899-AC_SUBST(PLUGIN_CFLAGS)
900-
901-AC_ARG_ENABLE(man,
902- [AS_HELP_STRING([--enable-man],
903- [generate man pages [default=yes]])],,
904- enable_man=yes)
905-if test "$enable_man" != no; then
906- AC_PATH_PROG([XSLTPROC], [xsltproc])
907- if test -z "$XSLTPROC"; then
908- AC_MSG_ERROR([xsltproc is required for --enable-man])
909- fi
910-fi
911-AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no)
912-
913-dnl ---------------------------------------------------------------------------
914-dnl - Finish
915-dnl ---------------------------------------------------------------------------
916-
917-
918-# Turn on the additional warnings last, so warnings don't affect other tests.
919-
920-AC_ARG_ENABLE(more-warnings,
921- [AC_HELP_STRING([--enable-more-warnings],
922- [Maximum compiler warnings])],
923- set_more_warnings="$enableval",[
924- if test -d $srcdir/.git; then
925- set_more_warnings=yes
926- else
927- set_more_warnings=no
928- fi
929- ])
930-AC_MSG_CHECKING(for more warnings)
931-if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
932- AC_MSG_RESULT(yes)
933- CFLAGS="\
934- -Wall \
935- -Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \
936- -Wnested-externs -Wpointer-arith \
937- -Wcast-align -Wsign-compare \
938- $CFLAGS"
939-
940- for option in -Wno-strict-aliasing -Wno-sign-compare; do
941- SAVE_CFLAGS="$CFLAGS"
942- CFLAGS="$CFLAGS $option"
943- AC_MSG_CHECKING([whether gcc understands $option])
944- AC_TRY_COMPILE([], [],
945- has_option=yes,
946- has_option=no,)
947- if test $has_option = no; then
948- CFLAGS="$SAVE_CFLAGS"
949- fi
950- AC_MSG_RESULT($has_option)
951- unset has_option
952- unset SAVE_CFLAGS
953- done
954- unset option
955-else
956- AC_MSG_RESULT(no)
957-fi
958-
959-#
960-# Enable Debug
961-#
962-AC_ARG_ENABLE(debug,
963- [AC_HELP_STRING([--enable-debug],
964- [turn on debugging])],
965- , enable_debug=yes)
966-if test "$enable_debug" = "yes"; then
967- DEBUG_CFLAGS="-DG_ENABLE_DEBUG"
968-else
969- if test "x$enable_debug" = "xno"; then
970- DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS"
971- else
972- DEBUG_CFLAGS=""
973- fi
974-fi
975-AC_SUBST(DEBUG_CFLAGS)
976-
977-AC_OUTPUT([
978-Makefile
979-gnome-settings-daemon/Makefile
980-plugins/Makefile
981-plugins/a11y-keyboard/Makefile
982-plugins/a11y-settings/Makefile
983-plugins/automount/Makefile
984-plugins/background/Makefile
985-plugins/clipboard/Makefile
986-plugins/color/Makefile
987-plugins/common/Makefile
988-plugins/cursor/Makefile
989-plugins/dummy/Makefile
990-plugins/power/Makefile
991-plugins/housekeeping/Makefile
992-plugins/keyboard/Makefile
993-plugins/media-keys/Makefile
994-plugins/media-keys/cut-n-paste/Makefile
995-plugins/mouse/Makefile
996-plugins/orientation/Makefile
997-plugins/print-notifications/Makefile
998-plugins/screensaver-proxy/Makefile
999-plugins/smartcard/Makefile
1000-plugins/sound/Makefile
1001-plugins/updates/Makefile
1002-plugins/wacom/Makefile
1003-plugins/xrandr/Makefile
1004-plugins/xsettings/Makefile
1005-data/Makefile
1006-data/gnome-settings-daemon.pc
1007-data/gnome-settings-daemon-uninstalled.pc
1008-data/org.gnome.settings-daemon.plugins.gschema.xml.in
1009-data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in
1010-data/org.gnome.settings-daemon.plugins.keyboard.gschema.xml.in
1011-data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
1012-data/org.gnome.settings-daemon.plugins.color.gschema.xml.in
1013-data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in
1014-data/org.gnome.settings-daemon.peripherals.gschema.xml.in
1015-data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in
1016-data/org.gnome.settings-daemon.plugins.orientation.gschema.xml.in
1017-data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in
1018-data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in
1019-data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in
1020-data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in
1021-po/Makefile.in
1022-man/Makefile
1023-])
1024-
1025-dnl ---------------------------------------------------------------------------
1026-dnl - Show summary
1027-dnl ---------------------------------------------------------------------------
1028-
1029-echo "
1030- gnome-settings-daemon $VERSION
1031- =============================
1032-
1033- prefix: ${prefix}
1034- exec_prefix: ${exec_prefix}
1035- libdir: ${libdir}
1036- bindir: ${bindir}
1037- sbindir: ${sbindir}
1038- sysconfdir: ${sysconfdir}
1039- sysconfsubdir: ${sysconfsubdir}
1040- localstatedir: ${localstatedir}
1041- plugindir: ${plugindir}
1042- datadir: ${datadir}
1043- source code location: ${srcdir}
1044- compiler: ${CC}
1045- cflags: ${CFLAGS}
1046- Maintainer mode: ${USE_MAINTAINER_MODE}
1047-
1048- Session tracking: ${SESSION_TRACKING}
1049- LCMS DICT support: ${have_new_lcms}
1050- IBus support: ${enable_ibus}
1051- Libnotify support: ${have_libnotify}
1052- App indicator support: ${enable_appindicator}
1053- PackageKit support: ${have_packagekit}
1054- Smartcard support: ${have_smartcard_support}
1055- Cups support: ${enable_cups}
1056- Wacom support: ${have_wacom}
1057-${NSS_DATABASE:+\
1058- System nssdb: ${NSS_DATABASE}
1059-}\
1060- Profiling support: ${enable_profiling}
1061-"
1062
1063=== removed directory '.pc/sync_input_sources_to_accountsservice.patch/plugins'
1064=== removed directory '.pc/sync_input_sources_to_accountsservice.patch/plugins/keyboard'
1065=== removed file '.pc/sync_input_sources_to_accountsservice.patch/plugins/keyboard/gsd-keyboard-manager.c'
1066--- .pc/sync_input_sources_to_accountsservice.patch/plugins/keyboard/gsd-keyboard-manager.c 2013-08-29 16:10:41 +0000
1067+++ .pc/sync_input_sources_to_accountsservice.patch/plugins/keyboard/gsd-keyboard-manager.c 1970-01-01 00:00:00 +0000
1068@@ -1,1708 +0,0 @@
1069-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1070- *
1071- * Copyright © 2001 Ximian, Inc.
1072- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
1073- * Written by Sergey V. Oudaltsov <svu@users.sourceforge.net>
1074- *
1075- * This program is free software; you can redistribute it and/or modify
1076- * it under the terms of the GNU General Public License as published by
1077- * the Free Software Foundation; either version 2 of the License, or
1078- * (at your option) any later version.
1079- *
1080- * This program is distributed in the hope that it will be useful,
1081- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1082- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1083- * GNU General Public License for more details.
1084- *
1085- * You should have received a copy of the GNU General Public License
1086- * along with this program; if not, write to the Free Software
1087- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1088- *
1089- */
1090-
1091-#include "config.h"
1092-
1093-#include <sys/types.h>
1094-#include <sys/wait.h>
1095-#include <stdlib.h>
1096-#include <stdio.h>
1097-#include <unistd.h>
1098-#include <string.h>
1099-#include <errno.h>
1100-
1101-#include <locale.h>
1102-
1103-#include <glib.h>
1104-#include <glib/gi18n.h>
1105-#include <gdk/gdk.h>
1106-#include <gdk/gdkx.h>
1107-#include <gtk/gtk.h>
1108-
1109-#include <X11/XKBlib.h>
1110-#include <X11/keysym.h>
1111-#include <X11/extensions/XKBrules.h>
1112-
1113-#define GNOME_DESKTOP_USE_UNSTABLE_API
1114-#include <libgnome-desktop/gnome-xkb-info.h>
1115-
1116-#ifdef HAVE_IBUS
1117-#include <ibus.h>
1118-#endif
1119-
1120-#include "gnome-settings-profile.h"
1121-#include "gsd-keyboard-manager.h"
1122-#include "gsd-input-helper.h"
1123-#include "gsd-enums.h"
1124-
1125-#define GSD_KEYBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_KEYBOARD_MANAGER, GsdKeyboardManagerPrivate))
1126-
1127-#define GSD_KEYBOARD_DIR "org.gnome.settings-daemon.peripherals.keyboard"
1128-
1129-#define KEY_REPEAT "repeat"
1130-#define KEY_CLICK "click"
1131-#define KEY_INTERVAL "repeat-interval"
1132-#define KEY_DELAY "delay"
1133-#define KEY_CLICK_VOLUME "click-volume"
1134-#define KEY_REMEMBER_NUMLOCK_STATE "remember-numlock-state"
1135-#define KEY_NUMLOCK_STATE "numlock-state"
1136-
1137-#define KEY_BELL_VOLUME "bell-volume"
1138-#define KEY_BELL_PITCH "bell-pitch"
1139-#define KEY_BELL_DURATION "bell-duration"
1140-#define KEY_BELL_MODE "bell-mode"
1141-
1142-#define KEY_SWITCHER "input-sources-switcher"
1143-
1144-#define GNOME_DESKTOP_INTERFACE_DIR "org.gnome.desktop.interface"
1145-
1146-#define KEY_GTK_IM_MODULE "gtk-im-module"
1147-#define GTK_IM_MODULE_SIMPLE "gtk-im-context-simple"
1148-#define GTK_IM_MODULE_IBUS "ibus"
1149-
1150-#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
1151-
1152-#define KEY_CURRENT_INPUT_SOURCE "current"
1153-#define KEY_INPUT_SOURCES "sources"
1154-#define KEY_KEYBOARD_OPTIONS "xkb-options"
1155-
1156-#define INPUT_SOURCE_TYPE_XKB "xkb"
1157-#define INPUT_SOURCE_TYPE_IBUS "ibus"
1158-
1159-#define DEFAULT_LANGUAGE "en_US"
1160-
1161-struct GsdKeyboardManagerPrivate
1162-{
1163- guint start_idle_id;
1164- GSettings *settings;
1165- GSettings *input_sources_settings;
1166- GSettings *interface_settings;
1167- GnomeXkbInfo *xkb_info;
1168-#ifdef HAVE_IBUS
1169- IBusBus *ibus;
1170- GHashTable *ibus_engines;
1171- GHashTable *ibus_xkb_engines;
1172- GCancellable *ibus_cancellable;
1173- gboolean session_is_fallback;
1174-#endif
1175- gint xkb_event_base;
1176- GsdNumLockState old_state;
1177- GdkDeviceManager *device_manager;
1178- guint device_added_id;
1179- guint device_removed_id;
1180-
1181- gboolean input_sources_switcher_spawned;
1182- GPid input_sources_switcher_pid;
1183-};
1184-
1185-static void gsd_keyboard_manager_class_init (GsdKeyboardManagerClass *klass);
1186-static void gsd_keyboard_manager_init (GsdKeyboardManager *keyboard_manager);
1187-static void gsd_keyboard_manager_finalize (GObject *object);
1188-static gboolean apply_input_sources_settings (GSettings *settings,
1189- gpointer keys,
1190- gint n_keys,
1191- GsdKeyboardManager *manager);
1192-static void set_gtk_im_module (GsdKeyboardManager *manager,
1193- const gchar *new_module);
1194-
1195-G_DEFINE_TYPE (GsdKeyboardManager, gsd_keyboard_manager, G_TYPE_OBJECT)
1196-
1197-static gpointer manager_object = NULL;
1198-
1199-static void
1200-init_builder_with_sources (GVariantBuilder *builder,
1201- GSettings *settings)
1202-{
1203- const gchar *type;
1204- const gchar *id;
1205- GVariantIter iter;
1206- GVariant *sources;
1207-
1208- sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
1209-
1210- g_variant_builder_init (builder, G_VARIANT_TYPE ("a(ss)"));
1211-
1212- g_variant_iter_init (&iter, sources);
1213- while (g_variant_iter_next (&iter, "(&s&s)", &type, &id))
1214- g_variant_builder_add (builder, "(ss)", type, id);
1215-
1216- g_variant_unref (sources);
1217-}
1218-
1219-static gboolean
1220-schema_is_installed (const gchar *name)
1221-{
1222- const gchar * const *schemas;
1223- const gchar * const *s;
1224-
1225- schemas = g_settings_list_schemas ();
1226- for (s = schemas; *s; ++s)
1227- if (g_str_equal (*s, name))
1228- return TRUE;
1229-
1230- return FALSE;
1231-}
1232-
1233-#ifdef HAVE_IBUS
1234-static void
1235-clear_ibus (GsdKeyboardManager *manager)
1236-{
1237- GsdKeyboardManagerPrivate *priv = manager->priv;
1238-
1239- g_cancellable_cancel (priv->ibus_cancellable);
1240- g_clear_object (&priv->ibus_cancellable);
1241- g_clear_pointer (&priv->ibus_engines, g_hash_table_destroy);
1242- g_clear_pointer (&priv->ibus_xkb_engines, g_hash_table_destroy);
1243- g_clear_object (&priv->ibus);
1244-}
1245-
1246-static gchar *
1247-make_xkb_source_id (const gchar *engine_id)
1248-{
1249- gchar *id;
1250- gchar *p;
1251- gint n_colons = 0;
1252-
1253- /* engine_id is like "xkb:layout:variant:lang" where
1254- * 'variant' and 'lang' might be empty */
1255-
1256- engine_id += 4;
1257-
1258- for (p = (gchar *)engine_id; *p; ++p)
1259- if (*p == ':')
1260- if (++n_colons == 2)
1261- break;
1262- if (!*p)
1263- return NULL;
1264-
1265- id = g_strndup (engine_id, p - engine_id + 1);
1266-
1267- id[p - engine_id] = '\0';
1268-
1269- /* id is "layout:variant" where 'variant' might be empty */
1270-
1271- for (p = id; *p; ++p)
1272- if (*p == ':') {
1273- if (*(p + 1) == '\0')
1274- *p = '\0';
1275- else
1276- *p = '+';
1277- break;
1278- }
1279-
1280- /* id is "layout+variant" or "layout" */
1281-
1282- return id;
1283-}
1284-
1285-static void
1286-fetch_ibus_engines_result (GObject *object,
1287- GAsyncResult *result,
1288- GsdKeyboardManager *manager)
1289-{
1290- GsdKeyboardManagerPrivate *priv = manager->priv;
1291- GList *list, *l;
1292- GError *error = NULL;
1293-
1294- /* engines shouldn't be there yet */
1295- g_return_if_fail (priv->ibus_engines == NULL);
1296-
1297- g_clear_object (&priv->ibus_cancellable);
1298-
1299- list = ibus_bus_list_engines_async_finish (priv->ibus,
1300- result,
1301- &error);
1302- if (!list && error) {
1303- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1304- g_warning ("Couldn't finish IBus request: %s", error->message);
1305- g_error_free (error);
1306-
1307- clear_ibus (manager);
1308- return;
1309- }
1310-
1311- /* Maps IBus engine ids to engine description objects */
1312- priv->ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
1313- /* Maps XKB source id strings to engine description objects */
1314- priv->ibus_xkb_engines = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1315-
1316- for (l = list; l; l = l->next) {
1317- IBusEngineDesc *engine = l->data;
1318- const gchar *engine_id = ibus_engine_desc_get_name (engine);
1319-
1320- g_hash_table_replace (priv->ibus_engines, (gpointer)engine_id, engine);
1321-
1322- if (strncmp ("xkb:", engine_id, 4) == 0) {
1323- gchar *xkb_source_id = make_xkb_source_id (engine_id);
1324- if (xkb_source_id)
1325- g_hash_table_replace (priv->ibus_xkb_engines,
1326- xkb_source_id,
1327- engine);
1328- }
1329- }
1330- g_list_free (list);
1331-
1332- apply_input_sources_settings (priv->input_sources_settings, NULL, 0, manager);
1333-}
1334-
1335-static void
1336-fetch_ibus_engines (GsdKeyboardManager *manager)
1337-{
1338- GsdKeyboardManagerPrivate *priv = manager->priv;
1339-
1340- /* engines shouldn't be there yet */
1341- g_return_if_fail (priv->ibus_engines == NULL);
1342- g_return_if_fail (priv->ibus_cancellable == NULL);
1343-
1344- priv->ibus_cancellable = g_cancellable_new ();
1345-
1346- ibus_bus_list_engines_async (priv->ibus,
1347- -1,
1348- priv->ibus_cancellable,
1349- (GAsyncReadyCallback)fetch_ibus_engines_result,
1350- manager);
1351-}
1352-
1353-static void
1354-maybe_start_ibus (GsdKeyboardManager *manager,
1355- GVariant *sources)
1356-{
1357- gboolean need_ibus = FALSE;
1358- GVariantIter iter;
1359- const gchar *type;
1360-
1361- if (manager->priv->session_is_fallback)
1362- return;
1363-
1364- g_variant_iter_init (&iter, sources);
1365- while (g_variant_iter_next (&iter, "(&s&s)", &type, NULL))
1366- if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
1367- need_ibus = TRUE;
1368- break;
1369- }
1370-
1371- if (!need_ibus)
1372- return;
1373-
1374- if (!manager->priv->ibus) {
1375- ibus_init ();
1376- manager->priv->ibus = ibus_bus_new_async ();
1377- g_signal_connect_swapped (manager->priv->ibus, "connected",
1378- G_CALLBACK (fetch_ibus_engines), manager);
1379- g_signal_connect_swapped (manager->priv->ibus, "disconnected",
1380- G_CALLBACK (clear_ibus), manager);
1381- }
1382- /* IBus doesn't export API in the session bus. The only thing
1383- * we have there is a well known name which we can use as a
1384- * sure-fire way to activate it. */
1385- g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION,
1386- IBUS_SERVICE_IBUS,
1387- G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
1388- NULL,
1389- NULL,
1390- NULL,
1391- NULL));
1392-}
1393-
1394-static void
1395-got_session_name (GObject *object,
1396- GAsyncResult *res,
1397- GsdKeyboardManager *manager)
1398-{
1399- GVariant *result, *variant;
1400- GDBusConnection *connection = G_DBUS_CONNECTION (object);
1401- GsdKeyboardManagerPrivate *priv = manager->priv;
1402- const gchar *session_name = NULL;
1403- GError *error = NULL;
1404-
1405- /* IBus shouldn't have been touched yet */
1406- g_return_if_fail (priv->ibus == NULL);
1407-
1408- g_clear_object (&priv->ibus_cancellable);
1409-
1410- result = g_dbus_connection_call_finish (connection, res, &error);
1411- if (!result) {
1412- g_warning ("Couldn't get session name: %s", error->message);
1413- g_error_free (error);
1414- goto out;
1415- }
1416-
1417- g_variant_get (result, "(v)", &variant);
1418- g_variant_unref (result);
1419-
1420- g_variant_get (variant, "&s", &session_name);
1421-
1422- if (g_strcmp0 (session_name, "gnome") == 0 || g_strcmp0 (session_name, "ubuntu") == 0)
1423- manager->priv->session_is_fallback = FALSE;
1424-
1425- g_variant_unref (variant);
1426- out:
1427- apply_input_sources_settings (manager->priv->input_sources_settings, NULL, 0, manager);
1428- g_object_unref (connection);
1429-}
1430-
1431-static void
1432-got_bus (GObject *object,
1433- GAsyncResult *res,
1434- GsdKeyboardManager *manager)
1435-{
1436- GDBusConnection *connection;
1437- GsdKeyboardManagerPrivate *priv = manager->priv;
1438- GError *error = NULL;
1439-
1440- /* IBus shouldn't have been touched yet */
1441- g_return_if_fail (priv->ibus == NULL);
1442-
1443- g_clear_object (&priv->ibus_cancellable);
1444-
1445- connection = g_bus_get_finish (res, &error);
1446- if (!connection) {
1447- g_warning ("Couldn't get session bus: %s", error->message);
1448- g_error_free (error);
1449- apply_input_sources_settings (priv->input_sources_settings, NULL, 0, manager);
1450- return;
1451- }
1452-
1453- priv->ibus_cancellable = g_cancellable_new ();
1454-
1455- g_dbus_connection_call (connection,
1456- "org.gnome.SessionManager",
1457- "/org/gnome/SessionManager",
1458- "org.freedesktop.DBus.Properties",
1459- "Get",
1460- g_variant_new ("(ss)",
1461- "org.gnome.SessionManager",
1462- "SessionName"),
1463- NULL,
1464- G_DBUS_CALL_FLAGS_NONE,
1465- -1,
1466- priv->ibus_cancellable,
1467- (GAsyncReadyCallback)got_session_name,
1468- manager);
1469-}
1470-
1471-static void
1472-set_ibus_engine_finish (GObject *object,
1473- GAsyncResult *res,
1474- GsdKeyboardManager *manager)
1475-{
1476- gboolean result;
1477- IBusBus *ibus = IBUS_BUS (object);
1478- GsdKeyboardManagerPrivate *priv = manager->priv;
1479- GError *error = NULL;
1480-
1481- g_clear_object (&priv->ibus_cancellable);
1482-
1483- result = ibus_bus_set_global_engine_async_finish (ibus, res, &error);
1484- if (!result) {
1485- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1486- g_warning ("Couldn't set IBus engine: %s", error->message);
1487- g_error_free (error);
1488- }
1489-}
1490-
1491-static void
1492-set_ibus_engine (GsdKeyboardManager *manager,
1493- const gchar *engine_id)
1494-{
1495- GsdKeyboardManagerPrivate *priv = manager->priv;
1496-
1497- g_return_if_fail (priv->ibus != NULL);
1498- g_return_if_fail (priv->ibus_engines != NULL);
1499-
1500- g_cancellable_cancel (priv->ibus_cancellable);
1501- g_clear_object (&priv->ibus_cancellable);
1502- priv->ibus_cancellable = g_cancellable_new ();
1503-
1504- ibus_bus_set_global_engine_async (priv->ibus,
1505- engine_id,
1506- -1,
1507- priv->ibus_cancellable,
1508- (GAsyncReadyCallback)set_ibus_engine_finish,
1509- manager);
1510-}
1511-
1512-static void
1513-set_ibus_xkb_engine (GsdKeyboardManager *manager,
1514- const gchar *xkb_id)
1515-{
1516- IBusEngineDesc *engine;
1517- GsdKeyboardManagerPrivate *priv = manager->priv;
1518-
1519- if (!priv->ibus_xkb_engines)
1520- return;
1521-
1522- engine = g_hash_table_lookup (priv->ibus_xkb_engines, xkb_id);
1523- if (!engine)
1524- return;
1525-
1526- set_ibus_engine (manager, ibus_engine_desc_get_name (engine));
1527-}
1528-
1529-/* XXX: See upstream bug:
1530- * https://codereview.appspot.com/6586075/ */
1531-static gchar *
1532-layout_from_ibus_layout (const gchar *ibus_layout)
1533-{
1534- const gchar *p;
1535-
1536- /* we get something like "layout(variant)[option1,option2]" */
1537-
1538- p = ibus_layout;
1539- while (*p) {
1540- if (*p == '(' || *p == '[')
1541- break;
1542- p += 1;
1543- }
1544-
1545- return g_strndup (ibus_layout, p - ibus_layout);
1546-}
1547-
1548-static gchar *
1549-variant_from_ibus_layout (const gchar *ibus_layout)
1550-{
1551- const gchar *a, *b;
1552-
1553- /* we get something like "layout(variant)[option1,option2]" */
1554-
1555- a = ibus_layout;
1556- while (*a) {
1557- if (*a == '(')
1558- break;
1559- a += 1;
1560- }
1561- if (!*a)
1562- return NULL;
1563-
1564- a += 1;
1565- b = a;
1566- while (*b) {
1567- if (*b == ')')
1568- break;
1569- b += 1;
1570- }
1571- if (!*b)
1572- return NULL;
1573-
1574- return g_strndup (a, b - a);
1575-}
1576-
1577-static gchar **
1578-options_from_ibus_layout (const gchar *ibus_layout)
1579-{
1580- const gchar *a, *b;
1581- GPtrArray *opt_array;
1582-
1583- /* we get something like "layout(variant)[option1,option2]" */
1584-
1585- a = ibus_layout;
1586- while (*a) {
1587- if (*a == '[')
1588- break;
1589- a += 1;
1590- }
1591- if (!*a)
1592- return NULL;
1593-
1594- opt_array = g_ptr_array_new ();
1595-
1596- do {
1597- a += 1;
1598- b = a;
1599- while (*b) {
1600- if (*b == ',' || *b == ']')
1601- break;
1602- b += 1;
1603- }
1604- if (!*b)
1605- goto out;
1606-
1607- g_ptr_array_add (opt_array, g_strndup (a, b - a));
1608-
1609- a = b;
1610- } while (*a && *a == ',');
1611-
1612-out:
1613- g_ptr_array_add (opt_array, NULL);
1614- return (gchar **) g_ptr_array_free (opt_array, FALSE);
1615-}
1616-
1617-static const gchar *
1618-engine_from_locale (void)
1619-{
1620- const gchar *locale;
1621- const gchar *locale_engine[][2] = {
1622- { "as_IN", "m17n:as:phonetic" },
1623- { "bn_IN", "m17n:bn:inscript" },
1624- { "gu_IN", "m17n:gu:inscript" },
1625- { "hi_IN", "m17n:hi:inscript" },
1626- { "ja_JP", "anthy" },
1627- { "kn_IN", "m17n:kn:kgp" },
1628- { "ko_KR", "hangul" },
1629- { "mai_IN", "m17n:mai:inscript" },
1630- { "ml_IN", "m17n:ml:inscript" },
1631- { "mr_IN", "m17n:mr:inscript" },
1632- { "or_IN", "m17n:or:inscript" },
1633- { "pa_IN", "m17n:pa:inscript" },
1634- { "sd_IN", "m17n:sd:inscript" },
1635- { "ta_IN", "m17n:ta:tamil99" },
1636- { "te_IN", "m17n:te:inscript" },
1637- { "zh_CN", "pinyin" },
1638- { "zh_HK", "cangjie3" },
1639- { "zh_TW", "chewing" },
1640- };
1641- gint i;
1642-
1643- locale = setlocale (LC_CTYPE, NULL);
1644- if (!locale)
1645- return NULL;
1646-
1647- for (i = 0; i < G_N_ELEMENTS (locale_engine); ++i)
1648- if (g_str_has_prefix (locale, locale_engine[i][0]))
1649- return locale_engine[i][1];
1650-
1651- return NULL;
1652-}
1653-
1654-static void
1655-add_ibus_sources_from_locale (GSettings *settings)
1656-{
1657- const gchar *locale_engine;
1658- GVariantBuilder builder;
1659-
1660- locale_engine = engine_from_locale ();
1661- if (!locale_engine)
1662- return;
1663-
1664- init_builder_with_sources (&builder, settings);
1665- g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_IBUS, locale_engine);
1666- g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
1667-}
1668-
1669-static void
1670-convert_ibus (GSettings *settings)
1671-{
1672- GVariantBuilder builder;
1673- GSettings *ibus_settings;
1674- gchar **engines, **e;
1675-
1676- if (!schema_is_installed ("org.freedesktop.ibus.general"))
1677- return;
1678-
1679- init_builder_with_sources (&builder, settings);
1680-
1681- ibus_settings = g_settings_new ("org.freedesktop.ibus.general");
1682- engines = g_settings_get_strv (ibus_settings, "preload-engines");
1683- for (e = engines; *e; ++e) {
1684- if (g_str_has_prefix (*e, "xkb:"))
1685- continue;
1686- g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_IBUS, *e);
1687- }
1688-
1689- g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
1690-
1691- g_strfreev (engines);
1692- g_object_unref (ibus_settings);
1693-}
1694-#endif /* HAVE_IBUS */
1695-
1696-static gboolean
1697-xkb_set_keyboard_autorepeat_rate (guint delay, guint interval)
1698-{
1699- return XkbSetAutoRepeatRate (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
1700- XkbUseCoreKbd,
1701- delay,
1702- interval);
1703-}
1704-
1705-static gboolean
1706-check_xkb_extension (GsdKeyboardManager *manager)
1707-{
1708- Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
1709- int opcode, error_base, major, minor;
1710- gboolean have_xkb;
1711-
1712- have_xkb = XkbQueryExtension (dpy,
1713- &opcode,
1714- &manager->priv->xkb_event_base,
1715- &error_base,
1716- &major,
1717- &minor);
1718- return have_xkb;
1719-}
1720-
1721-static void
1722-xkb_init (GsdKeyboardManager *manager)
1723-{
1724- Display *dpy;
1725-
1726- dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
1727- XkbSelectEventDetails (dpy,
1728- XkbUseCoreKbd,
1729- XkbStateNotify,
1730- XkbModifierLockMask,
1731- XkbModifierLockMask);
1732-}
1733-
1734-static unsigned
1735-numlock_NumLock_modifier_mask (void)
1736-{
1737- Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
1738- return XkbKeysymToModifiers (dpy, XK_Num_Lock);
1739-}
1740-
1741-static void
1742-numlock_set_xkb_state (GsdNumLockState new_state)
1743-{
1744- unsigned int num_mask;
1745- Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
1746- if (new_state != GSD_NUM_LOCK_STATE_ON && new_state != GSD_NUM_LOCK_STATE_OFF)
1747- return;
1748- num_mask = numlock_NumLock_modifier_mask ();
1749- XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state == GSD_NUM_LOCK_STATE_ON ? num_mask : 0);
1750-}
1751-
1752-static const char *
1753-num_lock_state_to_string (GsdNumLockState numlock_state)
1754-{
1755- switch (numlock_state) {
1756- case GSD_NUM_LOCK_STATE_UNKNOWN:
1757- return "GSD_NUM_LOCK_STATE_UNKNOWN";
1758- case GSD_NUM_LOCK_STATE_ON:
1759- return "GSD_NUM_LOCK_STATE_ON";
1760- case GSD_NUM_LOCK_STATE_OFF:
1761- return "GSD_NUM_LOCK_STATE_OFF";
1762- default:
1763- return "UNKNOWN";
1764- }
1765-}
1766-
1767-static GdkFilterReturn
1768-xkb_events_filter (GdkXEvent *xev_,
1769- GdkEvent *gdkev_,
1770- gpointer user_data)
1771-{
1772- XEvent *xev = (XEvent *) xev_;
1773- XkbEvent *xkbev = (XkbEvent *) xev;
1774- GsdKeyboardManager *manager = (GsdKeyboardManager *) user_data;
1775-
1776- if (xev->type != manager->priv->xkb_event_base ||
1777- xkbev->any.xkb_type != XkbStateNotify)
1778- return GDK_FILTER_CONTINUE;
1779-
1780- if (xkbev->state.changed & XkbModifierLockMask) {
1781- unsigned num_mask = numlock_NumLock_modifier_mask ();
1782- unsigned locked_mods = xkbev->state.locked_mods;
1783- GsdNumLockState numlock_state;
1784-
1785- numlock_state = (num_mask & locked_mods) ? GSD_NUM_LOCK_STATE_ON : GSD_NUM_LOCK_STATE_OFF;
1786-
1787- if (numlock_state != manager->priv->old_state) {
1788- g_debug ("New num-lock state '%s' != Old num-lock state '%s'",
1789- num_lock_state_to_string (numlock_state),
1790- num_lock_state_to_string (manager->priv->old_state));
1791- g_settings_set_enum (manager->priv->settings,
1792- KEY_NUMLOCK_STATE,
1793- numlock_state);
1794- manager->priv->old_state = numlock_state;
1795- }
1796- }
1797-
1798- return GDK_FILTER_CONTINUE;
1799-}
1800-
1801-static void
1802-install_xkb_filter (GsdKeyboardManager *manager)
1803-{
1804- gdk_window_add_filter (NULL,
1805- xkb_events_filter,
1806- manager);
1807-}
1808-
1809-static void
1810-remove_xkb_filter (GsdKeyboardManager *manager)
1811-{
1812- gdk_window_remove_filter (NULL,
1813- xkb_events_filter,
1814- manager);
1815-}
1816-
1817-static void
1818-free_xkb_component_names (XkbComponentNamesRec *p)
1819-{
1820- g_return_if_fail (p != NULL);
1821-
1822- free (p->keymap);
1823- free (p->keycodes);
1824- free (p->types);
1825- free (p->compat);
1826- free (p->symbols);
1827- free (p->geometry);
1828-
1829- g_free (p);
1830-}
1831-
1832-static void
1833-upload_xkb_description (const gchar *rules_file_path,
1834- XkbRF_VarDefsRec *var_defs,
1835- XkbComponentNamesRec *comp_names)
1836-{
1837- Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
1838- XkbDescRec *xkb_desc;
1839- gchar *rules_file;
1840-
1841- /* Upload it to the X server using the same method as setxkbmap */
1842- xkb_desc = XkbGetKeyboardByName (display,
1843- XkbUseCoreKbd,
1844- comp_names,
1845- XkbGBN_AllComponentsMask,
1846- XkbGBN_AllComponentsMask &
1847- (~XkbGBN_GeometryMask), True);
1848- if (!xkb_desc) {
1849- g_warning ("Couldn't upload new XKB keyboard description");
1850- return;
1851- }
1852-
1853- XkbFreeKeyboard (xkb_desc, 0, True);
1854-
1855- rules_file = g_path_get_basename (rules_file_path);
1856-
1857- if (!XkbRF_SetNamesProp (display, rules_file, var_defs))
1858- g_warning ("Couldn't update the XKB root window property");
1859-
1860- g_free (rules_file);
1861-}
1862-
1863-static gchar *
1864-language_code_from_locale (const gchar *locale)
1865-{
1866- if (!locale || !locale[0] || !locale[1])
1867- return NULL;
1868-
1869- if (!locale[2] || locale[2] == '_' || locale[2] == '.')
1870- return g_strndup (locale, 2);
1871-
1872- if (!locale[3] || locale[3] == '_' || locale[3] == '.')
1873- return g_strndup (locale, 3);
1874-
1875- return NULL;
1876-}
1877-
1878-static gchar *
1879-build_xkb_group_string (const gchar *user,
1880- const gchar *locale,
1881- const gchar *latin)
1882-{
1883- gchar *string;
1884- gsize length = 0;
1885- guint commas = 2;
1886-
1887- if (latin)
1888- length += strlen (latin);
1889- else
1890- commas -= 1;
1891-
1892- if (locale)
1893- length += strlen (locale);
1894- else
1895- commas -= 1;
1896-
1897- length += strlen (user) + commas + 1;
1898-
1899- string = malloc (length);
1900-
1901- if (locale && latin)
1902- sprintf (string, "%s,%s,%s", user, locale, latin);
1903- else if (locale)
1904- sprintf (string, "%s,%s", user, locale);
1905- else if (latin)
1906- sprintf (string, "%s,%s", user, latin);
1907- else
1908- sprintf (string, "%s", user);
1909-
1910- return string;
1911-}
1912-
1913-static gboolean
1914-layout_equal (const gchar *layout_a,
1915- const gchar *variant_a,
1916- const gchar *layout_b,
1917- const gchar *variant_b)
1918-{
1919- return !g_strcmp0 (layout_a, layout_b) && !g_strcmp0 (variant_a, variant_b);
1920-}
1921-
1922-static void
1923-replace_layout_and_variant (GsdKeyboardManager *manager,
1924- XkbRF_VarDefsRec *xkb_var_defs,
1925- const gchar *layout,
1926- const gchar *variant)
1927-{
1928- /* Toolkits need to know about both a latin layout to handle
1929- * accelerators which are usually defined like Ctrl+C and a
1930- * layout with the symbols for the language used in UI strings
1931- * to handle mnemonics like Alt+Ф, so we try to find and add
1932- * them in XKB group slots after the layout which the user
1933- * actually intends to type with. */
1934- const gchar *latin_layout = "us";
1935- const gchar *latin_variant = "";
1936- const gchar *locale_layout = NULL;
1937- const gchar *locale_variant = NULL;
1938- const gchar *locale;
1939- gchar *language;
1940-
1941- if (!layout)
1942- return;
1943-
1944- if (!variant)
1945- variant = "";
1946-
1947- locale = setlocale (LC_MESSAGES, NULL);
1948- /* If LANG is empty, default to en_US */
1949- if (!locale)
1950- language = g_strdup (DEFAULT_LANGUAGE);
1951- else
1952- language = language_code_from_locale (locale);
1953-
1954- if (!language)
1955- language = language_code_from_locale (DEFAULT_LANGUAGE);
1956-
1957- gnome_xkb_info_get_layout_info_for_language (manager->priv->xkb_info,
1958- language,
1959- NULL,
1960- NULL,
1961- NULL,
1962- &locale_layout,
1963- &locale_variant);
1964- g_free (language);
1965-
1966- /* We want to minimize the number of XKB groups if we have
1967- * duplicated layout+variant pairs.
1968- *
1969- * Also, if a layout doesn't have a variant we still have to
1970- * include it in the variants string because the number of
1971- * variants must agree with the number of layouts. For
1972- * instance:
1973- *
1974- * layouts: "us,ru,us"
1975- * variants: "dvorak,,"
1976- */
1977- if (layout_equal (latin_layout, latin_variant, locale_layout, locale_variant) ||
1978- layout_equal (latin_layout, latin_variant, layout, variant)) {
1979- latin_layout = NULL;
1980- latin_variant = NULL;
1981- }
1982-
1983- if (layout_equal (locale_layout, locale_variant, layout, variant)) {
1984- locale_layout = NULL;
1985- locale_variant = NULL;
1986- }
1987-
1988- free (xkb_var_defs->layout);
1989- xkb_var_defs->layout = build_xkb_group_string (layout, locale_layout, latin_layout);
1990-
1991- free (xkb_var_defs->variant);
1992- xkb_var_defs->variant = build_xkb_group_string (variant, locale_variant, latin_variant);
1993-}
1994-
1995-static gchar *
1996-build_xkb_options_string (gchar **options)
1997-{
1998- gchar *string;
1999-
2000- if (*options) {
2001- gint i;
2002- gsize len;
2003- gchar *ptr;
2004-
2005- /* First part, getting length */
2006- len = 1 + strlen (options[0]);
2007- for (i = 1; options[i] != NULL; i++)
2008- len += strlen (options[i]);
2009- len += (i - 1); /* commas */
2010-
2011- /* Second part, building string */
2012- string = malloc (len);
2013- ptr = g_stpcpy (string, *options);
2014- for (i = 1; options[i] != NULL; i++) {
2015- ptr = g_stpcpy (ptr, ",");
2016- ptr = g_stpcpy (ptr, options[i]);
2017- }
2018- } else {
2019- string = malloc (1);
2020- *string = '\0';
2021- }
2022-
2023- return string;
2024-}
2025-
2026-static gchar **
2027-append_options (gchar **a,
2028- gchar **b)
2029-{
2030- gchar **c, **p;
2031-
2032- if (!a && !b)
2033- return NULL;
2034- else if (!a)
2035- return g_strdupv (b);
2036- else if (!b)
2037- return g_strdupv (a);
2038-
2039- c = g_new0 (gchar *, g_strv_length (a) + g_strv_length (b) + 1);
2040- p = c;
2041-
2042- while (*a) {
2043- *p = g_strdup (*a);
2044- p += 1;
2045- a += 1;
2046- }
2047- while (*b) {
2048- *p = g_strdup (*b);
2049- p += 1;
2050- b += 1;
2051- }
2052-
2053- return c;
2054-}
2055-
2056-static void
2057-add_xkb_options (GsdKeyboardManager *manager,
2058- XkbRF_VarDefsRec *xkb_var_defs,
2059- gchar **extra_options)
2060-{
2061- gchar **options;
2062- gchar **settings_options;
2063-
2064- settings_options = g_settings_get_strv (manager->priv->input_sources_settings,
2065- KEY_KEYBOARD_OPTIONS);
2066- options = append_options (settings_options, extra_options);
2067- g_strfreev (settings_options);
2068-
2069- free (xkb_var_defs->options);
2070- xkb_var_defs->options = build_xkb_options_string (options);
2071-
2072- g_strfreev (options);
2073-}
2074-
2075-static void
2076-apply_xkb_settings (GsdKeyboardManager *manager,
2077- const gchar *layout,
2078- const gchar *variant,
2079- gchar **options)
2080-{
2081- XkbRF_RulesRec *xkb_rules;
2082- XkbRF_VarDefsRec *xkb_var_defs;
2083- gchar *rules_file_path;
2084-
2085- gnome_xkb_info_get_var_defs (&rules_file_path, &xkb_var_defs);
2086-
2087- add_xkb_options (manager, xkb_var_defs, options);
2088- replace_layout_and_variant (manager, xkb_var_defs, layout, variant);
2089-
2090- gdk_error_trap_push ();
2091-
2092- xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True);
2093- if (xkb_rules) {
2094- XkbComponentNamesRec *xkb_comp_names;
2095- xkb_comp_names = g_new0 (XkbComponentNamesRec, 1);
2096-
2097- XkbRF_GetComponents (xkb_rules, xkb_var_defs, xkb_comp_names);
2098- upload_xkb_description (rules_file_path, xkb_var_defs, xkb_comp_names);
2099-
2100- free_xkb_component_names (xkb_comp_names);
2101- XkbRF_Free (xkb_rules, True);
2102- } else {
2103- g_warning ("Couldn't load XKB rules");
2104- }
2105-
2106- if (gdk_error_trap_pop ())
2107- g_warning ("Error loading XKB rules");
2108-
2109- gnome_xkb_info_free_var_defs (xkb_var_defs);
2110- g_free (rules_file_path);
2111-}
2112-
2113-static void
2114-set_gtk_im_module (GsdKeyboardManager *manager,
2115- const gchar *new_module)
2116-{
2117- GsdKeyboardManagerPrivate *priv = manager->priv;
2118- gchar *current_module;
2119-
2120- current_module = g_settings_get_string (priv->interface_settings,
2121- KEY_GTK_IM_MODULE);
2122- if (!g_str_equal (current_module, new_module))
2123- g_settings_set_string (priv->interface_settings,
2124- KEY_GTK_IM_MODULE,
2125- new_module);
2126- g_free (current_module);
2127-}
2128-
2129-static gboolean
2130-apply_input_sources_settings (GSettings *settings,
2131- gpointer keys,
2132- gint n_keys,
2133- GsdKeyboardManager *manager)
2134-{
2135- GsdKeyboardManagerPrivate *priv = manager->priv;
2136- GVariant *sources;
2137- guint current;
2138- guint n_sources;
2139- const gchar *type = NULL;
2140- const gchar *id = NULL;
2141- gchar *layout = NULL;
2142- gchar *variant = NULL;
2143- gchar **options = NULL;
2144-
2145- sources = g_settings_get_value (priv->input_sources_settings, KEY_INPUT_SOURCES);
2146- current = g_settings_get_uint (priv->input_sources_settings, KEY_CURRENT_INPUT_SOURCE);
2147- n_sources = g_variant_n_children (sources);
2148-
2149- if (n_sources < 1)
2150- goto exit;
2151-
2152- if (current >= n_sources) {
2153- g_settings_set_uint (priv->input_sources_settings,
2154- KEY_CURRENT_INPUT_SOURCE,
2155- n_sources - 1);
2156- goto exit;
2157- }
2158-
2159-#ifdef HAVE_IBUS
2160- maybe_start_ibus (manager, sources);
2161-#endif
2162-
2163- g_variant_get_child (sources, current, "(&s&s)", &type, &id);
2164-
2165- if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) {
2166- const gchar *l, *v;
2167- gnome_xkb_info_get_layout_info (priv->xkb_info, id, NULL, NULL, &l, &v);
2168-
2169- layout = g_strdup (l);
2170- variant = g_strdup (v);
2171-
2172- if (!layout || !layout[0]) {
2173- g_warning ("Couldn't find XKB input source '%s'", id);
2174- goto exit;
2175- }
2176- set_gtk_im_module (manager, GTK_IM_MODULE_SIMPLE);
2177-#ifdef HAVE_IBUS
2178- set_ibus_xkb_engine (manager, id);
2179-#endif
2180- } else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
2181-#ifdef HAVE_IBUS
2182- IBusEngineDesc *engine_desc = NULL;
2183-
2184- if (priv->session_is_fallback)
2185- goto exit;
2186-
2187- if (priv->ibus_engines)
2188- engine_desc = g_hash_table_lookup (priv->ibus_engines, id);
2189- else
2190- goto exit; /* we'll be called again when ibus is up and running */
2191-
2192- if (engine_desc) {
2193- const gchar *ibus_layout;
2194- ibus_layout = ibus_engine_desc_get_layout (engine_desc);
2195-
2196- if (ibus_layout) {
2197- layout = layout_from_ibus_layout (ibus_layout);
2198- variant = variant_from_ibus_layout (ibus_layout);
2199- options = options_from_ibus_layout (ibus_layout);
2200- }
2201- } else {
2202- g_warning ("Couldn't find IBus input source '%s'", id);
2203- goto exit;
2204- }
2205-
2206- set_gtk_im_module (manager, GTK_IM_MODULE_IBUS);
2207- set_ibus_engine (manager, id);
2208-#else
2209- g_warning ("IBus input source type specified but IBus support was not compiled");
2210-#endif
2211- } else {
2212- g_warning ("Unknown input source type '%s'", type);
2213- }
2214-
2215- exit:
2216- apply_xkb_settings (manager, layout, variant, options);
2217- g_variant_unref (sources);
2218- g_free (layout);
2219- g_free (variant);
2220- g_strfreev (options);
2221- /* Prevent individual "changed" signal invocations since we
2222- don't need them. */
2223- return TRUE;
2224-}
2225-
2226-static void
2227-apply_bell (GsdKeyboardManager *manager)
2228-{
2229- GSettings *settings;
2230- XKeyboardControl kbdcontrol;
2231- gboolean click;
2232- int bell_volume;
2233- int bell_pitch;
2234- int bell_duration;
2235- GsdBellMode bell_mode;
2236- int click_volume;
2237-
2238- g_debug ("Applying the bell settings");
2239- settings = manager->priv->settings;
2240- click = g_settings_get_boolean (settings, KEY_CLICK);
2241- click_volume = g_settings_get_int (settings, KEY_CLICK_VOLUME);
2242-
2243- bell_pitch = g_settings_get_int (settings, KEY_BELL_PITCH);
2244- bell_duration = g_settings_get_int (settings, KEY_BELL_DURATION);
2245-
2246- bell_mode = g_settings_get_enum (settings, KEY_BELL_MODE);
2247- bell_volume = (bell_mode == GSD_BELL_MODE_ON) ? 50 : 0;
2248-
2249- /* as percentage from 0..100 inclusive */
2250- if (click_volume < 0) {
2251- click_volume = 0;
2252- } else if (click_volume > 100) {
2253- click_volume = 100;
2254- }
2255- kbdcontrol.key_click_percent = click ? click_volume : 0;
2256- kbdcontrol.bell_percent = bell_volume;
2257- kbdcontrol.bell_pitch = bell_pitch;
2258- kbdcontrol.bell_duration = bell_duration;
2259-
2260- gdk_error_trap_push ();
2261- XChangeKeyboardControl (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
2262- KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration,
2263- &kbdcontrol);
2264-
2265- XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE);
2266- gdk_error_trap_pop_ignored ();
2267-}
2268-
2269-static void
2270-apply_numlock (GsdKeyboardManager *manager)
2271-{
2272- GSettings *settings;
2273- gboolean rnumlock;
2274-
2275- g_debug ("Applying the num-lock settings");
2276- settings = manager->priv->settings;
2277- rnumlock = g_settings_get_boolean (settings, KEY_REMEMBER_NUMLOCK_STATE);
2278- manager->priv->old_state = g_settings_get_enum (manager->priv->settings, KEY_NUMLOCK_STATE);
2279-
2280- gdk_error_trap_push ();
2281- if (rnumlock) {
2282- g_debug ("Remember num-lock is set, so applying setting '%s'",
2283- num_lock_state_to_string (manager->priv->old_state));
2284- numlock_set_xkb_state (manager->priv->old_state);
2285- }
2286-
2287- XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE);
2288- gdk_error_trap_pop_ignored ();
2289-}
2290-
2291-static void
2292-apply_repeat (GsdKeyboardManager *manager)
2293-{
2294- GSettings *settings;
2295- gboolean repeat;
2296- guint interval;
2297- guint delay;
2298-
2299- g_debug ("Applying the repeat settings");
2300- settings = manager->priv->settings;
2301- repeat = g_settings_get_boolean (settings, KEY_REPEAT);
2302- interval = g_settings_get_uint (settings, KEY_INTERVAL);
2303- delay = g_settings_get_uint (settings, KEY_DELAY);
2304-
2305- gdk_error_trap_push ();
2306- if (repeat) {
2307- gboolean rate_set = FALSE;
2308-
2309- XAutoRepeatOn (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
2310- /* Use XKB in preference */
2311- rate_set = xkb_set_keyboard_autorepeat_rate (delay, interval);
2312-
2313- if (!rate_set)
2314- g_warning ("Neither XKeyboard not Xfree86's keyboard extensions are available,\n"
2315- "no way to support keyboard autorepeat rate settings");
2316- } else {
2317- XAutoRepeatOff (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
2318- }
2319-
2320- XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE);
2321- gdk_error_trap_pop_ignored ();
2322-}
2323-
2324-static void
2325-apply_all_settings (GsdKeyboardManager *manager)
2326-{
2327- apply_repeat (manager);
2328- apply_bell (manager);
2329- apply_numlock (manager);
2330-}
2331-
2332-static void
2333-set_input_sources_switcher (GsdKeyboardManager *manager,
2334- gboolean state)
2335-{
2336- if (state) {
2337- GError *error = NULL;
2338- char *args[2];
2339-
2340- if (manager->priv->input_sources_switcher_spawned)
2341- set_input_sources_switcher (manager, FALSE);
2342-
2343- args[0] = LIBEXECDIR "/gsd-input-sources-switcher";
2344- args[1] = NULL;
2345-
2346- g_spawn_async (NULL, args, NULL,
2347- 0, NULL, NULL,
2348- &manager->priv->input_sources_switcher_pid, &error);
2349-
2350- manager->priv->input_sources_switcher_spawned = (error == NULL);
2351-
2352- if (error) {
2353- g_warning ("Couldn't spawn %s: %s", args[0], error->message);
2354- g_error_free (error);
2355- }
2356- } else if (manager->priv->input_sources_switcher_spawned) {
2357- kill (manager->priv->input_sources_switcher_pid, SIGHUP);
2358- g_spawn_close_pid (manager->priv->input_sources_switcher_pid);
2359- manager->priv->input_sources_switcher_spawned = FALSE;
2360- }
2361-}
2362-
2363-static gboolean
2364-enable_switcher (GsdKeyboardManager *manager)
2365-{
2366- GsdInputSourcesSwitcher switcher;
2367-
2368- switcher = g_settings_get_enum (manager->priv->settings, KEY_SWITCHER);
2369-
2370- return switcher != GSD_INPUT_SOURCES_SWITCHER_OFF;
2371-}
2372-
2373-static void
2374-settings_changed (GSettings *settings,
2375- const char *key,
2376- GsdKeyboardManager *manager)
2377-{
2378- if (g_strcmp0 (key, KEY_CLICK) == 0||
2379- g_strcmp0 (key, KEY_CLICK_VOLUME) == 0 ||
2380- g_strcmp0 (key, KEY_BELL_PITCH) == 0 ||
2381- g_strcmp0 (key, KEY_BELL_DURATION) == 0 ||
2382- g_strcmp0 (key, KEY_BELL_MODE) == 0) {
2383- g_debug ("Bell setting '%s' changed, applying bell settings", key);
2384- apply_bell (manager);
2385- } else if (g_strcmp0 (key, KEY_REMEMBER_NUMLOCK_STATE) == 0) {
2386- g_debug ("Remember Num-Lock state '%s' changed, applying num-lock settings", key);
2387- apply_numlock (manager);
2388- } else if (g_strcmp0 (key, KEY_NUMLOCK_STATE) == 0) {
2389- g_debug ("Num-Lock state '%s' changed, will apply at next startup", key);
2390- } else if (g_strcmp0 (key, KEY_REPEAT) == 0 ||
2391- g_strcmp0 (key, KEY_INTERVAL) == 0 ||
2392- g_strcmp0 (key, KEY_DELAY) == 0) {
2393- g_debug ("Key repeat setting '%s' changed, applying key repeat settings", key);
2394- apply_repeat (manager);
2395- } else if (g_strcmp0 (key, KEY_SWITCHER) == 0) {
2396- set_input_sources_switcher (manager, enable_switcher (manager));
2397- } else {
2398- g_warning ("Unhandled settings change, key '%s'", key);
2399- }
2400-
2401-}
2402-
2403-static void
2404-device_added_cb (GdkDeviceManager *device_manager,
2405- GdkDevice *device,
2406- GsdKeyboardManager *manager)
2407-{
2408- GdkInputSource source;
2409-
2410- source = gdk_device_get_source (device);
2411- if (source == GDK_SOURCE_KEYBOARD) {
2412- g_debug ("New keyboard plugged in, applying all settings");
2413- apply_all_settings (manager);
2414- apply_input_sources_settings (manager->priv->input_sources_settings, NULL, 0, manager);
2415- run_custom_command (device, COMMAND_DEVICE_ADDED);
2416- }
2417-}
2418-
2419-static void
2420-device_removed_cb (GdkDeviceManager *device_manager,
2421- GdkDevice *device,
2422- GsdKeyboardManager *manager)
2423-{
2424- GdkInputSource source;
2425-
2426- source = gdk_device_get_source (device);
2427- if (source == GDK_SOURCE_KEYBOARD) {
2428- run_custom_command (device, COMMAND_DEVICE_REMOVED);
2429- }
2430-}
2431-
2432-static void
2433-set_devicepresence_handler (GsdKeyboardManager *manager)
2434-{
2435- GdkDeviceManager *device_manager;
2436-
2437- device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
2438-
2439- manager->priv->device_added_id = g_signal_connect (G_OBJECT (device_manager), "device-added",
2440- G_CALLBACK (device_added_cb), manager);
2441- manager->priv->device_removed_id = g_signal_connect (G_OBJECT (device_manager), "device-removed",
2442- G_CALLBACK (device_removed_cb), manager);
2443- manager->priv->device_manager = device_manager;
2444-}
2445-
2446-static void
2447-create_sources_from_current_xkb_config (GSettings *settings)
2448-{
2449- GVariantBuilder builder;
2450- XkbRF_VarDefsRec *xkb_var_defs;
2451- gchar *tmp;
2452- gchar **layouts = NULL;
2453- gchar **variants = NULL;
2454- guint i, n;
2455-
2456- gnome_xkb_info_get_var_defs (&tmp, &xkb_var_defs);
2457- g_free (tmp);
2458-
2459- if (xkb_var_defs->layout)
2460- layouts = g_strsplit (xkb_var_defs->layout, ",", 0);
2461- if (xkb_var_defs->variant)
2462- variants = g_strsplit (xkb_var_defs->variant, ",", 0);
2463-
2464- gnome_xkb_info_free_var_defs (xkb_var_defs);
2465-
2466- if (!layouts)
2467- goto out;
2468-
2469- if (variants && variants[0])
2470- n = MIN (g_strv_length (layouts), g_strv_length (variants));
2471- else
2472- n = g_strv_length (layouts);
2473-
2474- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
2475- for (i = 0; i < n && layouts[i][0]; ++i) {
2476- if (variants && variants[i] && variants[i][0])
2477- tmp = g_strdup_printf ("%s+%s", layouts[i], variants[i]);
2478- else
2479- tmp = g_strdup (layouts[i]);
2480-
2481- g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_XKB, tmp);
2482- g_free (tmp);
2483- }
2484- g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
2485-out:
2486- g_strfreev (layouts);
2487- g_strfreev (variants);
2488-}
2489-
2490-static void
2491-convert_libgnomekbd_options (GSettings *settings)
2492-{
2493- GPtrArray *opt_array;
2494- GSettings *libgnomekbd_settings;
2495- gchar **options, **o;
2496-
2497- if (!schema_is_installed ("org.gnome.libgnomekbd.keyboard"))
2498- return;
2499-
2500- opt_array = g_ptr_array_new_with_free_func (g_free);
2501-
2502- libgnomekbd_settings = g_settings_new ("org.gnome.libgnomekbd.keyboard");
2503- options = g_settings_get_strv (libgnomekbd_settings, "options");
2504-
2505- for (o = options; *o; ++o) {
2506- gchar **strv;
2507-
2508- strv = g_strsplit (*o, "\t", 2);
2509- if (strv[0] && strv[1]) {
2510- /* We don't want the group switcher because
2511- * it's incompatible with the way we use XKB
2512- * groups. */
2513- if (!g_str_has_prefix (strv[1], "grp:"))
2514- g_ptr_array_add (opt_array, g_strdup (strv[1]));
2515- }
2516- g_strfreev (strv);
2517- }
2518- g_ptr_array_add (opt_array, NULL);
2519-
2520- g_settings_set_strv (settings, KEY_KEYBOARD_OPTIONS, (const gchar * const*) opt_array->pdata);
2521-
2522- g_strfreev (options);
2523- g_object_unref (libgnomekbd_settings);
2524- g_ptr_array_free (opt_array, TRUE);
2525-}
2526-
2527-static void
2528-convert_libgnomekbd_layouts (GSettings *settings)
2529-{
2530- GVariantBuilder builder;
2531- GSettings *libgnomekbd_settings;
2532- gchar **layouts, **l;
2533-
2534- if (!schema_is_installed ("org.gnome.libgnomekbd.keyboard"))
2535- return;
2536-
2537- init_builder_with_sources (&builder, settings);
2538-
2539- libgnomekbd_settings = g_settings_new ("org.gnome.libgnomekbd.keyboard");
2540- layouts = g_settings_get_strv (libgnomekbd_settings, "layouts");
2541-
2542- for (l = layouts; *l; ++l) {
2543- gchar *id;
2544- gchar **strv;
2545-
2546- strv = g_strsplit (*l, "\t", 2);
2547- if (strv[0] && !strv[1])
2548- id = g_strdup (strv[0]);
2549- else if (strv[0] && strv[1])
2550- id = g_strdup_printf ("%s+%s", strv[0], strv[1]);
2551- else
2552- id = NULL;
2553-
2554- if (id)
2555- g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_XKB, id);
2556-
2557- g_free (id);
2558- g_strfreev (strv);
2559- }
2560-
2561- g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
2562-
2563- g_strfreev (layouts);
2564- g_object_unref (libgnomekbd_settings);
2565-}
2566-
2567-static void
2568-maybe_convert_old_settings (GSettings *settings)
2569-{
2570- GVariant *sources;
2571- gchar **options;
2572- gchar *stamp_dir_path = NULL;
2573- gchar *stamp_file_path = NULL;
2574- GError *error = NULL;
2575-
2576- stamp_dir_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME, NULL);
2577- if (g_mkdir_with_parents (stamp_dir_path, 0755)) {
2578- g_warning ("Failed to create directory %s: %s", stamp_dir_path, g_strerror (errno));
2579- goto out;
2580- }
2581-
2582- stamp_file_path = g_build_filename (stamp_dir_path, "input-sources-converted", NULL);
2583- if (g_file_test (stamp_file_path, G_FILE_TEST_EXISTS))
2584- goto out;
2585-
2586- sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
2587- if (g_variant_n_children (sources) < 1) {
2588- convert_libgnomekbd_layouts (settings);
2589-#ifdef HAVE_IBUS
2590- convert_ibus (settings);
2591-#endif
2592- }
2593- g_variant_unref (sources);
2594-
2595- options = g_settings_get_strv (settings, KEY_KEYBOARD_OPTIONS);
2596- if (g_strv_length (options) < 1)
2597- convert_libgnomekbd_options (settings);
2598- g_strfreev (options);
2599-
2600- if (!g_file_set_contents (stamp_file_path, "", 0, &error)) {
2601- g_warning ("%s", error->message);
2602- g_error_free (error);
2603- }
2604-out:
2605- g_free (stamp_file_path);
2606- g_free (stamp_dir_path);
2607-}
2608-
2609-static void
2610-maybe_create_input_sources (GsdKeyboardManager *manager)
2611-{
2612- GSettings *settings;
2613- GVariant *sources;
2614-
2615- settings = manager->priv->input_sources_settings;
2616-
2617- if (g_getenv ("RUNNING_UNDER_GDM")) {
2618- create_sources_from_current_xkb_config (settings);
2619- return;
2620- }
2621-
2622- maybe_convert_old_settings (settings);
2623-
2624- /* if we still don't have anything do some educated guesses */
2625- sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
2626- if (g_variant_n_children (sources) < 1) {
2627- create_sources_from_current_xkb_config (settings);
2628-#ifdef HAVE_IBUS
2629- add_ibus_sources_from_locale (settings);
2630-#endif
2631- }
2632- g_variant_unref (sources);
2633-}
2634-
2635-static gboolean
2636-start_keyboard_idle_cb (GsdKeyboardManager *manager)
2637-{
2638- gnome_settings_profile_start (NULL);
2639-
2640- g_debug ("Starting keyboard manager");
2641-
2642- manager->priv->settings = g_settings_new (GSD_KEYBOARD_DIR);
2643-
2644- xkb_init (manager);
2645-
2646- set_devicepresence_handler (manager);
2647-
2648- manager->priv->input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
2649- manager->priv->interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_DIR);
2650- manager->priv->xkb_info = gnome_xkb_info_new ();
2651-
2652- maybe_create_input_sources (manager);
2653-
2654-#ifdef HAVE_IBUS
2655- /* We don't want to touch IBus until we are sure this isn't a
2656- fallback session. */
2657- manager->priv->session_is_fallback = TRUE;
2658- manager->priv->ibus_cancellable = g_cancellable_new ();
2659- g_bus_get (G_BUS_TYPE_SESSION,
2660- manager->priv->ibus_cancellable,
2661- (GAsyncReadyCallback)got_bus,
2662- manager);
2663-#else
2664- apply_input_sources_settings (manager->priv->input_sources_settings, NULL, 0, manager);
2665-#endif
2666- /* apply current settings before we install the callback */
2667- g_debug ("Started the keyboard plugin, applying all settings");
2668- apply_all_settings (manager);
2669-
2670- g_signal_connect (G_OBJECT (manager->priv->settings), "changed",
2671- G_CALLBACK (settings_changed), manager);
2672- g_signal_connect (G_OBJECT (manager->priv->input_sources_settings), "change-event",
2673- G_CALLBACK (apply_input_sources_settings), manager);
2674-
2675- install_xkb_filter (manager);
2676- set_input_sources_switcher (manager, enable_switcher (manager));
2677-
2678- gnome_settings_profile_end (NULL);
2679-
2680- manager->priv->start_idle_id = 0;
2681-
2682- return FALSE;
2683-}
2684-
2685-gboolean
2686-gsd_keyboard_manager_start (GsdKeyboardManager *manager,
2687- GError **error)
2688-{
2689- gnome_settings_profile_start (NULL);
2690-
2691- if (check_xkb_extension (manager) == FALSE) {
2692- g_debug ("XKB is not supported, not applying any settings");
2693- return TRUE;
2694- }
2695-
2696- manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_keyboard_idle_cb, manager);
2697-
2698- gnome_settings_profile_end (NULL);
2699-
2700- return TRUE;
2701-}
2702-
2703-void
2704-gsd_keyboard_manager_stop (GsdKeyboardManager *manager)
2705-{
2706- GsdKeyboardManagerPrivate *p = manager->priv;
2707-
2708- g_debug ("Stopping keyboard manager");
2709-
2710- g_clear_object (&p->settings);
2711- g_clear_object (&p->input_sources_settings);
2712- g_clear_object (&p->interface_settings);
2713- g_clear_object (&p->xkb_info);
2714-
2715-#ifdef HAVE_IBUS
2716- clear_ibus (manager);
2717-#endif
2718-
2719- if (p->device_manager != NULL) {
2720- g_signal_handler_disconnect (p->device_manager, p->device_added_id);
2721- g_signal_handler_disconnect (p->device_manager, p->device_removed_id);
2722- p->device_manager = NULL;
2723- }
2724-
2725- remove_xkb_filter (manager);
2726-
2727- set_input_sources_switcher (manager, FALSE);
2728-}
2729-
2730-static void
2731-gsd_keyboard_manager_class_init (GsdKeyboardManagerClass *klass)
2732-{
2733- GObjectClass *object_class = G_OBJECT_CLASS (klass);
2734-
2735- object_class->finalize = gsd_keyboard_manager_finalize;
2736-
2737- g_type_class_add_private (klass, sizeof (GsdKeyboardManagerPrivate));
2738-}
2739-
2740-static void
2741-gsd_keyboard_manager_init (GsdKeyboardManager *manager)
2742-{
2743- manager->priv = GSD_KEYBOARD_MANAGER_GET_PRIVATE (manager);
2744-}
2745-
2746-static void
2747-gsd_keyboard_manager_finalize (GObject *object)
2748-{
2749- GsdKeyboardManager *keyboard_manager;
2750-
2751- g_return_if_fail (object != NULL);
2752- g_return_if_fail (GSD_IS_KEYBOARD_MANAGER (object));
2753-
2754- keyboard_manager = GSD_KEYBOARD_MANAGER (object);
2755-
2756- g_return_if_fail (keyboard_manager->priv != NULL);
2757-
2758- if (keyboard_manager->priv->start_idle_id != 0)
2759- g_source_remove (keyboard_manager->priv->start_idle_id);
2760-
2761- G_OBJECT_CLASS (gsd_keyboard_manager_parent_class)->finalize (object);
2762-}
2763-
2764-GsdKeyboardManager *
2765-gsd_keyboard_manager_new (void)
2766-{
2767- if (manager_object != NULL) {
2768- g_object_ref (manager_object);
2769- } else {
2770- manager_object = g_object_new (GSD_TYPE_KEYBOARD_MANAGER, NULL);
2771- g_object_add_weak_pointer (manager_object,
2772- (gpointer *) &manager_object);
2773- }
2774-
2775- return GSD_KEYBOARD_MANAGER (manager_object);
2776-}
2777
2778=== added directory '.pc/tune-syndaemon.patch'
2779=== added file '.pc/tune-syndaemon.patch/.timestamp'
2780=== added directory '.pc/tune-syndaemon.patch/plugins'
2781=== added directory '.pc/tune-syndaemon.patch/plugins/mouse'
2782=== added file '.pc/tune-syndaemon.patch/plugins/mouse/gsd-mouse-manager.c'
2783--- .pc/tune-syndaemon.patch/plugins/mouse/gsd-mouse-manager.c 1970-01-01 00:00:00 +0000
2784+++ .pc/tune-syndaemon.patch/plugins/mouse/gsd-mouse-manager.c 2013-08-29 18:58:42 +0000
2785@@ -0,0 +1,1354 @@
2786+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2787+ *
2788+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
2789+ *
2790+ * This program is free software; you can redistribute it and/or modify
2791+ * it under the terms of the GNU General Public License as published by
2792+ * the Free Software Foundation; either version 2 of the License, or
2793+ * (at your option) any later version.
2794+ *
2795+ * This program is distributed in the hope that it will be useful,
2796+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2797+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2798+ * GNU General Public License for more details.
2799+ *
2800+ * You should have received a copy of the GNU General Public License
2801+ * along with this program; if not, write to the Free Software
2802+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2803+ *
2804+ */
2805+
2806+#include "config.h"
2807+
2808+#include <sys/types.h>
2809+#include <sys/wait.h>
2810+#include <stdlib.h>
2811+#include <stdio.h>
2812+#include <unistd.h>
2813+#include <string.h>
2814+#include <errno.h>
2815+#include <math.h>
2816+#ifdef __linux
2817+#include <sys/prctl.h>
2818+#endif
2819+
2820+#include <locale.h>
2821+
2822+#include <glib.h>
2823+#include <glib/gi18n.h>
2824+#include <gio/gio.h>
2825+#include <gtk/gtk.h>
2826+#include <gdk/gdk.h>
2827+#include <gdk/gdkx.h>
2828+#include <gdk/gdkkeysyms.h>
2829+#include <X11/keysym.h>
2830+#include <X11/Xatom.h>
2831+
2832+#include <X11/extensions/XInput.h>
2833+#include <X11/extensions/XIproto.h>
2834+
2835+#include "gnome-settings-profile.h"
2836+#include "gsd-mouse-manager.h"
2837+#include "gsd-input-helper.h"
2838+#include "gsd-enums.h"
2839+
2840+#define GSD_MOUSE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MOUSE_MANAGER, GsdMouseManagerPrivate))
2841+
2842+#define SETTINGS_MOUSE_DIR "org.gnome.settings-daemon.peripherals.mouse"
2843+#define SETTINGS_TOUCHPAD_DIR "org.gnome.settings-daemon.peripherals.touchpad"
2844+
2845+/* Keys for both touchpad and mouse */
2846+#define KEY_LEFT_HANDED "left-handed" /* a boolean for mouse, an enum for touchpad */
2847+#define KEY_MOTION_ACCELERATION "motion-acceleration"
2848+#define KEY_MOTION_THRESHOLD "motion-threshold"
2849+
2850+/* Touchpad settings */
2851+#define KEY_TOUCHPAD_DISABLE_W_TYPING "disable-while-typing"
2852+#define KEY_PAD_HORIZ_SCROLL "horiz-scroll-enabled"
2853+#define KEY_SCROLL_METHOD "scroll-method"
2854+#define KEY_TAP_TO_CLICK "tap-to-click"
2855+#define KEY_TOUCHPAD_ENABLED "touchpad-enabled"
2856+#define KEY_NATURAL_SCROLL_ENABLED "natural-scroll"
2857+
2858+/* Mouse settings */
2859+#define KEY_LOCATE_POINTER "locate-pointer"
2860+#define KEY_DWELL_CLICK_ENABLED "dwell-click-enabled"
2861+#define KEY_SECONDARY_CLICK_ENABLED "secondary-click-enabled"
2862+#define KEY_MIDDLE_BUTTON_EMULATION "middle-button-enabled"
2863+
2864+struct GsdMouseManagerPrivate
2865+{
2866+ guint start_idle_id;
2867+ GSettings *touchpad_settings;
2868+ GSettings *mouse_settings;
2869+ GSettings *mouse_a11y_settings;
2870+ GdkDeviceManager *device_manager;
2871+ guint device_added_id;
2872+ guint device_removed_id;
2873+ GHashTable *blacklist;
2874+
2875+ gboolean mousetweaks_daemon_running;
2876+ gboolean syndaemon_spawned;
2877+ GPid syndaemon_pid;
2878+ gboolean locate_pointer_spawned;
2879+ GPid locate_pointer_pid;
2880+};
2881+
2882+static void gsd_mouse_manager_class_init (GsdMouseManagerClass *klass);
2883+static void gsd_mouse_manager_init (GsdMouseManager *mouse_manager);
2884+static void gsd_mouse_manager_finalize (GObject *object);
2885+static void set_tap_to_click (GdkDevice *device,
2886+ gboolean state,
2887+ gboolean left_handed);
2888+static void set_natural_scroll (GsdMouseManager *manager,
2889+ GdkDevice *device,
2890+ gboolean natural_scroll);
2891+
2892+G_DEFINE_TYPE (GsdMouseManager, gsd_mouse_manager, G_TYPE_OBJECT)
2893+
2894+static gpointer manager_object = NULL;
2895+
2896+
2897+static GObject *
2898+gsd_mouse_manager_constructor (GType type,
2899+ guint n_construct_properties,
2900+ GObjectConstructParam *construct_properties)
2901+{
2902+ GsdMouseManager *mouse_manager;
2903+
2904+ mouse_manager = GSD_MOUSE_MANAGER (G_OBJECT_CLASS (gsd_mouse_manager_parent_class)->constructor (type,
2905+ n_construct_properties,
2906+ construct_properties));
2907+
2908+ return G_OBJECT (mouse_manager);
2909+}
2910+
2911+static void
2912+gsd_mouse_manager_dispose (GObject *object)
2913+{
2914+ G_OBJECT_CLASS (gsd_mouse_manager_parent_class)->dispose (object);
2915+}
2916+
2917+static void
2918+gsd_mouse_manager_class_init (GsdMouseManagerClass *klass)
2919+{
2920+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
2921+
2922+ object_class->constructor = gsd_mouse_manager_constructor;
2923+ object_class->dispose = gsd_mouse_manager_dispose;
2924+ object_class->finalize = gsd_mouse_manager_finalize;
2925+
2926+ g_type_class_add_private (klass, sizeof (GsdMouseManagerPrivate));
2927+}
2928+
2929+static XDevice *
2930+open_gdk_device (GdkDevice *device)
2931+{
2932+ XDevice *xdevice;
2933+ int id;
2934+
2935+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
2936+
2937+ gdk_error_trap_push ();
2938+
2939+ xdevice = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), id);
2940+
2941+ if (gdk_error_trap_pop () != 0)
2942+ return NULL;
2943+
2944+ return xdevice;
2945+}
2946+
2947+static gboolean
2948+device_is_blacklisted (GsdMouseManager *manager,
2949+ GdkDevice *device)
2950+{
2951+ int id;
2952+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
2953+ if (g_hash_table_lookup (manager->priv->blacklist, GINT_TO_POINTER (id)) != NULL) {
2954+ g_debug ("device %s (%d) is blacklisted", gdk_device_get_name (device), id);
2955+ return TRUE;
2956+ }
2957+ return FALSE;
2958+}
2959+
2960+static gboolean
2961+device_is_ignored (GsdMouseManager *manager,
2962+ GdkDevice *device)
2963+{
2964+ GdkInputSource source;
2965+ const char *name;
2966+
2967+ if (device_is_blacklisted (manager, device))
2968+ return TRUE;
2969+
2970+ source = gdk_device_get_source (device);
2971+ if (source != GDK_SOURCE_MOUSE &&
2972+ source != GDK_SOURCE_TOUCHPAD &&
2973+ source != GDK_SOURCE_CURSOR)
2974+ return TRUE;
2975+
2976+ name = gdk_device_get_name (device);
2977+ if (name != NULL && g_str_equal ("Virtual core XTEST pointer", name))
2978+ return TRUE;
2979+
2980+ return FALSE;
2981+}
2982+
2983+static void
2984+configure_button_layout (guchar *buttons,
2985+ gint n_buttons,
2986+ gboolean left_handed)
2987+{
2988+ const gint left_button = 1;
2989+ gint right_button;
2990+ gint i;
2991+
2992+ /* if the button is higher than 2 (3rd button) then it's
2993+ * probably one direction of a scroll wheel or something else
2994+ * uninteresting
2995+ */
2996+ right_button = MIN (n_buttons, 3);
2997+
2998+ /* If we change things we need to make sure we only swap buttons.
2999+ * If we end up with multiple physical buttons assigned to the same
3000+ * logical button the server will complain. This code assumes physical
3001+ * button 0 is the physical left mouse button, and that the physical
3002+ * button other than 0 currently assigned left_button or right_button
3003+ * is the physical right mouse button.
3004+ */
3005+
3006+ /* check if the current mapping satisfies the above assumptions */
3007+ if (buttons[left_button - 1] != left_button &&
3008+ buttons[left_button - 1] != right_button)
3009+ /* The current mapping is weird. Swapping buttons is probably not a
3010+ * good idea.
3011+ */
3012+ return;
3013+
3014+ /* check if we are left_handed and currently not swapped */
3015+ if (left_handed && buttons[left_button - 1] == left_button) {
3016+ /* find the right button */
3017+ for (i = 0; i < n_buttons; i++) {
3018+ if (buttons[i] == right_button) {
3019+ buttons[i] = left_button;
3020+ break;
3021+ }
3022+ }
3023+ /* swap the buttons */
3024+ buttons[left_button - 1] = right_button;
3025+ }
3026+ /* check if we are not left_handed but are swapped */
3027+ else if (!left_handed && buttons[left_button - 1] == right_button) {
3028+ /* find the right button */
3029+ for (i = 0; i < n_buttons; i++) {
3030+ if (buttons[i] == left_button) {
3031+ buttons[i] = right_button;
3032+ break;
3033+ }
3034+ }
3035+ /* swap the buttons */
3036+ buttons[left_button - 1] = left_button;
3037+ }
3038+}
3039+
3040+static gboolean
3041+xinput_device_has_buttons (GdkDevice *device)
3042+{
3043+ int i;
3044+ XAnyClassInfo *class_info;
3045+
3046+ /* FIXME can we use the XDevice's classes here instead? */
3047+ XDeviceInfo *device_info, *info;
3048+ gint n_devices;
3049+ int id;
3050+
3051+ /* Find the XDeviceInfo for the GdkDevice */
3052+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
3053+
3054+ device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices);
3055+ if (device_info == NULL)
3056+ return FALSE;
3057+
3058+ info = NULL;
3059+ for (i = 0; i < n_devices; i++) {
3060+ if (device_info[i].id == id) {
3061+ info = &device_info[i];
3062+ break;
3063+ }
3064+ }
3065+ if (info == NULL)
3066+ goto bail;
3067+
3068+ class_info = info->inputclassinfo;
3069+ for (i = 0; i < info->num_classes; i++) {
3070+ if (class_info->class == ButtonClass) {
3071+ XButtonInfo *button_info;
3072+
3073+ button_info = (XButtonInfo *) class_info;
3074+ if (button_info->num_buttons > 0) {
3075+ XFreeDeviceList (device_info);
3076+ return TRUE;
3077+ }
3078+ }
3079+
3080+ class_info = (XAnyClassInfo *) (((guchar *) class_info) +
3081+ class_info->length);
3082+ }
3083+
3084+bail:
3085+ XFreeDeviceList (device_info);
3086+
3087+ return FALSE;
3088+}
3089+
3090+static gboolean
3091+touchpad_has_single_button (XDevice *device)
3092+{
3093+ Atom type, prop;
3094+ int format;
3095+ unsigned long nitems, bytes_after;
3096+ unsigned char *data;
3097+ gboolean is_single_button = FALSE;
3098+ int rc;
3099+
3100+ prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Capabilities", False);
3101+ if (!prop)
3102+ return FALSE;
3103+
3104+ gdk_error_trap_push ();
3105+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop, 0, 1, False,
3106+ XA_INTEGER, &type, &format, &nitems,
3107+ &bytes_after, &data);
3108+ if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 3)
3109+ is_single_button = (data[0] == 1 && data[1] == 0 && data[2] == 0);
3110+
3111+ if (rc == Success)
3112+ XFree (data);
3113+
3114+ gdk_error_trap_pop_ignored ();
3115+
3116+ return is_single_button;
3117+}
3118+
3119+static void
3120+set_left_handed (GsdMouseManager *manager,
3121+ GdkDevice *device,
3122+ gboolean mouse_left_handed,
3123+ gboolean touchpad_left_handed)
3124+{
3125+ XDevice *xdevice;
3126+ guchar *buttons;
3127+ gsize buttons_capacity = 16;
3128+ gboolean left_handed;
3129+ gint n_buttons;
3130+
3131+ if (!xinput_device_has_buttons (device))
3132+ return;
3133+
3134+ xdevice = open_gdk_device (device);
3135+ if (xdevice == NULL)
3136+ return;
3137+
3138+ g_debug ("setting handedness on %s", gdk_device_get_name (device));
3139+
3140+ buttons = g_new (guchar, buttons_capacity);
3141+
3142+ /* If the device is a touchpad, swap tap buttons
3143+ * around too, otherwise a tap would be a right-click */
3144+ if (device_is_touchpad (xdevice)) {
3145+ gboolean tap = g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TAP_TO_CLICK);
3146+ gboolean single_button = touchpad_has_single_button (xdevice);
3147+
3148+ left_handed = touchpad_left_handed;
3149+
3150+ if (tap && !single_button)
3151+ set_tap_to_click (device, tap, left_handed);
3152+
3153+ if (single_button)
3154+ goto out;
3155+ } else {
3156+ left_handed = mouse_left_handed;
3157+ }
3158+
3159+ n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3160+ buttons,
3161+ buttons_capacity);
3162+
3163+ while (n_buttons > buttons_capacity) {
3164+ buttons_capacity = n_buttons;
3165+ buttons = (guchar *) g_realloc (buttons,
3166+ buttons_capacity * sizeof (guchar));
3167+
3168+ n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3169+ buttons,
3170+ buttons_capacity);
3171+ }
3172+
3173+ configure_button_layout (buttons, n_buttons, left_handed);
3174+
3175+ gdk_error_trap_push ();
3176+ XSetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, buttons, n_buttons);
3177+ gdk_error_trap_pop_ignored ();
3178+
3179+out:
3180+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3181+ g_free (buttons);
3182+}
3183+
3184+static void
3185+set_motion (GsdMouseManager *manager,
3186+ GdkDevice *device)
3187+{
3188+ XDevice *xdevice;
3189+ XPtrFeedbackControl feedback;
3190+ XFeedbackState *states, *state;
3191+ int num_feedbacks;
3192+ int numerator, denominator;
3193+ gfloat motion_acceleration;
3194+ int motion_threshold;
3195+ GSettings *settings;
3196+ guint i;
3197+
3198+ xdevice = open_gdk_device (device);
3199+ if (xdevice == NULL)
3200+ return;
3201+
3202+ g_debug ("setting motion on %s", gdk_device_get_name (device));
3203+
3204+ if (device_is_touchpad (xdevice))
3205+ settings = manager->priv->touchpad_settings;
3206+ else
3207+ settings = manager->priv->mouse_settings;
3208+
3209+ /* Calculate acceleration */
3210+ motion_acceleration = g_settings_get_double (settings, KEY_MOTION_ACCELERATION);
3211+
3212+ if (motion_acceleration >= 1.0) {
3213+ /* we want to get the acceleration, with a resolution of 0.5
3214+ */
3215+ if ((motion_acceleration - floor (motion_acceleration)) < 0.25) {
3216+ numerator = floor (motion_acceleration);
3217+ denominator = 1;
3218+ } else if ((motion_acceleration - floor (motion_acceleration)) < 0.5) {
3219+ numerator = ceil (2.0 * motion_acceleration);
3220+ denominator = 2;
3221+ } else if ((motion_acceleration - floor (motion_acceleration)) < 0.75) {
3222+ numerator = floor (2.0 *motion_acceleration);
3223+ denominator = 2;
3224+ } else {
3225+ numerator = ceil (motion_acceleration);
3226+ denominator = 1;
3227+ }
3228+ } else if (motion_acceleration < 1.0 && motion_acceleration > 0) {
3229+ /* This we do to 1/10ths */
3230+ numerator = floor (motion_acceleration * 10) + 1;
3231+ denominator= 10;
3232+ } else {
3233+ numerator = -1;
3234+ denominator = -1;
3235+ }
3236+
3237+ /* And threshold */
3238+ motion_threshold = g_settings_get_int (settings, KEY_MOTION_THRESHOLD);
3239+
3240+ /* Get the list of feedbacks for the device */
3241+ states = XGetFeedbackControl (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, &num_feedbacks);
3242+ if (states == NULL)
3243+ goto out;
3244+ state = (XFeedbackState *) states;
3245+ for (i = 0; i < num_feedbacks; i++) {
3246+ if (state->class == PtrFeedbackClass) {
3247+ /* And tell the device */
3248+ feedback.class = PtrFeedbackClass;
3249+ feedback.length = sizeof (XPtrFeedbackControl);
3250+ feedback.id = state->id;
3251+ feedback.threshold = motion_threshold;
3252+ feedback.accelNum = numerator;
3253+ feedback.accelDenom = denominator;
3254+
3255+ g_debug ("Setting accel %d/%d, threshold %d for device '%s'",
3256+ numerator, denominator, motion_threshold, gdk_device_get_name (device));
3257+
3258+ XChangeFeedbackControl (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
3259+ xdevice,
3260+ DvAccelNum | DvAccelDenom | DvThreshold,
3261+ (XFeedbackControl *) &feedback);
3262+
3263+ break;
3264+ }
3265+ state = (XFeedbackState *) ((char *) state + state->length);
3266+ }
3267+
3268+ XFreeFeedbackList (states);
3269+
3270+ out:
3271+
3272+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3273+}
3274+
3275+static void
3276+set_middle_button (GsdMouseManager *manager,
3277+ GdkDevice *device,
3278+ gboolean middle_button)
3279+{
3280+ Atom prop;
3281+ XDevice *xdevice;
3282+ Atom type;
3283+ int format;
3284+ unsigned long nitems, bytes_after;
3285+ unsigned char *data;
3286+ int rc;
3287+
3288+ prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
3289+ "Evdev Middle Button Emulation", True);
3290+
3291+ if (!prop) /* no evdev devices */
3292+ return;
3293+
3294+ xdevice = open_gdk_device (device);
3295+ if (xdevice == NULL)
3296+ return;
3297+
3298+ g_debug ("setting middle button on %s", gdk_device_get_name (device));
3299+
3300+ gdk_error_trap_push ();
3301+
3302+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
3303+ xdevice, prop, 0, 1, False, XA_INTEGER, &type, &format,
3304+ &nitems, &bytes_after, &data);
3305+
3306+ if (rc == Success && format == 8 && type == XA_INTEGER && nitems == 1) {
3307+ data[0] = middle_button ? 1 : 0;
3308+
3309+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
3310+ xdevice, prop, type, format, PropModeReplace, data, nitems);
3311+ }
3312+
3313+ if (gdk_error_trap_pop ())
3314+ g_warning ("Error in setting middle button emulation on \"%s\"", gdk_device_get_name (device));
3315+
3316+ if (rc == Success)
3317+ XFree (data);
3318+
3319+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3320+}
3321+
3322+/* Ensure that syndaemon dies together with us, to avoid running several of
3323+ * them */
3324+static void
3325+setup_syndaemon (gpointer user_data)
3326+{
3327+#ifdef __linux
3328+ prctl (PR_SET_PDEATHSIG, SIGHUP);
3329+#endif
3330+}
3331+
3332+static gboolean
3333+have_program_in_path (const char *name)
3334+{
3335+ gchar *path;
3336+ gboolean result;
3337+
3338+ path = g_find_program_in_path (name);
3339+ result = (path != NULL);
3340+ g_free (path);
3341+ return result;
3342+}
3343+
3344+static void
3345+syndaemon_died (GPid pid, gint status, gpointer user_data)
3346+{
3347+ GsdMouseManager *manager = GSD_MOUSE_MANAGER (user_data);
3348+
3349+ g_debug ("syndaemon stopped with status %i", status);
3350+ g_spawn_close_pid (pid);
3351+ manager->priv->syndaemon_spawned = FALSE;
3352+}
3353+
3354+static int
3355+set_disable_w_typing (GsdMouseManager *manager, gboolean state)
3356+{
3357+ if (state && touchpad_is_present ()) {
3358+ GError *error = NULL;
3359+ GPtrArray *args;
3360+
3361+ if (manager->priv->syndaemon_spawned)
3362+ return 0;
3363+
3364+ if (!have_program_in_path ("syndaemon"))
3365+ return 0;
3366+
3367+ args = g_ptr_array_new ();
3368+
3369+ g_ptr_array_add (args, "syndaemon");
3370+ g_ptr_array_add (args, "-i");
3371+ g_ptr_array_add (args, "1.0");
3372+ g_ptr_array_add (args, "-t");
3373+ g_ptr_array_add (args, "-K");
3374+ g_ptr_array_add (args, "-R");
3375+ g_ptr_array_add (args, NULL);
3376+
3377+ /* we must use G_SPAWN_DO_NOT_REAP_CHILD to avoid
3378+ * double-forking, otherwise syndaemon will immediately get
3379+ * killed again through (PR_SET_PDEATHSIG when the intermediate
3380+ * process dies */
3381+ g_spawn_async (g_get_home_dir (), (char **) args->pdata, NULL,
3382+ G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, setup_syndaemon, NULL,
3383+ &manager->priv->syndaemon_pid, &error);
3384+
3385+ manager->priv->syndaemon_spawned = (error == NULL);
3386+ g_ptr_array_free (args, FALSE);
3387+
3388+ if (error) {
3389+ g_warning ("Failed to launch syndaemon: %s", error->message);
3390+ g_settings_set_boolean (manager->priv->touchpad_settings, KEY_TOUCHPAD_DISABLE_W_TYPING, FALSE);
3391+ g_error_free (error);
3392+ } else {
3393+ g_child_watch_add (manager->priv->syndaemon_pid, syndaemon_died, manager);
3394+ g_debug ("Launched syndaemon");
3395+ }
3396+ } else if (manager->priv->syndaemon_spawned) {
3397+ kill (manager->priv->syndaemon_pid, SIGHUP);
3398+ g_spawn_close_pid (manager->priv->syndaemon_pid);
3399+ manager->priv->syndaemon_spawned = FALSE;
3400+ g_debug ("Killed syndaemon");
3401+ }
3402+
3403+ return 0;
3404+}
3405+
3406+static void
3407+set_tap_to_click (GdkDevice *device,
3408+ gboolean state,
3409+ gboolean left_handed)
3410+{
3411+ int format, rc;
3412+ unsigned long nitems, bytes_after;
3413+ XDevice *xdevice;
3414+ unsigned char* data;
3415+ Atom prop, type;
3416+
3417+ prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Tap Action", False);
3418+ if (!prop)
3419+ return;
3420+
3421+ xdevice = open_gdk_device (device);
3422+ if (xdevice == NULL)
3423+ return;
3424+
3425+ if (!device_is_touchpad (xdevice)) {
3426+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3427+ return;
3428+ }
3429+
3430+ g_debug ("setting tap to click on %s", gdk_device_get_name (device));
3431+
3432+ gdk_error_trap_push ();
3433+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, 0, 2,
3434+ False, XA_INTEGER, &type, &format, &nitems,
3435+ &bytes_after, &data);
3436+
3437+ if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 7) {
3438+ /* Set MR mapping for corner tapping on the right side*/
3439+ data[0] = (state) ? 2 : 0;
3440+ data[1] = (state) ? 3 : 0;
3441+
3442+ /* Set RLM mapping for 1/2/3 fingers*/
3443+ data[4] = (state) ? ((left_handed) ? 3 : 1) : 0;
3444+ data[5] = (state) ? ((left_handed) ? 1 : 3) : 0;
3445+ data[6] = 0; /* Disable three touch tap so gestures work */
3446+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, XA_INTEGER, 8,
3447+ PropModeReplace, data, nitems);
3448+ }
3449+
3450+ if (rc == Success)
3451+ XFree (data);
3452+
3453+ if (gdk_error_trap_pop ())
3454+ g_warning ("Error in setting tap to click on \"%s\"", gdk_device_get_name (device));
3455+
3456+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3457+}
3458+
3459+static void
3460+set_horiz_scroll (GdkDevice *device,
3461+ gboolean state)
3462+{
3463+ int rc;
3464+ XDevice *xdevice;
3465+ Atom act_type, prop_edge, prop_twofinger;
3466+ int act_format;
3467+ unsigned long nitems, bytes_after;
3468+ unsigned char *data;
3469+
3470+ prop_edge = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Edge Scrolling", False);
3471+ prop_twofinger = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Two-Finger Scrolling", False);
3472+
3473+ if (!prop_edge || !prop_twofinger)
3474+ return;
3475+
3476+ xdevice = open_gdk_device (device);
3477+ if (xdevice == NULL)
3478+ return;
3479+
3480+ if (!device_is_touchpad (xdevice)) {
3481+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3482+ return;
3483+ }
3484+
3485+ g_debug ("setting horiz scroll on %s", gdk_device_get_name (device));
3486+
3487+ gdk_error_trap_push ();
3488+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3489+ prop_edge, 0, 1, False,
3490+ XA_INTEGER, &act_type, &act_format, &nitems,
3491+ &bytes_after, &data);
3492+ if (rc == Success && act_type == XA_INTEGER &&
3493+ act_format == 8 && nitems >= 2) {
3494+ data[1] = (state && data[0]);
3495+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3496+ prop_edge, XA_INTEGER, 8,
3497+ PropModeReplace, data, nitems);
3498+ }
3499+
3500+ XFree (data);
3501+
3502+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3503+ prop_twofinger, 0, 1, False,
3504+ XA_INTEGER, &act_type, &act_format, &nitems,
3505+ &bytes_after, &data);
3506+ if (rc == Success && act_type == XA_INTEGER &&
3507+ act_format == 8 && nitems >= 2) {
3508+ data[1] = (state && data[0]);
3509+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3510+ prop_twofinger, XA_INTEGER, 8,
3511+ PropModeReplace, data, nitems);
3512+ }
3513+
3514+ if (gdk_error_trap_pop ())
3515+ g_warning ("Error in setting horiz scroll on \"%s\"", gdk_device_get_name (device));
3516+
3517+ if (rc == Success)
3518+ XFree (data);
3519+
3520+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3521+
3522+}
3523+
3524+static void
3525+set_edge_scroll (GdkDevice *device,
3526+ GsdTouchpadScrollMethod method)
3527+{
3528+ int rc;
3529+ XDevice *xdevice;
3530+ Atom act_type, prop_edge, prop_twofinger;
3531+ int act_format;
3532+ unsigned long nitems, bytes_after;
3533+ unsigned char *data;
3534+
3535+ prop_edge = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Edge Scrolling", False);
3536+ prop_twofinger = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Two-Finger Scrolling", False);
3537+
3538+ if (!prop_edge || !prop_twofinger)
3539+ return;
3540+
3541+ xdevice = open_gdk_device (device);
3542+ if (xdevice == NULL)
3543+ return;
3544+
3545+ if (!device_is_touchpad (xdevice)) {
3546+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3547+ return;
3548+ }
3549+
3550+ g_debug ("setting edge scroll on %s", gdk_device_get_name (device));
3551+
3552+ gdk_error_trap_push ();
3553+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3554+ prop_edge, 0, 1, False,
3555+ XA_INTEGER, &act_type, &act_format, &nitems,
3556+ &bytes_after, &data);
3557+ if (rc == Success && act_type == XA_INTEGER &&
3558+ act_format == 8 && nitems >= 2) {
3559+ data[0] = (method == GSD_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING) ? 1 : 0;
3560+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3561+ prop_edge, XA_INTEGER, 8,
3562+ PropModeReplace, data, nitems);
3563+ }
3564+
3565+ XFree (data);
3566+
3567+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3568+ prop_twofinger, 0, 1, False,
3569+ XA_INTEGER, &act_type, &act_format, &nitems,
3570+ &bytes_after, &data);
3571+ if (rc == Success && act_type == XA_INTEGER &&
3572+ act_format == 8 && nitems >= 2) {
3573+ data[0] = (method == GSD_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING) ? 1 : 0;
3574+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3575+ prop_twofinger, XA_INTEGER, 8,
3576+ PropModeReplace, data, nitems);
3577+ }
3578+
3579+ if (gdk_error_trap_pop ())
3580+ g_warning ("Error in setting edge scroll on \"%s\"", gdk_device_get_name (device));
3581+
3582+ if (rc == Success)
3583+ XFree (data);
3584+
3585+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3586+}
3587+
3588+static void
3589+set_touchpad_disabled (GdkDevice *device)
3590+{
3591+ int id;
3592+ XDevice *xdevice;
3593+
3594+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
3595+
3596+ g_debug ("Trying to set device disabled for \"%s\" (%d)", gdk_device_get_name (device), id);
3597+
3598+ xdevice = open_gdk_device (device);
3599+ if (xdevice == NULL)
3600+ return;
3601+
3602+ if (!device_is_touchpad (xdevice)) {
3603+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3604+ return;
3605+ }
3606+
3607+ if (set_device_enabled (id, FALSE) == FALSE)
3608+ g_warning ("Error disabling device \"%s\" (%d)", gdk_device_get_name (device), id);
3609+ else
3610+ g_debug ("Disabled device \"%s\" (%d)", gdk_device_get_name (device), id);
3611+
3612+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3613+}
3614+
3615+static void
3616+set_touchpad_enabled (int id)
3617+{
3618+ XDevice *xdevice;
3619+
3620+ g_debug ("Trying to set device enabled for %d", id);
3621+
3622+ gdk_error_trap_push ();
3623+ xdevice = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), id);
3624+ if (gdk_error_trap_pop () != 0)
3625+ return;
3626+
3627+ if (!device_is_touchpad (xdevice)) {
3628+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3629+ return;
3630+ }
3631+
3632+ if (set_device_enabled (id, TRUE) == FALSE)
3633+ g_warning ("Error enabling device \"%d\"", id);
3634+ else
3635+ g_debug ("Enabled device %d", id);
3636+
3637+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3638+}
3639+
3640+static void
3641+set_locate_pointer (GsdMouseManager *manager,
3642+ gboolean state)
3643+{
3644+ if (state) {
3645+ GError *error = NULL;
3646+ char *args[2];
3647+
3648+ if (manager->priv->locate_pointer_spawned)
3649+ return;
3650+
3651+ args[0] = LIBEXECDIR "/gsd-locate-pointer";
3652+ args[1] = NULL;
3653+
3654+ g_spawn_async (NULL, args, NULL,
3655+ 0, NULL, NULL,
3656+ &manager->priv->locate_pointer_pid, &error);
3657+
3658+ manager->priv->locate_pointer_spawned = (error == NULL);
3659+
3660+ if (error) {
3661+ g_settings_set_boolean (manager->priv->mouse_settings, KEY_LOCATE_POINTER, FALSE);
3662+ g_error_free (error);
3663+ }
3664+
3665+ } else if (manager->priv->locate_pointer_spawned) {
3666+ kill (manager->priv->locate_pointer_pid, SIGHUP);
3667+ g_spawn_close_pid (manager->priv->locate_pointer_pid);
3668+ manager->priv->locate_pointer_spawned = FALSE;
3669+ }
3670+}
3671+
3672+static void
3673+set_mousetweaks_daemon (GsdMouseManager *manager,
3674+ gboolean dwell_click_enabled,
3675+ gboolean secondary_click_enabled)
3676+{
3677+ GError *error = NULL;
3678+ gchar *comm;
3679+ gboolean run_daemon = dwell_click_enabled || secondary_click_enabled;
3680+
3681+ if (run_daemon || manager->priv->mousetweaks_daemon_running)
3682+ comm = g_strdup_printf ("mousetweaks %s",
3683+ run_daemon ? "" : "-s");
3684+ else
3685+ return;
3686+
3687+ if (run_daemon)
3688+ manager->priv->mousetweaks_daemon_running = TRUE;
3689+
3690+ if (! g_spawn_command_line_async (comm, &error)) {
3691+ if (error->code == G_SPAWN_ERROR_NOENT && run_daemon) {
3692+ GtkWidget *dialog;
3693+
3694+ if (dwell_click_enabled) {
3695+ g_settings_set_boolean (manager->priv->mouse_a11y_settings,
3696+ KEY_DWELL_CLICK_ENABLED, FALSE);
3697+ } else if (secondary_click_enabled) {
3698+ g_settings_set_boolean (manager->priv->mouse_a11y_settings,
3699+ KEY_SECONDARY_CLICK_ENABLED, FALSE);
3700+ }
3701+
3702+ dialog = gtk_message_dialog_new (NULL, 0,
3703+ GTK_MESSAGE_WARNING,
3704+ GTK_BUTTONS_OK,
3705+ _("Could not enable mouse accessibility features"));
3706+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3707+ _("Mouse accessibility requires Mousetweaks "
3708+ "to be installed on your system."));
3709+ gtk_window_set_title (GTK_WINDOW (dialog), _("Universal Access"));
3710+ gtk_window_set_icon_name (GTK_WINDOW (dialog),
3711+ "preferences-desktop-accessibility");
3712+ gtk_dialog_run (GTK_DIALOG (dialog));
3713+ gtk_widget_destroy (dialog);
3714+ }
3715+ g_error_free (error);
3716+ }
3717+ g_free (comm);
3718+}
3719+
3720+static gboolean
3721+get_touchpad_handedness (GsdMouseManager *manager, gboolean mouse_left_handed)
3722+{
3723+ switch (g_settings_get_enum (manager->priv->touchpad_settings, KEY_LEFT_HANDED)) {
3724+ case GSD_TOUCHPAD_HANDEDNESS_RIGHT:
3725+ return FALSE;
3726+ case GSD_TOUCHPAD_HANDEDNESS_LEFT:
3727+ return TRUE;
3728+ case GSD_TOUCHPAD_HANDEDNESS_MOUSE:
3729+ return mouse_left_handed;
3730+ default:
3731+ g_assert_not_reached ();
3732+ }
3733+}
3734+
3735+static void
3736+set_mouse_settings (GsdMouseManager *manager,
3737+ GdkDevice *device)
3738+{
3739+ gboolean mouse_left_handed, touchpad_left_handed;
3740+
3741+ mouse_left_handed = g_settings_get_boolean (manager->priv->mouse_settings, KEY_LEFT_HANDED);
3742+ touchpad_left_handed = get_touchpad_handedness (manager, mouse_left_handed);
3743+ set_left_handed (manager, device, mouse_left_handed, touchpad_left_handed);
3744+
3745+ set_motion (manager, device);
3746+ set_middle_button (manager, device, g_settings_get_boolean (manager->priv->mouse_settings, KEY_MIDDLE_BUTTON_EMULATION));
3747+
3748+ set_tap_to_click (device, g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TAP_TO_CLICK), touchpad_left_handed);
3749+ set_edge_scroll (device, g_settings_get_enum (manager->priv->touchpad_settings, KEY_SCROLL_METHOD));
3750+ set_horiz_scroll (device, g_settings_get_boolean (manager->priv->touchpad_settings, KEY_PAD_HORIZ_SCROLL));
3751+ set_natural_scroll (manager, device, g_settings_get_boolean (manager->priv->touchpad_settings, KEY_NATURAL_SCROLL_ENABLED));
3752+ if (g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TOUCHPAD_ENABLED) == FALSE)
3753+ set_touchpad_disabled (device);
3754+}
3755+
3756+static void
3757+set_natural_scroll (GsdMouseManager *manager,
3758+ GdkDevice *device,
3759+ gboolean natural_scroll)
3760+{
3761+ XDevice *xdevice;
3762+ Atom scrolling_distance, act_type;
3763+ int rc, act_format;
3764+ unsigned long nitems, bytes_after;
3765+ unsigned char *data;
3766+ glong *ptr;
3767+
3768+ xdevice = open_gdk_device (device);
3769+ if (xdevice == NULL)
3770+ return;
3771+
3772+ if (!device_is_touchpad (xdevice)) {
3773+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3774+ return;
3775+ }
3776+
3777+ g_debug ("Trying to set %s for \"%s\"",
3778+ natural_scroll ? "natural (reverse) scroll" : "normal scroll",
3779+ gdk_device_get_name (device));
3780+
3781+ scrolling_distance = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
3782+ "Synaptics Scrolling Distance", False);
3783+
3784+ gdk_error_trap_push ();
3785+ rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3786+ scrolling_distance, 0, 2, False,
3787+ XA_INTEGER, &act_type, &act_format, &nitems,
3788+ &bytes_after, &data);
3789+
3790+ if (rc == Success && act_type == XA_INTEGER && act_format == 32 && nitems >= 2) {
3791+ ptr = (glong *) data;
3792+
3793+ if (natural_scroll) {
3794+ ptr[0] = -abs(ptr[0]);
3795+ ptr[1] = -abs(ptr[1]);
3796+ } else {
3797+ ptr[0] = abs(ptr[0]);
3798+ ptr[1] = abs(ptr[1]);
3799+ }
3800+
3801+ XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
3802+ scrolling_distance, XA_INTEGER, act_format,
3803+ PropModeReplace, data, nitems);
3804+ }
3805+
3806+ if (gdk_error_trap_pop ())
3807+ g_warning ("Error setting %s for \"%s\"",
3808+ natural_scroll ? "natural (reverse) scroll" : "normal scroll",
3809+ gdk_device_get_name (device));
3810+
3811+ if (rc == Success)
3812+ XFree (data);
3813+
3814+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
3815+}
3816+
3817+static void
3818+mouse_callback (GSettings *settings,
3819+ const gchar *key,
3820+ GsdMouseManager *manager)
3821+{
3822+ GList *devices, *l;
3823+
3824+ if (g_str_equal (key, KEY_DWELL_CLICK_ENABLED) ||
3825+ g_str_equal (key, KEY_SECONDARY_CLICK_ENABLED)) {
3826+ set_mousetweaks_daemon (manager,
3827+ g_settings_get_boolean (settings, KEY_DWELL_CLICK_ENABLED),
3828+ g_settings_get_boolean (settings, KEY_SECONDARY_CLICK_ENABLED));
3829+ return;
3830+ } else if (g_str_equal (key, KEY_LOCATE_POINTER)) {
3831+ set_locate_pointer (manager, g_settings_get_boolean (settings, KEY_LOCATE_POINTER));
3832+ return;
3833+ }
3834+
3835+ devices = gdk_device_manager_list_devices (manager->priv->device_manager, GDK_DEVICE_TYPE_SLAVE);
3836+
3837+ for (l = devices; l != NULL; l = l->next) {
3838+ GdkDevice *device = l->data;
3839+
3840+ if (device_is_ignored (manager, device))
3841+ continue;
3842+
3843+ if (g_str_equal (key, KEY_LEFT_HANDED)) {
3844+ gboolean mouse_left_handed;
3845+ mouse_left_handed = g_settings_get_boolean (settings, KEY_LEFT_HANDED);
3846+ set_left_handed (manager, device, mouse_left_handed, get_touchpad_handedness (manager, mouse_left_handed));
3847+ } else if (g_str_equal (key, KEY_MOTION_ACCELERATION) ||
3848+ g_str_equal (key, KEY_MOTION_THRESHOLD)) {
3849+ set_motion (manager, device);
3850+ } else if (g_str_equal (key, KEY_MIDDLE_BUTTON_EMULATION)) {
3851+ set_middle_button (manager, device, g_settings_get_boolean (settings, KEY_MIDDLE_BUTTON_EMULATION));
3852+ }
3853+ }
3854+ g_list_free (devices);
3855+}
3856+
3857+static void
3858+touchpad_callback (GSettings *settings,
3859+ const gchar *key,
3860+ GsdMouseManager *manager)
3861+{
3862+ GList *devices, *l;
3863+
3864+ if (g_str_equal (key, KEY_TOUCHPAD_DISABLE_W_TYPING)) {
3865+ set_disable_w_typing (manager, g_settings_get_boolean (manager->priv->touchpad_settings, key));
3866+ return;
3867+ }
3868+
3869+ devices = gdk_device_manager_list_devices (manager->priv->device_manager, GDK_DEVICE_TYPE_SLAVE);
3870+
3871+ for (l = devices; l != NULL; l = l->next) {
3872+ GdkDevice *device = l->data;
3873+
3874+ if (device_is_ignored (manager, device))
3875+ continue;
3876+
3877+ if (g_str_equal (key, KEY_TAP_TO_CLICK)) {
3878+ set_tap_to_click (device, g_settings_get_boolean (settings, key),
3879+ g_settings_get_boolean (manager->priv->touchpad_settings, KEY_LEFT_HANDED));
3880+ } else if (g_str_equal (key, KEY_SCROLL_METHOD)) {
3881+ set_edge_scroll (device, g_settings_get_enum (settings, key));
3882+ set_horiz_scroll (device, g_settings_get_boolean (settings, KEY_PAD_HORIZ_SCROLL));
3883+ } else if (g_str_equal (key, KEY_PAD_HORIZ_SCROLL)) {
3884+ set_horiz_scroll (device, g_settings_get_boolean (settings, key));
3885+ } else if (g_str_equal (key, KEY_TOUCHPAD_ENABLED)) {
3886+ if (g_settings_get_boolean (settings, key) == FALSE)
3887+ set_touchpad_disabled (device);
3888+ else
3889+ set_touchpad_enabled (gdk_x11_device_get_id (device));
3890+ } else if (g_str_equal (key, KEY_MOTION_ACCELERATION) ||
3891+ g_str_equal (key, KEY_MOTION_THRESHOLD)) {
3892+ set_motion (manager, device);
3893+ } else if (g_str_equal (key, KEY_LEFT_HANDED)) {
3894+ gboolean mouse_left_handed;
3895+ mouse_left_handed = g_settings_get_boolean (manager->priv->mouse_settings, KEY_LEFT_HANDED);
3896+ set_left_handed (manager, device, mouse_left_handed, get_touchpad_handedness (manager, mouse_left_handed));
3897+ } else if (g_str_equal (key, KEY_NATURAL_SCROLL_ENABLED)) {
3898+ set_natural_scroll (manager, device, g_settings_get_boolean (settings, key));
3899+ }
3900+ }
3901+ g_list_free (devices);
3902+
3903+ if (g_str_equal (key, KEY_TOUCHPAD_ENABLED) &&
3904+ g_settings_get_boolean (settings, key)) {
3905+ devices = get_disabled_devices (manager->priv->device_manager);
3906+ for (l = devices; l != NULL; l = l->next) {
3907+ int device_id;
3908+
3909+ device_id = GPOINTER_TO_INT (l->data);
3910+ set_touchpad_enabled (device_id);
3911+ }
3912+ g_list_free (devices);
3913+ }
3914+}
3915+
3916+static void
3917+device_added_cb (GdkDeviceManager *device_manager,
3918+ GdkDevice *device,
3919+ GsdMouseManager *manager)
3920+{
3921+ if (device_is_ignored (manager, device) == FALSE) {
3922+ if (run_custom_command (device, COMMAND_DEVICE_ADDED) == FALSE) {
3923+ set_mouse_settings (manager, device);
3924+ } else {
3925+ int id;
3926+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
3927+ g_hash_table_insert (manager->priv->blacklist,
3928+ GINT_TO_POINTER (id), GINT_TO_POINTER (1));
3929+ }
3930+
3931+ /* If a touchpad was to appear... */
3932+ set_disable_w_typing (manager, g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TOUCHPAD_DISABLE_W_TYPING));
3933+ }
3934+}
3935+
3936+static void
3937+device_removed_cb (GdkDeviceManager *device_manager,
3938+ GdkDevice *device,
3939+ GsdMouseManager *manager)
3940+{
3941+ int id;
3942+
3943+ /* Remove the device from the hash table so that
3944+ * device_is_ignored () doesn't check for blacklisted devices */
3945+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
3946+ g_hash_table_remove (manager->priv->blacklist,
3947+ GINT_TO_POINTER (id));
3948+
3949+ if (device_is_ignored (manager, device) == FALSE) {
3950+ run_custom_command (device, COMMAND_DEVICE_REMOVED);
3951+
3952+ /* If a touchpad was to disappear... */
3953+ set_disable_w_typing (manager, g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TOUCHPAD_DISABLE_W_TYPING));
3954+ }
3955+}
3956+
3957+static void
3958+set_devicepresence_handler (GsdMouseManager *manager)
3959+{
3960+ GdkDeviceManager *device_manager;
3961+
3962+ device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
3963+
3964+ manager->priv->device_added_id = g_signal_connect (G_OBJECT (device_manager), "device-added",
3965+ G_CALLBACK (device_added_cb), manager);
3966+ manager->priv->device_removed_id = g_signal_connect (G_OBJECT (device_manager), "device-removed",
3967+ G_CALLBACK (device_removed_cb), manager);
3968+ manager->priv->device_manager = device_manager;
3969+}
3970+
3971+static void
3972+gsd_mouse_manager_init (GsdMouseManager *manager)
3973+{
3974+ manager->priv = GSD_MOUSE_MANAGER_GET_PRIVATE (manager);
3975+ manager->priv->blacklist = g_hash_table_new (g_direct_hash, g_direct_equal);
3976+}
3977+
3978+static gboolean
3979+gsd_mouse_manager_idle_cb (GsdMouseManager *manager)
3980+{
3981+ GList *devices, *l;
3982+
3983+ gnome_settings_profile_start (NULL);
3984+
3985+ set_devicepresence_handler (manager);
3986+
3987+ manager->priv->mouse_settings = g_settings_new (SETTINGS_MOUSE_DIR);
3988+ g_signal_connect (manager->priv->mouse_settings, "changed",
3989+ G_CALLBACK (mouse_callback), manager);
3990+
3991+ manager->priv->mouse_a11y_settings = g_settings_new ("org.gnome.desktop.a11y.mouse");
3992+ g_signal_connect (manager->priv->mouse_a11y_settings, "changed",
3993+ G_CALLBACK (mouse_callback), manager);
3994+
3995+ manager->priv->touchpad_settings = g_settings_new (SETTINGS_TOUCHPAD_DIR);
3996+ g_signal_connect (manager->priv->touchpad_settings, "changed",
3997+ G_CALLBACK (touchpad_callback), manager);
3998+
3999+ manager->priv->syndaemon_spawned = FALSE;
4000+
4001+ set_locate_pointer (manager, g_settings_get_boolean (manager->priv->mouse_settings, KEY_LOCATE_POINTER));
4002+ set_mousetweaks_daemon (manager,
4003+ g_settings_get_boolean (manager->priv->mouse_a11y_settings, KEY_DWELL_CLICK_ENABLED),
4004+ g_settings_get_boolean (manager->priv->mouse_a11y_settings, KEY_SECONDARY_CLICK_ENABLED));
4005+ set_disable_w_typing (manager, g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TOUCHPAD_DISABLE_W_TYPING));
4006+
4007+ devices = gdk_device_manager_list_devices (manager->priv->device_manager, GDK_DEVICE_TYPE_SLAVE);
4008+ for (l = devices; l != NULL; l = l->next) {
4009+ GdkDevice *device = l->data;
4010+
4011+ if (device_is_ignored (manager, device))
4012+ continue;
4013+
4014+ if (run_custom_command (device, COMMAND_DEVICE_PRESENT) == FALSE) {
4015+ set_mouse_settings (manager, device);
4016+ } else {
4017+ int id;
4018+ g_object_get (G_OBJECT (device), "device-id", &id, NULL);
4019+ g_hash_table_insert (manager->priv->blacklist,
4020+ GINT_TO_POINTER (id), GINT_TO_POINTER (1));
4021+ }
4022+ }
4023+ g_list_free (devices);
4024+
4025+ if (g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TOUCHPAD_ENABLED)) {
4026+ devices = get_disabled_devices (manager->priv->device_manager);
4027+ for (l = devices; l != NULL; l = l->next) {
4028+ int device_id;
4029+
4030+ device_id = GPOINTER_TO_INT (l->data);
4031+ set_touchpad_enabled (device_id);
4032+ }
4033+ g_list_free (devices);
4034+ }
4035+
4036+ gnome_settings_profile_end (NULL);
4037+
4038+ manager->priv->start_idle_id = 0;
4039+
4040+ return FALSE;
4041+}
4042+
4043+gboolean
4044+gsd_mouse_manager_start (GsdMouseManager *manager,
4045+ GError **error)
4046+{
4047+ gnome_settings_profile_start (NULL);
4048+
4049+ if (!supports_xinput_devices ()) {
4050+ g_debug ("XInput is not supported, not applying any settings");
4051+ return TRUE;
4052+ }
4053+
4054+ manager->priv->start_idle_id = g_idle_add ((GSourceFunc) gsd_mouse_manager_idle_cb, manager);
4055+
4056+ gnome_settings_profile_end (NULL);
4057+
4058+ return TRUE;
4059+}
4060+
4061+void
4062+gsd_mouse_manager_stop (GsdMouseManager *manager)
4063+{
4064+ GsdMouseManagerPrivate *p = manager->priv;
4065+
4066+ g_debug ("Stopping mouse manager");
4067+
4068+ if (p->device_manager != NULL) {
4069+ g_signal_handler_disconnect (p->device_manager, p->device_added_id);
4070+ g_signal_handler_disconnect (p->device_manager, p->device_removed_id);
4071+ p->device_manager = NULL;
4072+ }
4073+
4074+ if (p->mouse_a11y_settings != NULL) {
4075+ g_object_unref (p->mouse_a11y_settings);
4076+ p->mouse_a11y_settings = NULL;
4077+ }
4078+
4079+ if (p->mouse_settings != NULL) {
4080+ g_object_unref (p->mouse_settings);
4081+ p->mouse_settings = NULL;
4082+ }
4083+
4084+ if (p->touchpad_settings != NULL) {
4085+ g_object_unref (p->touchpad_settings);
4086+ p->touchpad_settings = NULL;
4087+ }
4088+
4089+ set_locate_pointer (manager, FALSE);
4090+}
4091+
4092+static void
4093+gsd_mouse_manager_finalize (GObject *object)
4094+{
4095+ GsdMouseManager *mouse_manager;
4096+
4097+ g_return_if_fail (object != NULL);
4098+ g_return_if_fail (GSD_IS_MOUSE_MANAGER (object));
4099+
4100+ mouse_manager = GSD_MOUSE_MANAGER (object);
4101+
4102+ g_return_if_fail (mouse_manager->priv != NULL);
4103+
4104+ if (mouse_manager->priv->blacklist != NULL)
4105+ g_hash_table_destroy (mouse_manager->priv->blacklist);
4106+
4107+ if (mouse_manager->priv->start_idle_id != 0)
4108+ g_source_remove (mouse_manager->priv->start_idle_id);
4109+
4110+ if (mouse_manager->priv->device_manager != NULL) {
4111+ g_signal_handler_disconnect (mouse_manager->priv->device_manager, mouse_manager->priv->device_added_id);
4112+ g_signal_handler_disconnect (mouse_manager->priv->device_manager, mouse_manager->priv->device_removed_id);
4113+ }
4114+
4115+ if (mouse_manager->priv->mouse_settings != NULL)
4116+ g_object_unref (mouse_manager->priv->mouse_settings);
4117+
4118+ if (mouse_manager->priv->mouse_a11y_settings != NULL)
4119+ g_object_unref (mouse_manager->priv->mouse_a11y_settings);
4120+
4121+ if (mouse_manager->priv->touchpad_settings != NULL)
4122+ g_object_unref (mouse_manager->priv->touchpad_settings);
4123+
4124+ G_OBJECT_CLASS (gsd_mouse_manager_parent_class)->finalize (object);
4125+}
4126+
4127+GsdMouseManager *
4128+gsd_mouse_manager_new (void)
4129+{
4130+ if (manager_object != NULL) {
4131+ g_object_ref (manager_object);
4132+ } else {
4133+ manager_object = g_object_new (GSD_TYPE_MOUSE_MANAGER, NULL);
4134+ g_object_add_weak_pointer (manager_object,
4135+ (gpointer *) &manager_object);
4136+ }
4137+
4138+ return GSD_MOUSE_MANAGER (manager_object);
4139+}
4140
4141=== modified file 'debian/changelog'
4142--- debian/changelog 2013-08-29 11:14:56 +0000
4143+++ debian/changelog 2013-08-29 18:58:42 +0000
4144@@ -1,3 +1,10 @@
4145+gnome-settings-daemon (3.6.4-0ubuntu20) saucy; urgency=low
4146+
4147+ * "Disable while typing" should disable cursor movements (LP: #1215463),
4148+ debian/patches/tune-syndaemon.patch: Launch syndaemon with '-i 0.5 -K -R'
4149+
4150+ -- Jason Gerard DeRose <jason@system76.com> Thu, 29 Aug 2013 12:56:37 -0600
4151+
4152 gnome-settings-daemon (3.6.4-0ubuntu19) saucy; urgency=low
4153
4154 * Install the ibus dbus service (LP: #1194138)
4155
4156=== modified file 'debian/patches/series'
4157--- debian/patches/series 2013-08-29 16:10:41 +0000
4158+++ debian/patches/series 2013-08-29 18:58:42 +0000
4159@@ -31,3 +31,4 @@
4160 git_keyboard_Adapt_to_gnome_xkb_info_API_change.patch
4161 git_keyboard_Adapt_to_gnome_xkb_info_API_change_2.patch
4162 git_keybindings_add_screen_reader_toggle.patch
4163+tune-syndaemon.patch
4164
4165=== added file 'debian/patches/tune-syndaemon.patch'
4166--- debian/patches/tune-syndaemon.patch 1970-01-01 00:00:00 +0000
4167+++ debian/patches/tune-syndaemon.patch 2013-08-29 18:58:42 +0000
4168@@ -0,0 +1,20 @@
4169+Description: Tweaks syndaemon arguments so it disables cursor movement when typing
4170+Author: Jason Gerard DeRose <jason@system76.com>
4171+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1215463
4172+Forwarded: no
4173+Last-Update: 2013-08-26
4174+
4175+---
4176+
4177+--- a/plugins/mouse/gsd-mouse-manager.c
4178++++ b/plugins/mouse/gsd-mouse-manager.c
4179+@@ -583,8 +583,7 @@
4180+
4181+ g_ptr_array_add (args, "syndaemon");
4182+ g_ptr_array_add (args, "-i");
4183+- g_ptr_array_add (args, "1.0");
4184+- g_ptr_array_add (args, "-t");
4185++ g_ptr_array_add (args, "0.5");
4186+ g_ptr_array_add (args, "-K");
4187+ g_ptr_array_add (args, "-R");
4188+ g_ptr_array_add (args, NULL);
4189
4190=== modified file 'plugins/mouse/gsd-mouse-manager.c'
4191--- plugins/mouse/gsd-mouse-manager.c 2012-11-21 17:16:23 +0000
4192+++ plugins/mouse/gsd-mouse-manager.c 2013-08-29 18:58:42 +0000
4193@@ -583,8 +583,7 @@
4194
4195 g_ptr_array_add (args, "syndaemon");
4196 g_ptr_array_add (args, "-i");
4197- g_ptr_array_add (args, "1.0");
4198- g_ptr_array_add (args, "-t");
4199+ g_ptr_array_add (args, "0.5");
4200 g_ptr_array_add (args, "-K");
4201 g_ptr_array_add (args, "-R");
4202 g_ptr_array_add (args, NULL);

Subscribers

People subscribed via source and target branches