diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | data/init.in | 1 | ||||
-rw-r--r-- | data/keys | 6 | ||||
-rw-r--r-- | src/FbCommandFactory.cc | 3 | ||||
-rw-r--r-- | src/FbCommands.cc | 9 | ||||
-rw-r--r-- | src/FbCommands.hh | 5 | ||||
-rw-r--r-- | src/FbTk/KeyUtil.cc | 7 | ||||
-rw-r--r-- | src/FbTk/KeyUtil.hh | 1 | ||||
-rw-r--r-- | src/Keys.cc | 95 | ||||
-rw-r--r-- | src/Keys.hh | 43 | ||||
-rw-r--r-- | src/Screen.cc | 2 | ||||
-rw-r--r-- | src/Screen.hh | 2 | ||||
-rw-r--r-- | src/WorkspaceCmd.cc | 66 | ||||
-rw-r--r-- | src/fluxbox.cc | 98 | ||||
-rw-r--r-- | util/Makefile.am | 12 | ||||
-rw-r--r-- | util/fluxbox-update_configs.cc | 197 |
16 files changed, 433 insertions, 127 deletions
@@ -1,5 +1,18 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 1.0rc3: | 2 | Changes for 1.0rc3: |
3 | *07/02/09: | ||
4 | * Introduced support for mouse buttons in the keys file (Mark) | ||
5 | - Mouse buttons are bound to new `keys' Mouse1, Mouse2, etc. | ||
6 | - Also a new modifier `OnDesktop' to specify actions that should take place | ||
7 | when you click on the desktop -- without this, mouse bindings are global | ||
8 | - Obviously, more modifiers are planned, so don't ask | ||
9 | - Introduced new command HideMenus | ||
10 | - Added a utility to the project that automatically updates configuration | ||
11 | files when we change the syntax -- your current mouse bindings on the | ||
12 | desktop will be added to your keys file automatically | ||
13 | FbCommands.cc/hh FbCommandFactory.cc Keys.cc/hh Screen.cc/hh fluxbox.cc | ||
14 | FbTk/KeyUtil.cc/hh WorkspaceCmd.cc data/init.in data/keys util/Makefile.am | ||
15 | Added util/fluxbox-update_configs.cc | ||
3 | *07/02/06: | 16 | *07/02/06: |
4 | * Wrong window was being raised when attaching an unfocused window (Mark) | 17 | * Wrong window was being raised when attaching an unfocused window (Mark) |
5 | Window.cc | 18 | Window.cc |
diff --git a/data/init.in b/data/init.in index 278ac80..76b4e08 100644 --- a/data/init.in +++ b/data/init.in | |||
@@ -33,3 +33,4 @@ session.colorsPerChannel: 4 | |||
33 | session.doubleClickInterval: 250 | 33 | session.doubleClickInterval: 250 |
34 | session.cacheMax: 200 | 34 | session.cacheMax: 200 |
35 | session.imageDither: True | 35 | session.imageDither: True |
36 | session.configVersion: 1 | ||
@@ -1,3 +1,9 @@ | |||
1 | OnDesktop Mouse1 :HideMenus | ||
2 | OnDesktop Mouse2 :WorkspaceMenu | ||
3 | OnDesktop Mouse3 :RootMenu | ||
4 | OnDesktop Mouse4 :NextWorkspace | ||
5 | OnDesktop Mouse5 :PrevWorkspace | ||
6 | |||
1 | Mod1 Tab :NextWindow | 7 | Mod1 Tab :NextWindow |
2 | Mod1 Shift Tab :PrevWindow | 8 | Mod1 Shift Tab :PrevWindow |
3 | Mod1 F1 :Workspace 1 | 9 | Mod1 F1 :Workspace 1 |
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index b82332a..2f05e5a 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc | |||
@@ -77,6 +77,7 @@ FbCommandFactory::FbCommandFactory() { | |||
77 | "focusleft", | 77 | "focusleft", |
78 | "focusright", | 78 | "focusright", |
79 | "fullscreen", | 79 | "fullscreen", |
80 | "hidemenus", | ||
80 | "iconify", | 81 | "iconify", |
81 | "keymode", | 82 | "keymode", |
82 | "killwindow", | 83 | "killwindow", |
@@ -433,6 +434,8 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
433 | return new ArrangeWindowsCmd(); | 434 | return new ArrangeWindowsCmd(); |
434 | else if (command == "showdesktop") | 435 | else if (command == "showdesktop") |
435 | return new ShowDesktopCmd(); | 436 | return new ShowDesktopCmd(); |
437 | else if (command == "hidemenus") | ||
438 | return new HideMenuCmd(); | ||
436 | else if (command == "rootmenu") | 439 | else if (command == "rootmenu") |
437 | return new ShowRootMenuCmd(); | 440 | return new ShowRootMenuCmd(); |
438 | else if (command == "workspacemenu") | 441 | else if (command == "workspacemenu") |
diff --git a/src/FbCommands.cc b/src/FbCommands.cc index 5fbceab..692e12f 100644 --- a/src/FbCommands.cc +++ b/src/FbCommands.cc | |||
@@ -260,6 +260,15 @@ void KeyModeCmd::execute() { | |||
260 | Fluxbox::instance()->keys()->keyMode(m_keymode); | 260 | Fluxbox::instance()->keys()->keyMode(m_keymode); |
261 | } | 261 | } |
262 | 262 | ||
263 | void HideMenuCmd::execute() { | ||
264 | BScreen *screen = Fluxbox::instance()->mouseScreen(); | ||
265 | screen->hideMenus(); | ||
266 | if (screen->rootMenu().isVisible()) | ||
267 | screen->rootMenu().hide(); | ||
268 | if (screen->workspaceMenu().isVisible()) | ||
269 | screen->workspaceMenu().hide(); | ||
270 | } | ||
271 | |||
263 | void ShowRootMenuCmd::execute() { | 272 | void ShowRootMenuCmd::execute() { |
264 | BScreen *screen = Fluxbox::instance()->mouseScreen(); | 273 | BScreen *screen = Fluxbox::instance()->mouseScreen(); |
265 | if (screen == 0) | 274 | if (screen == 0) |
diff --git a/src/FbCommands.hh b/src/FbCommands.hh index 8ac40fa..59200d2 100644 --- a/src/FbCommands.hh +++ b/src/FbCommands.hh | |||
@@ -113,6 +113,11 @@ private: | |||
113 | std::string m_end_args; | 113 | std::string m_end_args; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | class HideMenuCmd: public FbTk::Command { | ||
117 | public: | ||
118 | void execute(); | ||
119 | }; | ||
120 | |||
116 | class ShowRootMenuCmd: public FbTk::Command { | 121 | class ShowRootMenuCmd: public FbTk::Command { |
117 | public: | 122 | public: |
118 | void execute(); | 123 | void execute(); |
diff --git a/src/FbTk/KeyUtil.cc b/src/FbTk/KeyUtil.cc index 3f413a9..6985139 100644 --- a/src/FbTk/KeyUtil.cc +++ b/src/FbTk/KeyUtil.cc | |||
@@ -138,7 +138,7 @@ void KeyUtil::grabButton(unsigned int button, unsigned int mod, Window win, | |||
138 | for (int i = 0; i < 8; i++) { | 138 | for (int i = 0; i < 8; i++) { |
139 | XGrabButton(display, button, mod | (i & 1 ? capsmod : 0) | | 139 | XGrabButton(display, button, mod | (i & 1 ? capsmod : 0) | |
140 | (i & 2 ? nummod : 0) | (i & 4 ? scrollmod : 0), | 140 | (i & 2 ? nummod : 0) | (i & 4 ? scrollmod : 0), |
141 | win, True, event_mask, GrabModeAsync, GrabModeAsync, | 141 | win, False, event_mask, GrabModeAsync, GrabModeAsync, |
142 | None, cursor); | 142 | None, cursor); |
143 | } | 143 | } |
144 | 144 | ||
@@ -180,6 +180,11 @@ void KeyUtil::ungrabKeys(Window win) { | |||
180 | XUngrabKey(display, AnyKey, AnyModifier, win); | 180 | XUngrabKey(display, AnyKey, AnyModifier, win); |
181 | } | 181 | } |
182 | 182 | ||
183 | void KeyUtil::ungrabButtons(Window win) { | ||
184 | Display * display = App::instance()->display(); | ||
185 | XUngrabButton(display, AnyButton, AnyModifier, win); | ||
186 | } | ||
187 | |||
183 | unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { | 188 | unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { |
184 | XModifierKeymap *modmap = instance().m_modmap; | 189 | XModifierKeymap *modmap = instance().m_modmap; |
185 | 190 | ||
diff --git a/src/FbTk/KeyUtil.hh b/src/FbTk/KeyUtil.hh index eb2cdd5..4909c5a 100644 --- a/src/FbTk/KeyUtil.hh +++ b/src/FbTk/KeyUtil.hh | |||
@@ -62,6 +62,7 @@ public: | |||
62 | ungrabs all keys | 62 | ungrabs all keys |
63 | */ | 63 | */ |
64 | static void ungrabKeys(Window win); | 64 | static void ungrabKeys(Window win); |
65 | static void ungrabButtons(Window win); | ||
65 | 66 | ||
66 | /** | 67 | /** |
67 | Strip out modifiers we want to ignore | 68 | Strip out modifiers we want to ignore |
diff --git a/src/Keys.cc b/src/Keys.cc index e7b7acd..dbcff67 100644 --- a/src/Keys.cc +++ b/src/Keys.cc | |||
@@ -114,6 +114,7 @@ Keys::Keys(): | |||
114 | 114 | ||
115 | Keys::~Keys() { | 115 | Keys::~Keys() { |
116 | ungrabKeys(); | 116 | ungrabKeys(); |
117 | ungrabButtons(); | ||
117 | deleteTree(); | 118 | deleteTree(); |
118 | } | 119 | } |
119 | 120 | ||
@@ -140,6 +141,23 @@ void Keys::ungrabKeys() { | |||
140 | FbTk::KeyUtil::ungrabKeys(*it); | 141 | FbTk::KeyUtil::ungrabKeys(*it); |
141 | } | 142 | } |
142 | 143 | ||
144 | void Keys::grabButton(unsigned int button, unsigned int mod) { | ||
145 | std::list<Window>::iterator it = m_window_list.begin(); | ||
146 | std::list<Window>::iterator it_end = m_window_list.end(); | ||
147 | |||
148 | for (; it != it_end; ++it) | ||
149 | FbTk::KeyUtil::grabButton(button, mod, *it, | ||
150 | ButtonPressMask|ButtonReleaseMask); | ||
151 | } | ||
152 | |||
153 | void Keys::ungrabButtons() { | ||
154 | std::list<Window>::iterator it = m_window_list.begin(); | ||
155 | std::list<Window>::iterator it_end = m_window_list.end(); | ||
156 | |||
157 | for (; it != it_end; ++it) | ||
158 | FbTk::KeyUtil::ungrabButtons(*it); | ||
159 | } | ||
160 | |||
143 | /** | 161 | /** |
144 | Load and grab keys | 162 | Load and grab keys |
145 | TODO: error checking | 163 | TODO: error checking |
@@ -152,7 +170,7 @@ bool Keys::load(const char *filename) { | |||
152 | //free memory of previous grabs | 170 | //free memory of previous grabs |
153 | deleteTree(); | 171 | deleteTree(); |
154 | 172 | ||
155 | m_map["default:"] = new t_key(0,0); | 173 | m_map["default:"] = new t_key(0,0,0,0); |
156 | 174 | ||
157 | FbTk::App::instance()->sync(false); | 175 | FbTk::App::instance()->sync(false); |
158 | 176 | ||
@@ -211,6 +229,7 @@ bool Keys::addBinding(const string &linebuffer) { | |||
211 | return true; // still a valid line. | 229 | return true; // still a valid line. |
212 | 230 | ||
213 | unsigned int key = 0, mod = 0; | 231 | unsigned int key = 0, mod = 0; |
232 | int type = 0, context = 0; | ||
214 | size_t argc = 0; | 233 | size_t argc = 0; |
215 | t_key *current_key=m_map["default:"]; | 234 | t_key *current_key=m_map["default:"]; |
216 | t_key *first_new_keylist = current_key, *first_new_key=0; | 235 | t_key *first_new_keylist = current_key, *first_new_key=0; |
@@ -219,7 +238,7 @@ bool Keys::addBinding(const string &linebuffer) { | |||
219 | argc++; | 238 | argc++; |
220 | keyspace_t::iterator it = m_map.find(val[0]); | 239 | keyspace_t::iterator it = m_map.find(val[0]); |
221 | if (it == m_map.end()) | 240 | if (it == m_map.end()) |
222 | m_map[val[0]] = new t_key(0,0); | 241 | m_map[val[0]] = new t_key(0,0,0,0); |
223 | current_key = m_map[val[0]]; | 242 | current_key = m_map[val[0]]; |
224 | } | 243 | } |
225 | // for each argument | 244 | // for each argument |
@@ -230,41 +249,53 @@ bool Keys::addBinding(const string &linebuffer) { | |||
230 | int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str()); | 249 | int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str()); |
231 | if(tmpmod) | 250 | if(tmpmod) |
232 | mod |= tmpmod; //If it's a modifier | 251 | mod |= tmpmod; //If it's a modifier |
252 | else if (strcasecmp("ondesktop", val[argc].c_str()) == 0) | ||
253 | context |= ON_DESKTOP; | ||
233 | else if (strcasecmp("NONE",val[argc].c_str())) { | 254 | else if (strcasecmp("NONE",val[argc].c_str())) { |
255 | // check if it's a mouse button | ||
256 | if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") && | ||
257 | val[argc].length() > 5) { | ||
258 | type = ButtonPress; | ||
259 | key = atoi(val[argc].substr(5,val[argc].length()-5).c_str()); | ||
234 | // keycode covers the following three two-byte cases: | 260 | // keycode covers the following three two-byte cases: |
235 | // 0x - hex | 261 | // 0x - hex |
236 | // +[1-9] - number between +1 and +9 | 262 | // +[1-9] - number between +1 and +9 |
237 | // numbers 10 and above | 263 | // numbers 10 and above |
238 | // | 264 | // |
239 | if (val[argc].size() > 1 && (isdigit(val[argc][0]) && | 265 | } else if (val[argc].size() > 1 && (isdigit(val[argc][0]) && |
240 | (isdigit(val[argc][1]) || val[argc][1] == 'x') || | 266 | (isdigit(val[argc][1]) || val[argc][1] == 'x') || |
241 | val[argc][0] == '+' && isdigit(val[argc][1])) ) { | 267 | val[argc][0] == '+' && isdigit(val[argc][1])) ) { |
242 | 268 | ||
243 | key = strtoul(val[argc].c_str(), NULL, 0); | 269 | key = strtoul(val[argc].c_str(), NULL, 0); |
270 | type = KeyPress; | ||
244 | 271 | ||
245 | if (errno == EINVAL || errno == ERANGE) | 272 | if (errno == EINVAL || errno == ERANGE) |
246 | key = 0; | 273 | key = 0; |
247 | 274 | ||
248 | } else // convert from string symbol | 275 | } else { // convert from string symbol |
249 | key = FbTk::KeyUtil::getKey(val[argc].c_str()); | 276 | key = FbTk::KeyUtil::getKey(val[argc].c_str()); |
277 | type = KeyPress; | ||
278 | } | ||
250 | 279 | ||
251 | if (key == 0) | 280 | if (key == 0) |
252 | return false; | 281 | return false; |
253 | if (!first_new_key) { | 282 | if (!first_new_key) { |
254 | first_new_keylist = current_key; | 283 | first_new_keylist = current_key; |
255 | current_key = current_key->find(key, mod); | 284 | current_key = current_key->find(type, mod, key, context); |
256 | if (!current_key) { | 285 | if (!current_key) { |
257 | first_new_key = new t_key(key, mod); | 286 | first_new_key = new t_key(type, mod, key, context); |
258 | current_key = first_new_key; | 287 | current_key = first_new_key; |
259 | } else if (*current_key->m_command) // already being used | 288 | } else if (*current_key->m_command) // already being used |
260 | return false; | 289 | return false; |
261 | } else { | 290 | } else { |
262 | t_key *temp_key = new t_key(key, mod); | 291 | t_key *temp_key = new t_key(type, mod, key, context); |
263 | current_key->keylist.push_back(temp_key); | 292 | current_key->keylist.push_back(temp_key); |
264 | current_key = temp_key; | 293 | current_key = temp_key; |
265 | } | 294 | } |
266 | mod = 0; | 295 | mod = 0; |
267 | key = 0; | 296 | key = 0; |
297 | type = 0; | ||
298 | context = 0; | ||
268 | } | 299 | } |
269 | 300 | ||
270 | } else { // parse command line | 301 | } else { // parse command line |
@@ -291,36 +322,43 @@ bool Keys::addBinding(const string &linebuffer) { | |||
291 | } | 322 | } |
292 | 323 | ||
293 | // return true if bound to a command, else false | 324 | // return true if bound to a command, else false |
294 | bool Keys::doAction(XKeyEvent &ke) { | 325 | bool Keys::doAction(int type, unsigned int mods, unsigned int key) { |
295 | |||
296 | ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state); | ||
297 | 326 | ||
298 | static t_key* next_key = m_keylist; | 327 | static t_key* next_key = m_keylist; |
299 | if (!next_key) | 328 | if (!next_key) |
300 | next_key = m_keylist; | 329 | next_key = m_keylist; |
301 | t_key *temp_key = next_key->find(ke); | ||
302 | 330 | ||
331 | mods = FbTk::KeyUtil::instance().cleanMods(mods); | ||
332 | // at the moment, any key/button that gets here is on root window | ||
333 | // context will need to be added as an argument to doAction, though | ||
334 | t_key *temp_key = next_key->find(type, mods, key, ON_DESKTOP|GLOBAL); | ||
303 | 335 | ||
304 | // need to save this for emacs-style keybindings | 336 | // need to save this for emacs-style keybindings |
305 | static t_key *saved_keymode = 0; | 337 | static t_key *saved_keymode = 0; |
306 | 338 | ||
339 | // grab "None Escape" to exit keychain in the middle | ||
340 | unsigned int esc = FbTk::KeyUtil::getKey("Escape"); | ||
341 | |||
307 | if (temp_key && temp_key->keylist.size()) { // emacs-style | 342 | if (temp_key && temp_key->keylist.size()) { // emacs-style |
308 | saved_keymode = m_keylist; | 343 | if (!saved_keymode) |
344 | saved_keymode = m_keylist; | ||
309 | next_key = temp_key; | 345 | next_key = temp_key; |
310 | setKeyMode(next_key); | 346 | setKeyMode(next_key); |
311 | // grab "None Escape" to exit keychain in the middle | ||
312 | unsigned int esc = FbTk::KeyUtil::getKey("Escape"); | ||
313 | grabKey(esc,0); | 347 | grabKey(esc,0); |
314 | return true; | 348 | return true; |
315 | } | 349 | } |
316 | if (!temp_key || *temp_key->m_command == 0) { | 350 | if (!temp_key || *temp_key->m_command == 0) { |
317 | next_key = 0; | 351 | if (type == KeyPress && key == esc && mods == 0) { |
318 | if (saved_keymode) { | 352 | // if we're in the middle of an emacs-style keychain, exit it |
319 | setKeyMode(saved_keymode); | 353 | next_key = 0; |
320 | saved_keymode = 0; | 354 | if (saved_keymode) { |
355 | setKeyMode(saved_keymode); | ||
356 | saved_keymode = 0; | ||
357 | } | ||
321 | } | 358 | } |
322 | return false; | 359 | return false; |
323 | } | 360 | } |
361 | |||
324 | temp_key->m_command->execute(); | 362 | temp_key->m_command->execute(); |
325 | if (saved_keymode) { | 363 | if (saved_keymode) { |
326 | if (next_key == m_keylist) // don't reset keymode if command changed it | 364 | if (next_key == m_keylist) // don't reset keymode if command changed it |
@@ -349,22 +387,33 @@ void Keys::keyMode(string keyMode) { | |||
349 | 387 | ||
350 | void Keys::setKeyMode(t_key *keyMode) { | 388 | void Keys::setKeyMode(t_key *keyMode) { |
351 | ungrabKeys(); | 389 | ungrabKeys(); |
390 | ungrabButtons(); | ||
352 | keylist_t::iterator it = keyMode->keylist.begin(); | 391 | keylist_t::iterator it = keyMode->keylist.begin(); |
353 | keylist_t::iterator it_end = keyMode->keylist.end(); | 392 | keylist_t::iterator it_end = keyMode->keylist.end(); |
354 | for (; it != it_end; ++it) | 393 | for (; it != it_end; ++it) { |
355 | grabKey((*it)->key,(*it)->mod); | 394 | if ((*it)->type == KeyPress) |
395 | grabKey((*it)->key,(*it)->mod); | ||
396 | else if ((*it)->context == GLOBAL) | ||
397 | grabButton((*it)->key,(*it)->mod); | ||
398 | // we must use root window's event mask to get ON_DESKTOP events | ||
399 | } | ||
356 | m_keylist = keyMode; | 400 | m_keylist = keyMode; |
357 | } | 401 | } |
358 | 402 | ||
359 | Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) { | 403 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, |
404 | int context_, FbTk::RefCount<FbTk::Command> command) { | ||
360 | key = key_; | 405 | key = key_; |
361 | mod = mod_; | 406 | mod = mod_; |
407 | type = type_; | ||
408 | context = context_ ? context_ : GLOBAL; | ||
362 | m_command = command; | 409 | m_command = command; |
363 | } | 410 | } |
364 | 411 | ||
365 | Keys::t_key::t_key(t_key *k) { | 412 | Keys::t_key::t_key(t_key *k) { |
366 | key = k->key; | 413 | key = k->key; |
367 | mod = k->mod; | 414 | mod = k->mod; |
415 | type = k->type; | ||
416 | context = k->context; | ||
368 | m_command = k->m_command; | 417 | m_command = k->m_command; |
369 | } | 418 | } |
370 | 419 | ||
diff --git a/src/Keys.hh b/src/Keys.hh index 6602d49..0365cf8 100644 --- a/src/Keys.hh +++ b/src/Keys.hh | |||
@@ -38,6 +38,21 @@ | |||
38 | class Keys:private FbTk::NotCopyable { | 38 | class Keys:private FbTk::NotCopyable { |
39 | public: | 39 | public: |
40 | 40 | ||
41 | // contexts for events | ||
42 | // it's ok if there is overlap; it will be worked out in t_key::find() | ||
43 | // eventHandlers should submit bitwise-or of contexts the event happened in | ||
44 | enum { | ||
45 | GLOBAL = 0x01, | ||
46 | ON_DESKTOP = 0x02, | ||
47 | ON_TOOLBAR = 0x04, | ||
48 | ON_ICONBUTTON = 0x08, | ||
49 | ON_TITLEBAR = 0x10, | ||
50 | ON_WINDOW = 0x20, | ||
51 | ON_TAB = 0x40, | ||
52 | ON_SLIT = 0x80 | ||
53 | // and so on... | ||
54 | }; | ||
55 | |||
41 | /** | 56 | /** |
42 | Constructor | 57 | Constructor |
43 | @param display display connection | 58 | @param display display connection |
@@ -65,7 +80,7 @@ public: | |||
65 | /** | 80 | /** |
66 | do action from XKeyEvent; return false if not bound to anything | 81 | do action from XKeyEvent; return false if not bound to anything |
67 | */ | 82 | */ |
68 | bool doAction(XKeyEvent &ke); | 83 | bool doAction(int type, unsigned int mods, unsigned int key); |
69 | 84 | ||
70 | /** | 85 | /** |
71 | Reload configuration from filename | 86 | Reload configuration from filename |
@@ -79,6 +94,8 @@ private: | |||
79 | 94 | ||
80 | void grabKey(unsigned int key, unsigned int mod); | 95 | void grabKey(unsigned int key, unsigned int mod); |
81 | void ungrabKeys(); | 96 | void ungrabKeys(); |
97 | void grabButton(unsigned int button, unsigned int mod); | ||
98 | void ungrabButtons(); | ||
82 | 99 | ||
83 | std::string m_filename; | 100 | std::string m_filename; |
84 | 101 | ||
@@ -87,33 +104,27 @@ private: | |||
87 | 104 | ||
88 | class t_key { | 105 | class t_key { |
89 | public: | 106 | public: |
90 | t_key(unsigned int key, unsigned int mod, | 107 | t_key(int type, unsigned int mod, unsigned int key, int context, |
91 | FbTk::RefCount<FbTk::Command> command = FbTk::RefCount<FbTk::Command>(0)); | 108 | FbTk::RefCount<FbTk::Command> command = FbTk::RefCount<FbTk::Command>(0)); |
92 | t_key(t_key *k); | 109 | t_key(t_key *k); |
93 | ~t_key(); | 110 | ~t_key(); |
94 | 111 | ||
95 | t_key *find(unsigned int key_, unsigned int mod_) { | 112 | t_key *find(int type_, unsigned int mod_, unsigned int key_, |
96 | for (size_t i = 0; i < keylist.size(); i++) { | 113 | int context_) { |
97 | if (keylist[i]->key == key_ && keylist[i]->mod == FbTk::KeyUtil::instance().isolateModifierMask(mod_)) | ||
98 | return keylist[i]; | ||
99 | } | ||
100 | return 0; | ||
101 | } | ||
102 | t_key *find(XKeyEvent &ke) { | ||
103 | for (size_t i = 0; i < keylist.size(); i++) { | 114 | for (size_t i = 0; i < keylist.size(); i++) { |
104 | if (keylist[i]->key == ke.keycode && | 115 | if (keylist[i]->type == type_ && keylist[i]->key == key_ && |
105 | keylist[i]->mod == FbTk::KeyUtil::instance().isolateModifierMask(ke.state)) | 116 | (keylist[i]->context & context_) > 0 && keylist[i]->mod == |
117 | FbTk::KeyUtil::instance().isolateModifierMask(mod_)) | ||
106 | return keylist[i]; | 118 | return keylist[i]; |
107 | } | 119 | } |
108 | return 0; | 120 | return 0; |
109 | } | 121 | } |
110 | 122 | ||
111 | bool operator == (XKeyEvent &ke) const { | ||
112 | return (mod == FbTk::KeyUtil::instance().isolateModifierMask(ke.state) && key == ke.keycode); | ||
113 | } | ||
114 | 123 | ||
115 | FbTk::RefCount<FbTk::Command> m_command; | 124 | FbTk::RefCount<FbTk::Command> m_command; |
116 | unsigned int key; | 125 | int context; // ON_TITLEBAR, etc.: bitwise-or of all desired contexts |
126 | int type; // KeyPress or ButtonPress | ||
127 | unsigned int key; // key code or button number | ||
117 | unsigned int mod; | 128 | unsigned int mod; |
118 | keylist_t keylist; | 129 | keylist_t keylist; |
119 | }; | 130 | }; |
diff --git a/src/Screen.cc b/src/Screen.cc index d7fc19a..f3a5d01 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -2060,7 +2060,7 @@ void BScreen::renderPosWindow() { | |||
2060 | /** | 2060 | /** |
2061 | Called when a set of watched modifiers has been released | 2061 | Called when a set of watched modifiers has been released |
2062 | */ | 2062 | */ |
2063 | void BScreen::notifyReleasedKeys(XKeyEvent &ke) { | 2063 | void BScreen::notifyReleasedKeys() { |
2064 | focusControl().stopCyclingFocus(); | 2064 | focusControl().stopCyclingFocus(); |
2065 | } | 2065 | } |
2066 | 2066 | ||
diff --git a/src/Screen.hh b/src/Screen.hh index 739c458..de1dc78 100644 --- a/src/Screen.hh +++ b/src/Screen.hh | |||
@@ -294,7 +294,7 @@ public: | |||
294 | void showGeometry(int width, int height); | 294 | void showGeometry(int width, int height); |
295 | void hideGeometry(); | 295 | void hideGeometry(); |
296 | 296 | ||
297 | void notifyReleasedKeys(XKeyEvent &ke); | 297 | void notifyReleasedKeys(); |
298 | 298 | ||
299 | void setLayer(FbTk::XLayerItem &item, int layernum); | 299 | void setLayer(FbTk::XLayerItem &item, int layernum); |
300 | // remove? no, items are never removed from their layer until they die | 300 | // remove? no, items are never removed from their layer until they die |
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index 6c97808..d2bc3b7 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc | |||
@@ -42,44 +42,48 @@ | |||
42 | #include <functional> | 42 | #include <functional> |
43 | 43 | ||
44 | void NextWindowCmd::execute() { | 44 | void NextWindowCmd::execute() { |
45 | BScreen *screen = Fluxbox::instance()->keyScreen(); | 45 | Fluxbox *fb = Fluxbox::instance(); |
46 | BScreen *screen = fb->keyScreen(); | ||
46 | if (screen != 0) { | 47 | if (screen != 0) { |
47 | Fluxbox *fb = Fluxbox::instance(); | 48 | // get modifiers from event that causes this for focus order cycling |
48 | // special case for commands from key events | 49 | unsigned int mods = 0; |
49 | if (fb->lastEvent().type == KeyPress) { | 50 | XEvent ev = fb->lastEvent(); |
50 | unsigned int mods = FbTk::KeyUtil::instance().cleanMods(fb->lastEvent().xkey.state); | 51 | if (ev.type == KeyPress) { |
51 | mods = FbTk::KeyUtil::instance().isolateModifierMask(mods); | 52 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xkey.state); |
52 | if (mods == 0) // can't stacked cycle unless there is a mod to grab | 53 | } else if (ev.type == ButtonPress) { |
53 | screen->focusControl().nextFocus(m_option | FocusControl::CYCLELINEAR); | 54 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); |
54 | else { | 55 | } |
55 | // if stacked cycling, then set a watch for | 56 | if (mods == 0) // can't stacked cycle unless there is a mod to grab |
56 | // the release of exactly these modifiers | ||
57 | Fluxbox::instance()->watchKeyRelease(*screen, mods); | ||
58 | screen->focusControl().nextFocus(m_option); | ||
59 | } | ||
60 | } else | ||
61 | screen->focusControl().nextFocus(m_option | FocusControl::CYCLELINEAR); | 57 | screen->focusControl().nextFocus(m_option | FocusControl::CYCLELINEAR); |
58 | else { | ||
59 | // if stacked cycling, then set a watch for | ||
60 | // the release of exactly these modifiers | ||
61 | fb->watchKeyRelease(*screen, mods); | ||
62 | screen->focusControl().nextFocus(m_option); | ||
63 | } | ||
62 | } | 64 | } |
63 | } | 65 | } |
64 | 66 | ||
65 | void PrevWindowCmd::execute() { | 67 | void PrevWindowCmd::execute() { |
66 | BScreen *screen = Fluxbox::instance()->keyScreen(); | 68 | Fluxbox *fb = Fluxbox::instance(); |
69 | BScreen *screen = fb->keyScreen(); | ||
67 | if (screen != 0) { | 70 | if (screen != 0) { |
68 | Fluxbox *fb = Fluxbox::instance(); | 71 | // get modifiers from event that causes this for focus order cycling |
69 | // special case for commands from key events | 72 | unsigned int mods = 0; |
70 | if (fb->lastEvent().type == KeyPress) { | 73 | XEvent ev = fb->lastEvent(); |
71 | unsigned int mods = FbTk::KeyUtil::instance().cleanMods(fb->lastEvent().xkey.state); | 74 | if (ev.type == KeyPress) { |
72 | mods = FbTk::KeyUtil::instance().isolateModifierMask(mods); | 75 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xkey.state); |
73 | if (mods == 0) // can't stacked cycle unless there is a mod to grab | 76 | } else if (ev.type == ButtonPress) { |
74 | screen->focusControl().prevFocus(m_option | FocusControl::CYCLELINEAR); | 77 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); |
75 | else { | 78 | } |
76 | // if stacked cycling, then set a watch for | 79 | if (mods == 0) // can't stacked cycle unless there is a mod to grab |
77 | // the release of exactly these modifiers | 80 | screen->focusControl().prevFocus(m_option | FocusControl::CYCLELINEAR); |
78 | Fluxbox::instance()->watchKeyRelease(*screen, mods); | 81 | else { |
79 | screen->focusControl().prevFocus(m_option); | 82 | // if stacked cycling, then set a watch for |
80 | } | 83 | // the release of exactly these modifiers |
81 | } else | 84 | fb->watchKeyRelease(*screen, mods); |
82 | screen->focusControl().nextFocus(m_option | FocusControl::CYCLELINEAR); | 85 | screen->focusControl().prevFocus(m_option); |
86 | } | ||
83 | } | 87 | } |
84 | } | 88 | } |
85 | 89 | ||
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 89b37fe..7958a27 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc | |||
@@ -649,6 +649,28 @@ void Fluxbox::setupConfigFiles() { | |||
649 | if (create_init) | 649 | if (create_init) |
650 | FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); | 650 | FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); |
651 | 651 | ||
652 | #define CONFIG_VERSION 1 | ||
653 | FbTk::Resource<int> config_version(m_resourcemanager, 0, | ||
654 | "session.configVersion", "Session.ConfigVersion"); | ||
655 | if (*config_version < CONFIG_VERSION) { | ||
656 | // configs are out of date, so run fluxbox-update_configs | ||
657 | |||
658 | string commandargs = "fluxbox-update_configs -rc "; | ||
659 | commandargs += init_file; | ||
660 | |||
661 | #ifdef HAVE_GETPID | ||
662 | // add the fluxbox pid so fbuc can have us reload rc if necessary | ||
663 | pid_t bpid = getpid(); | ||
664 | char intbuff[64]; | ||
665 | sprintf(intbuff, "%d", bpid); | ||
666 | commandargs += " -pid "; | ||
667 | commandargs += intbuff; | ||
668 | #endif // HAVE_GETPID | ||
669 | |||
670 | FbCommands::ExecuteCmd fbuc(commandargs, 0); | ||
671 | fbuc.execute(); | ||
672 | } | ||
673 | |||
652 | } | 674 | } |
653 | 675 | ||
654 | void Fluxbox::handleEvent(XEvent * const e) { | 676 | void Fluxbox::handleEvent(XEvent * const e) { |
@@ -936,59 +958,28 @@ void Fluxbox::handleEvent(XEvent * const e) { | |||
936 | } | 958 | } |
937 | 959 | ||
938 | void Fluxbox::handleButtonEvent(XButtonEvent &be) { | 960 | void Fluxbox::handleButtonEvent(XButtonEvent &be) { |
961 | m_last_time = be.time; | ||
939 | 962 | ||
940 | switch (be.type) { | 963 | BScreen *screen = searchScreen(be.window); |
941 | case ButtonPress: { | 964 | if (be.type == ButtonRelease || !screen) |
942 | m_last_time = be.time; | 965 | // no bindings for this type yet |
943 | 966 | return; | |
944 | BScreen *screen = searchScreen(be.window); | ||
945 | if (screen == 0) | ||
946 | break; // end case | ||
947 | |||
948 | screen->hideMenus(); | ||
949 | 967 | ||
950 | // strip num/caps/scroll-lock and | 968 | if (be.button == 1 && !screen->isRootColormapInstalled()) |
951 | // see if we're using any other modifier, | 969 | screen->imageControl().installRootColormap(); |
952 | // if we're we shouldn't show the root menu | ||
953 | // this could happen if we're resizing aterm for instance | ||
954 | if (FbTk::KeyUtil::instance().cleanMods(be.state) != 0) | ||
955 | return; | ||
956 | 970 | ||
957 | if (be.button == 1) { | 971 | // see if we need to keep watching for key releases |
958 | if (! screen->isRootColormapInstalled()) | 972 | BScreen *old_watching_screen = m_watching_screen; |
959 | screen->imageControl().installRootColormap(); | 973 | m_watching_screen = 0; |
960 | // hide menus | 974 | if (!m_key->doAction(be.type, be.state, be.button)) |
961 | if (screen->rootMenu().isVisible()) | 975 | // no command run, so could still be cycling |
962 | screen->rootMenu().hide(); | 976 | m_watching_screen = old_watching_screen; |
963 | if (screen->workspaceMenu().isVisible()) | 977 | else if (old_watching_screen && |
964 | screen->workspaceMenu().hide(); | 978 | m_watching_screen != old_watching_screen) { |
965 | 979 | // no longer need to watch old screen, so stop cycling | |
966 | } else if (be.button == 2) { | 980 | old_watching_screen->notifyReleasedKeys(); |
967 | FbCommands::ShowWorkspaceMenuCmd cmd; | 981 | if (!m_watching_screen) |
968 | cmd.execute(); | 982 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); |
969 | } else if (be.button == 3) { | ||
970 | FbCommands::ShowRootMenuCmd cmd; | ||
971 | cmd.execute(); | ||
972 | } else if (screen->isDesktopWheeling() && be.button == 4) { | ||
973 | if(screen->isReverseWheeling()) { | ||
974 | screen->prevWorkspace(1); | ||
975 | } else { | ||
976 | screen->nextWorkspace(1); | ||
977 | } | ||
978 | } else if (screen->isDesktopWheeling() && be.button == 5) { | ||
979 | if(screen->isReverseWheeling()) { | ||
980 | screen->nextWorkspace(1); | ||
981 | } else { | ||
982 | screen->prevWorkspace(1); | ||
983 | } | ||
984 | } | ||
985 | |||
986 | } break; | ||
987 | case ButtonRelease: | ||
988 | m_last_time = be.time; | ||
989 | break; | ||
990 | default: | ||
991 | break; | ||
992 | } | 983 | } |
993 | } | 984 | } |
994 | 985 | ||
@@ -1126,11 +1117,12 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1126 | case KeyPress: | 1117 | case KeyPress: |
1127 | // see if we need to keep watching for key releases | 1118 | // see if we need to keep watching for key releases |
1128 | m_watching_screen = 0; | 1119 | m_watching_screen = 0; |
1129 | if (!m_key->doAction(ke)) // could still be cycling | 1120 | if (!m_key->doAction(ke.type, ke.state, ke.keycode)) |
1121 | // no command run, so could still be cycling | ||
1130 | m_watching_screen = old_watching_screen; | 1122 | m_watching_screen = old_watching_screen; |
1131 | else if (old_watching_screen && | 1123 | else if (old_watching_screen && |
1132 | m_watching_screen != old_watching_screen) { | 1124 | m_watching_screen != old_watching_screen) { |
1133 | old_watching_screen->notifyReleasedKeys(ke); | 1125 | old_watching_screen->notifyReleasedKeys(); |
1134 | if (!m_watching_screen) | 1126 | if (!m_watching_screen) |
1135 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); | 1127 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); |
1136 | } | 1128 | } |
@@ -1148,7 +1140,7 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1148 | 1140 | ||
1149 | if ((m_watch_keyrelease & state) == 0) { | 1141 | if ((m_watch_keyrelease & state) == 0) { |
1150 | 1142 | ||
1151 | m_watching_screen->notifyReleasedKeys(ke); | 1143 | m_watching_screen->notifyReleasedKeys(); |
1152 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); | 1144 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); |
1153 | 1145 | ||
1154 | // once they are released, we drop the watch | 1146 | // once they are released, we drop the watch |
diff --git a/util/Makefile.am b/util/Makefile.am index 53a61d7..263c456 100644 --- a/util/Makefile.am +++ b/util/Makefile.am | |||
@@ -2,10 +2,13 @@ | |||
2 | SUBDIRS= fbrun | 2 | SUBDIRS= fbrun |
3 | INCLUDES= -I$(top_srcdir)/src -I$(top_srcdir)/src/FbTk | 3 | INCLUDES= -I$(top_srcdir)/src -I$(top_srcdir)/src/FbTk |
4 | bin_SCRIPTS= fbsetbg fluxbox-generate_menu startfluxbox | 4 | bin_SCRIPTS= fbsetbg fluxbox-generate_menu startfluxbox |
5 | bin_PROGRAMS= fbsetroot | 5 | bin_PROGRAMS= fbsetroot fluxbox-update_configs |
6 | fbsetroot_SOURCES= fbsetroot.cc fbsetroot.hh | 6 | fbsetroot_SOURCES= fbsetroot.cc fbsetroot.hh |
7 | fbsetroot_LDADD=../src/FbRootWindow.o ../src/FbAtoms.o \ | 7 | fbsetroot_LDADD=../src/FbRootWindow.o ../src/FbAtoms.o \ |
8 | ../src/FbTk/libFbTk.a | 8 | ../src/FbTk/libFbTk.a |
9 | fluxbox_update_configs_SOURCES= fluxbox-update_configs.cc | ||
10 | fluxbox_update_configs_LDADD= ../src/defaults.o ../src/Resources.o \ | ||
11 | ../src/FbTk/libFbTk.a | ||
9 | 12 | ||
10 | MAINTAINERCLEANFILES= Makefile.in | 13 | MAINTAINERCLEANFILES= Makefile.in |
11 | EXTRA_DIST= fbsetbg fluxbox-generate_menu.in \ | 14 | EXTRA_DIST= fbsetbg fluxbox-generate_menu.in \ |
@@ -22,6 +25,9 @@ clean-local: | |||
22 | fbsetroot.o: fbsetroot.cc ../config.h $(srcdir)/fbsetroot.hh \ | 25 | fbsetroot.o: fbsetroot.cc ../config.h $(srcdir)/fbsetroot.hh \ |
23 | $(top_srcdir)/src/FbRootWindow.hh $(top_srcdir)/src/FbAtoms.hh | 26 | $(top_srcdir)/src/FbRootWindow.hh $(top_srcdir)/src/FbAtoms.hh |
24 | 27 | ||
28 | fluxbox-update_configs.o: fluxbox-update_configs.cc ../config.h \ | ||
29 | $(top_srcdir)/src/defaults.hh | ||
30 | |||
25 | startfluxbox: startfluxbox.in | 31 | startfluxbox: startfluxbox.in |
26 | @regex_cmd@ -e "s,@pkgdatadir@,$(pkgdatadir),g" \ | 32 | @regex_cmd@ -e "s,@pkgdatadir@,$(pkgdatadir),g" \ |
27 | -e "s,@pkgbindir@,$(bindir),g" \ | 33 | -e "s,@pkgbindir@,$(bindir),g" \ |
@@ -40,3 +46,7 @@ fluxbox-generate_menu: fluxbox-generate_menu.in | |||
40 | cd ../src && ${MAKE} FbRootWindow.o | 46 | cd ../src && ${MAKE} FbRootWindow.o |
41 | ../src/FbAtoms.o: | 47 | ../src/FbAtoms.o: |
42 | cd ../src && ${MAKE} FbAtoms.o | 48 | cd ../src && ${MAKE} FbAtoms.o |
49 | ../src/defaults.o: | ||
50 | cd ../src && ${MAKE} defaults.o | ||
51 | ../src/Resources.o: | ||
52 | cd ../src && ${MAKE} Resources.o | ||
diff --git a/util/fluxbox-update_configs.cc b/util/fluxbox-update_configs.cc new file mode 100644 index 0000000..de1fbb9 --- /dev/null +++ b/util/fluxbox-update_configs.cc | |||
@@ -0,0 +1,197 @@ | |||
1 | // fluxbox-update_configs.cc | ||
2 | // Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | #include "../src/FbTk/I18n.hh" | ||
23 | #include "../src/FbTk/Resource.hh" | ||
24 | #include "../src/FbTk/StringUtil.hh" | ||
25 | |||
26 | #include "../src/defaults.hh" | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif // HAVE_CONFIG_H | ||
31 | |||
32 | #ifdef HAVE_SIGNAL_H | ||
33 | #include <signal.h> | ||
34 | #endif // HAVE_SIGNAL_H | ||
35 | |||
36 | //use GNU extensions | ||
37 | #ifndef _GNU_SOURCE | ||
38 | #define _GNU_SOURCE | ||
39 | #endif // _GNU_SOURCE | ||
40 | |||
41 | #ifdef HAVE_CSTDIO | ||
42 | #include <cstdio> | ||
43 | #else | ||
44 | #include <stdio.h> | ||
45 | #endif | ||
46 | #ifdef HAVE_CSTDLIB | ||
47 | #include <cstdlib> | ||
48 | #else | ||
49 | #include <stdlib.h> | ||
50 | #endif | ||
51 | #ifdef HAVE_CSTRING | ||
52 | #include <cstring> | ||
53 | #else | ||
54 | #include <string.h> | ||
55 | #endif | ||
56 | #include <iostream> | ||
57 | #include <fstream> | ||
58 | |||
59 | using std::cout; | ||
60 | using std::cerr; | ||
61 | using std::endl; | ||
62 | using std::string; | ||
63 | using std::ifstream; | ||
64 | using std::ofstream; | ||
65 | |||
66 | #define VERSION 1 | ||
67 | |||
68 | int run_updates(int old_version, FbTk::ResourceManager rm) { | ||
69 | int new_version = old_version; | ||
70 | |||
71 | if (old_version < 1) { // add mouse events to keys file | ||
72 | FbTk::Resource<string> rc_keyfile(rm, DEFAULTKEYSFILE, | ||
73 | "session.keyFile", "Session.KeyFile"); | ||
74 | string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile); | ||
75 | |||
76 | // ok, I don't know anything about file handling in c++ | ||
77 | // what's it to you?!?! | ||
78 | // I assume there should be some error handling in here, but I sure | ||
79 | // don't know how, and I don't have documentation | ||
80 | |||
81 | ifstream in_keyfile(keyfilename.c_str()); | ||
82 | string whole_keyfile = ""; | ||
83 | |||
84 | while (!in_keyfile.eof()) { | ||
85 | string linebuffer; | ||
86 | |||
87 | getline(in_keyfile, linebuffer); | ||
88 | whole_keyfile += linebuffer + "\n"; | ||
89 | } | ||
90 | in_keyfile.close(); | ||
91 | |||
92 | ofstream out_keyfile(keyfilename.c_str()); | ||
93 | // let's put our new keybindings first, so they're easy to find | ||
94 | out_keyfile << "!mouse actions added by fluxbox-update_configs" << endl | ||
95 | << "OnDesktop Mouse1 :hideMenus" << endl | ||
96 | << "OnDesktop Mouse2 :workspaceMenu" << endl | ||
97 | << "OnDesktop Mouse3 :rootMenu" << endl; | ||
98 | |||
99 | // scrolling on desktop needs to match user's desktop wheeling settings | ||
100 | // hmmm, what are the odds that somebody wants this to be different on | ||
101 | // different screens? the ability is going away until we make per-screen | ||
102 | // keys files, anyway, so let's just use the first screen's setting | ||
103 | FbTk::Resource<bool> rc_wheeling(rm, true, | ||
104 | "session.screen0.desktopwheeling", | ||
105 | "Session.Screen0.DesktopWheeling"); | ||
106 | FbTk::Resource<bool> rc_reverse(rm, false, | ||
107 | "session.screen0.reversewheeling", | ||
108 | "Session.Screen0.ReverseWheeling"); | ||
109 | if (*rc_wheeling) { | ||
110 | if (*rc_reverse) { // if you ask me, this should have been default | ||
111 | out_keyfile << "OnDesktop Mouse4 :prevWorkspace" << endl | ||
112 | << "OnDesktop Mouse5 :nextWorkspace" << endl; | ||
113 | } else { | ||
114 | out_keyfile << "OnDesktop Mouse4 :nextWorkspace" << endl | ||
115 | << "OnDesktop Mouse5 :prevWorkspace" << endl; | ||
116 | } | ||
117 | } | ||
118 | out_keyfile << endl; // just for good looks | ||
119 | |||
120 | // now, restore user's old keybindings | ||
121 | out_keyfile << whole_keyfile; | ||
122 | new_version = 1; | ||
123 | } | ||
124 | |||
125 | return new_version; | ||
126 | } | ||
127 | |||
128 | int main(int argc, char **argv) { | ||
129 | string rc_filename; | ||
130 | int i = 1; | ||
131 | pid_t fb_pid = 0; | ||
132 | |||
133 | FbTk::NLSInit("fluxbox.cat"); | ||
134 | _FB_USES_NLS; | ||
135 | |||
136 | for (; i < argc; i++) { | ||
137 | if (strcmp(argv[i], "-rc") == 0) { | ||
138 | // look for alternative rc file to use | ||
139 | |||
140 | if ((++i) >= argc) { | ||
141 | cerr<<_FB_CONSOLETEXT(main, RCRequiresArg, | ||
142 | "error: '-rc' requires an argument", "the -rc option requires a file argument")<<endl; | ||
143 | exit(1); | ||
144 | } | ||
145 | |||
146 | rc_filename = argv[i]; | ||
147 | } else if (strcmp(argv[i], "-pid") == 0) { | ||
148 | if ((++i) >= argc) { | ||
149 | // need translations for this, too | ||
150 | cerr<<"the -pid option requires a numeric argument"<<endl; | ||
151 | } else | ||
152 | fb_pid = atoi(argv[i]); | ||
153 | } else if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) { | ||
154 | // no NLS translations yet -- we'll just have to use English for now | ||
155 | cout << " -rc <string>\t\t\tuse alternate resource file.\n" | ||
156 | << " -pid <int>\t\t\ttell fluxbox to reload configuration.\n" | ||
157 | << " -help\t\t\t\tdisplay this help text and exit.\n\n" | ||
158 | << endl; | ||
159 | exit(0); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | FbTk::ResourceManager resource_manager(rc_filename.c_str(),false); | ||
164 | if (rc_filename.empty() || !resource_manager.load(rc_filename.c_str())) { | ||
165 | // couldn't load rc file | ||
166 | if (!rc_filename.empty()) { | ||
167 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "Failed trying to read rc file")<<":"<<rc_filename<<endl; | ||
168 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFileTrying, "Retrying with", "Retrying rc file loading with (the following file)")<<": "<<DEFAULT_INITFILE<<endl; | ||
169 | } | ||
170 | // couldn't load default rc file, either | ||
171 | if (!resource_manager.load(DEFAULT_INITFILE)) { | ||
172 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "")<<": "<<DEFAULT_INITFILE<<endl; | ||
173 | exit(1); // this is a fatal error for us | ||
174 | } | ||
175 | } | ||
176 | |||
177 | // run updates here | ||
178 | // I feel like putting this in a separate function for no apparent reason | ||
179 | |||
180 | FbTk::Resource<int> config_version(resource_manager, 0, | ||
181 | "session.configVersion", "Session.ConfigVersion"); | ||
182 | int old_version = *config_version; | ||
183 | int new_version = run_updates(old_version, resource_manager); | ||
184 | if (new_version > old_version) { | ||
185 | config_version = new_version; | ||
186 | resource_manager.save(rc_filename.c_str(), rc_filename.c_str()); | ||
187 | |||
188 | #ifdef HAVE_SIGNAL_H | ||
189 | // if we were given a fluxbox pid, send it a reconfigure signal | ||
190 | if (fb_pid > 0) | ||
191 | kill(fb_pid, SIGUSR2); | ||
192 | #endif // HAVE_SIGNAL_H | ||
193 | |||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||