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