diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/Remember.cc | 182 |
2 files changed, 104 insertions, 82 deletions
@@ -1,5 +1,9 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.16: | 2 | Changes for 0.9.16: |
3 | *06/05/01: | ||
4 | * Make apps file keywords case insensitive, plus reload it (if newer) | ||
5 | before save on close and remember menu events (Simon) | ||
6 | Remember.cc | ||
3 | *06/04/26: | 7 | *06/04/26: |
4 | * Fix resizing of client window when autogroup from apps (Simon) | 8 | * Fix resizing of client window when autogroup from apps (Simon) |
5 | Window.cc | 9 | Window.cc |
diff --git a/src/Remember.cc b/src/Remember.cc index 33ed08d..dfa0e8f 100644 --- a/src/Remember.cc +++ b/src/Remember.cc | |||
@@ -49,7 +49,6 @@ | |||
49 | #define _GNU_SOURCE | 49 | #define _GNU_SOURCE |
50 | #endif // _GNU_SOURCE | 50 | #endif // _GNU_SOURCE |
51 | 51 | ||
52 | |||
53 | #include <iostream> | 52 | #include <iostream> |
54 | #include <fstream> | 53 | #include <fstream> |
55 | #include <string> | 54 | #include <string> |
@@ -61,6 +60,10 @@ using namespace std; | |||
61 | 60 | ||
62 | namespace { | 61 | namespace { |
63 | 62 | ||
63 | bool getuint(const char *val, unsigned int &ret) { | ||
64 | return (sscanf(val, "%ui", &ret) == 1); | ||
65 | } | ||
66 | |||
64 | class RememberMenuItem : public FbTk::MenuItem { | 67 | class RememberMenuItem : public FbTk::MenuItem { |
65 | public: | 68 | public: |
66 | RememberMenuItem(const char *label, | 69 | RememberMenuItem(const char *label, |
@@ -93,6 +96,8 @@ public: | |||
93 | } | 96 | } |
94 | 97 | ||
95 | void click(int button, int time) { | 98 | void click(int button, int time) { |
99 | // reconfigure only does stuff if the apps file has changed | ||
100 | Remember::instance().reconfigure(); | ||
96 | if (WindowCmd<void>::window() != 0) { | 101 | if (WindowCmd<void>::window() != 0) { |
97 | if (isSelected()) { | 102 | if (isSelected()) { |
98 | Remember::instance().forgetAttrib(WindowCmd<void>::window()->winClient(), m_attrib); | 103 | Remember::instance().forgetAttrib(WindowCmd<void>::window()->winClient(), m_attrib); |
@@ -154,7 +159,7 @@ FbTk::Menu *createRememberMenu(BScreen &screen) { | |||
154 | bool handleStartupItem(const string &line, int offset) { | 159 | bool handleStartupItem(const string &line, int offset) { |
155 | int next = 0; | 160 | int next = 0; |
156 | string str; | 161 | string str; |
157 | int screen = 0; | 162 | unsigned int screen = 0; |
158 | 163 | ||
159 | // accept some options, for now only "screen=NN" | 164 | // accept some options, for now only "screen=NN" |
160 | // these option are given in parentheses before the command | 165 | // these option are given in parentheses before the command |
@@ -168,9 +173,8 @@ bool handleStartupItem(const string &line, int offset) { | |||
168 | bool error = false; | 173 | bool error = false; |
169 | if (pos > 0) { | 174 | if (pos > 0) { |
170 | option = str.substr(0, pos); | 175 | option = str.substr(0, pos); |
171 | if (option == "screen") { | 176 | if (strcasecmp(option.c_str(), "screen") == 0) { |
172 | FbTk_istringstream iss(str.c_str() + pos + 1); | 177 | error = getuint(str.c_str() + pos + 1, screen); |
173 | iss >> screen; | ||
174 | } else { | 178 | } else { |
175 | error = true; | 179 | error = true; |
176 | } | 180 | } |
@@ -337,45 +341,50 @@ int Remember::parseApp(std::ifstream &file, Application &app, std::string *first | |||
337 | } else | 341 | } else |
338 | continue; //read next line | 342 | continue; //read next line |
339 | 343 | ||
344 | bool had_error = false; | ||
345 | |||
340 | if (!str_key.size()) | 346 | if (!str_key.size()) |
341 | continue; //read next line | 347 | continue; //read next line |
342 | if (str_key == "Workspace") { | 348 | if (strcasecmp(str_key.c_str(), "Workspace") == 0) { |
343 | unsigned int w; | 349 | unsigned int w; |
344 | FbTk_istringstream iss(str_label.c_str()); | 350 | if (getuint(str_label.c_str(), w)) |
345 | iss >> w; | 351 | app.rememberWorkspace(w); |
346 | app.rememberWorkspace(w); | 352 | else |
347 | } else if (str_key == "Head") { | 353 | had_error = true; |
348 | int h = atoi(str_label.c_str()); | 354 | } else if (strcasecmp(str_key.c_str(), "Head") == 0) { |
349 | app.rememberHead(h); | 355 | unsigned int h; |
350 | } else if (str_key == "Layer") { | 356 | if (getuint(str_label.c_str(), h)) |
357 | app.rememberHead(h); | ||
358 | else | ||
359 | had_error = true; | ||
360 | } else if (strcasecmp(str_key.c_str(), "Layer") == 0) { | ||
351 | unsigned int l; | 361 | unsigned int l; |
352 | if (str_label == "DESKTOP") { | 362 | if (strcasecmp(str_label.c_str(), "DESKTOP") == 0) { |
353 | l = Layer::DESKTOP; | 363 | l = Layer::DESKTOP; |
354 | } else if (str_label == "BOTTOM") { | 364 | } else if (strcasecmp(str_label.c_str(), "BOTTOM") == 0) { |
355 | l = Layer::BOTTOM; | 365 | l = Layer::BOTTOM; |
356 | } else if (str_label == "NORMAL") { | 366 | } else if (strcasecmp(str_label.c_str(), "NORMAL") == 0) { |
357 | l = Layer::NORMAL; | 367 | l = Layer::NORMAL; |
358 | } else if (str_label == "TOP") { | 368 | } else if (strcasecmp(str_label.c_str(), "TOP") == 0) { |
359 | l = Layer::TOP; | 369 | l = Layer::TOP; |
360 | } else if (str_label == "DOCK") { | 370 | } else if (strcasecmp(str_label.c_str(), "DOCK") == 0) { |
361 | l = Layer::DOCK; | 371 | l = Layer::DOCK; |
362 | } else if (str_label == "ABOVEDOCK") { | 372 | } else if (strcasecmp(str_label.c_str(), "ABOVEDOCK") == 0) { |
363 | l = Layer::ABOVE_DOCK; | 373 | l = Layer::ABOVE_DOCK; |
364 | } else if (str_label == "MENU") { | 374 | } else if (strcasecmp(str_label.c_str(), "MENU") == 0) { |
365 | l = Layer::MENU; | 375 | l = Layer::MENU; |
366 | } else { | 376 | } else if (!getuint(str_label.c_str(), l)) { |
367 | FbTk_istringstream iss(str_label.c_str()); | 377 | had_error = true; |
368 | iss >> l; | ||
369 | } | 378 | } |
370 | app.rememberLayer(l); | 379 | if (!had_error) |
371 | } else if (str_key == "Dimensions") { | 380 | app.rememberLayer(l); |
381 | } else if (strcasecmp(str_key.c_str(), "Dimensions") == 0) { | ||
372 | unsigned int h,w; | 382 | unsigned int h,w; |
373 | FbTk_istringstream iss(str_label.c_str()); | 383 | if (sscanf(str_label.c_str(), "%i %i", &w, &h) == 2) |
374 | iss >> w >> h; | 384 | app.rememberDimensions(w, h); |
375 | 385 | else | |
376 | app.rememberDimensions(w, h); | 386 | had_error = true; |
377 | 387 | } else if (strcasecmp(str_key.c_str(), "Position") == 0) { | |
378 | } else if (str_key == "Position") { | ||
379 | unsigned int r= 0; | 388 | unsigned int r= 0; |
380 | unsigned int x= 0; | 389 | unsigned int x= 0; |
381 | unsigned int y= 0; | 390 | unsigned int y= 0; |
@@ -384,55 +393,55 @@ int Remember::parseApp(std::ifstream &file, Application &app, std::string *first | |||
384 | 393 | ||
385 | if ( str_option.length() ) | 394 | if ( str_option.length() ) |
386 | { | 395 | { |
387 | if ( str_option == "UPPERLEFT" ) r= POS_UPPERLEFT; | 396 | if (strcasecmp(str_option.c_str(), "UPPERLEFT") == 0) r= POS_UPPERLEFT; |
388 | else if ( str_option == "UPPERRIGHT" ) r= POS_UPPERRIGHT; | 397 | else if (strcasecmp(str_option.c_str(), "UPPERRIGHT") == 0) r= POS_UPPERRIGHT; |
389 | else if ( str_option == "LOWERLEFT" ) r= POS_LOWERLEFT; | 398 | else if (strcasecmp(str_option.c_str(), "LOWERLEFT") == 0) r= POS_LOWERLEFT; |
390 | else if ( str_option == "LOWERRIGHT" ) r= POS_LOWERRIGHT; | 399 | else if (strcasecmp(str_option.c_str(), "LOWERRIGHT") == 0) r= POS_LOWERRIGHT; |
391 | else if ( str_option == "CENTER" ) r= POS_CENTER; | 400 | else if (strcasecmp(str_option.c_str(), "CENTER") == 0) r= POS_CENTER; |
392 | else if ( str_option == "WINCENTER" ) r= POS_WINCENTER; | 401 | else if (strcasecmp(str_option.c_str(), "WINCENTER") == 0) r= POS_WINCENTER; |
393 | else { | 402 | else if (!getuint(str_option.c_str(), r)) { |
394 | FbTk_istringstream iss_r(str_option.c_str()); | 403 | had_error = 1; |
395 | iss_r >> r; | ||
396 | } | 404 | } |
397 | } | 405 | } |
398 | 406 | ||
399 | FbTk_istringstream iss_xy(str_label.c_str()); | 407 | if (!had_error && sscanf(str_label.c_str(), "%i %i", &x, &y) == 2) |
400 | iss_xy >> x >> y; | 408 | app.rememberPosition(x, y, r); |
401 | app.rememberPosition(x, y, r); | 409 | else |
402 | } else if (str_key == "Shaded") { | 410 | had_error = true; |
403 | app.rememberShadedstate((str_label=="yes")); | 411 | } else if (strcasecmp(str_key.c_str(), "Shaded") == 0) { |
404 | } else if (str_key == "Tab") { | 412 | app.rememberShadedstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
405 | app.rememberTabstate((str_label=="yes")); | 413 | } else if (strcasecmp(str_key.c_str(), "Tab") == 0) { |
406 | } else if (str_key == "FocusHidden") { | 414 | app.rememberTabstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
407 | app.rememberFocusHiddenstate((str_label=="yes")); | 415 | } else if (strcasecmp(str_key.c_str(), "FocusHidden") == 0) { |
408 | } else if (str_key == "IconHidden") { | 416 | app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
409 | app.rememberIconHiddenstate((str_label=="yes")); | 417 | } else if (strcasecmp(str_key.c_str(), "IconHidden") == 0) { |
410 | } else if (str_key == "Hidden") { | 418 | app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
411 | app.rememberIconHiddenstate((str_label=="yes")); | 419 | } else if (strcasecmp(str_key.c_str(), "Hidden") == 0) { |
412 | app.rememberFocusHiddenstate((str_label=="yes")); | 420 | app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
413 | } else if (str_key == "Deco") { | 421 | app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
414 | if (str_label == "NONE") { | 422 | } else if (strcasecmp(str_key.c_str(), "Deco") == 0) { |
423 | if (strcasecmp(str_label.c_str(), "NONE") == 0) { | ||
415 | app.rememberDecostate((unsigned int) 0); | 424 | app.rememberDecostate((unsigned int) 0); |
416 | } else if (str_label == "NORMAL") { | 425 | } else if (strcasecmp(str_label.c_str(), "NORMAL") == 0) { |
417 | app.rememberDecostate((unsigned int) 0xfffffff); | 426 | app.rememberDecostate((unsigned int) 0xfffffff); |
418 | } else if (str_label == "TINY") { | 427 | } else if (strcasecmp(str_label.c_str(), "TINY") == 0) { |
419 | app.rememberDecostate((unsigned int) | 428 | app.rememberDecostate((unsigned int) |
420 | FluxboxWindow::DECORM_TITLEBAR | 429 | FluxboxWindow::DECORM_TITLEBAR |
421 | | FluxboxWindow::DECORM_ICONIFY | 430 | | FluxboxWindow::DECORM_ICONIFY |
422 | | FluxboxWindow::DECORM_MENU | 431 | | FluxboxWindow::DECORM_MENU |
423 | | FluxboxWindow::DECORM_TAB | 432 | | FluxboxWindow::DECORM_TAB |
424 | ); | 433 | ); |
425 | } else if (str_label == "TOOL") { | 434 | } else if (strcasecmp(str_label.c_str(), "TOOL") == 0) { |
426 | app.rememberDecostate((unsigned int) | 435 | app.rememberDecostate((unsigned int) |
427 | FluxboxWindow::DECORM_TITLEBAR | 436 | FluxboxWindow::DECORM_TITLEBAR |
428 | | FluxboxWindow::DECORM_MENU | 437 | | FluxboxWindow::DECORM_MENU |
429 | ); | 438 | ); |
430 | } else if (str_label == "BORDER") { | 439 | } else if (strcasecmp(str_label.c_str(), "BORDER") == 0) { |
431 | app.rememberDecostate((unsigned int) | 440 | app.rememberDecostate((unsigned int) |
432 | FluxboxWindow::DECORM_BORDER | 441 | FluxboxWindow::DECORM_BORDER |
433 | | FluxboxWindow::DECORM_MENU | 442 | | FluxboxWindow::DECORM_MENU |
434 | ); | 443 | ); |
435 | } else if (str_label == "TAB") { | 444 | } else if (strcasecmp(str_label.c_str(), "TAB") == 0) { |
436 | app.rememberDecostate((unsigned int) | 445 | app.rememberDecostate((unsigned int) |
437 | FluxboxWindow::DECORM_BORDER | 446 | FluxboxWindow::DECORM_BORDER |
438 | | FluxboxWindow::DECORM_MENU | 447 | | FluxboxWindow::DECORM_MENU |
@@ -440,28 +449,25 @@ int Remember::parseApp(std::ifstream &file, Application &app, std::string *first | |||
440 | ); | 449 | ); |
441 | } else { | 450 | } else { |
442 | unsigned int mask; | 451 | unsigned int mask; |
443 | const char * str = str_label.c_str(); | 452 | if (getuint(str_label.c_str(), mask)) |
444 | // it'll have at least one char and \0, so this is safe | 453 | app.rememberDecostate(mask); |
445 | FbTk_istringstream iss(str); | 454 | else |
446 | // check for hex | 455 | had_error = 1; |
447 | if (str[0] == '0' && str[1] == 'x') { | ||
448 | iss.seekg(2); | ||
449 | iss >> hex; | ||
450 | } | ||
451 | iss >> mask ; | ||
452 | app.rememberDecostate(mask); | ||
453 | } | 456 | } |
454 | } else if (str_key == "Sticky") { | 457 | } else if (strcasecmp(str_key.c_str(), "Sticky") == 0) { |
455 | app.rememberStuckstate((str_label=="yes")); | 458 | app.rememberStuckstate((strcasecmp(str_label.c_str(), "yes") == 0)); |
456 | } else if (str_key == "Jump") { | 459 | } else if (strcasecmp(str_key.c_str(), "Jump") == 0) { |
457 | app.rememberJumpworkspace((str_label=="yes")); | 460 | app.rememberJumpworkspace((strcasecmp(str_label.c_str(), "yes") == 0)); |
458 | } else if (str_key == "Close") { | 461 | } else if (strcasecmp(str_key.c_str(), "Close") == 0) { |
459 | app.rememberSaveOnClose((str_label=="yes")); | 462 | app.rememberSaveOnClose((strcasecmp(str_label.c_str(), "yes") == 0)); |
460 | } else if (str_key == "end") { | 463 | } else if (strcasecmp(str_key.c_str(), "end") == 0) { |
461 | return row; | 464 | return row; |
462 | } else { | 465 | } else { |
463 | cerr << _FBTEXT(Remember, Unknown, "Unknown apps key", "apps entry type not known")<<" = " << str_key << endl; | 466 | cerr << _FBTEXT(Remember, Unknown, "Unknown apps key", "apps entry type not known")<<" = " << str_key << endl; |
464 | } | 467 | } |
468 | if (had_error) { | ||
469 | cerr<<"Error parsing apps entry: ("<<line<<")"<<endl; | ||
470 | } | ||
465 | } | 471 | } |
466 | } | 472 | } |
467 | return row; | 473 | return row; |
@@ -545,7 +551,7 @@ void Remember::reconfigure() { | |||
545 | line.c_str(), | 551 | line.c_str(), |
546 | '[', ']'); | 552 | '[', ']'); |
547 | 553 | ||
548 | if (pos > 0 && key == "app") { | 554 | if (pos > 0 && strcasecmp(key.c_str(), "app") == 0) { |
549 | ClientPattern *pat = new ClientPattern(line.c_str() + pos); | 555 | ClientPattern *pat = new ClientPattern(line.c_str() + pos); |
550 | if (!in_group) { | 556 | if (!in_group) { |
551 | if ((err = pat->error()) == 0) { | 557 | if ((err = pat->error()) == 0) { |
@@ -562,13 +568,13 @@ void Remember::reconfigure() { | |||
562 | } else { | 568 | } else { |
563 | grouped_pats.push_back(pat); | 569 | grouped_pats.push_back(pat); |
564 | } | 570 | } |
565 | } else if (pos > 0 && key == "startup") { | 571 | } else if (pos > 0 && strcasecmp(key.c_str(), "startup") == 0) { |
566 | if (!handleStartupItem(line, pos)) { | 572 | if (!handleStartupItem(line, pos)) { |
567 | cerr<<"Error reading apps file at line "<<row<<"."<<endl; | 573 | cerr<<"Error reading apps file at line "<<row<<"."<<endl; |
568 | } | 574 | } |
569 | // save the item even if it was bad (aren't we nice) | 575 | // save the item even if it was bad (aren't we nice) |
570 | m_startups.push_back(line.substr(pos)); | 576 | m_startups.push_back(line.substr(pos)); |
571 | } else if (pos > 0 && key == "group") { | 577 | } else if (pos > 0 && strcasecmp(key.c_str(), "group") == 0) { |
572 | in_group = true; | 578 | in_group = true; |
573 | } else if (in_group) { | 579 | } else if (in_group) { |
574 | // otherwise assume that it is the start of the attributes | 580 | // otherwise assume that it is the start of the attributes |
@@ -593,7 +599,7 @@ void Remember::reconfigure() { | |||
593 | // we hit end... probably don't have attribs for the group | 599 | // we hit end... probably don't have attribs for the group |
594 | // so finish it off with an empty application | 600 | // so finish it off with an empty application |
595 | // otherwise parse the app | 601 | // otherwise parse the app |
596 | if (!(pos>0 && key == "end")) { | 602 | if (!(pos>0 && strcasecmp(key.c_str(), "end") == 0)) { |
597 | row += parseApp(apps_file, *app, &line); | 603 | row += parseApp(apps_file, *app, &line); |
598 | } | 604 | } |
599 | in_group = false; | 605 | in_group = false; |
@@ -745,6 +751,11 @@ void Remember::save() { | |||
745 | | FluxboxWindow::DECORM_MENU): | 751 | | FluxboxWindow::DECORM_MENU): |
746 | apps_file << " [Deco]\t{BORDER}" << endl; | 752 | apps_file << " [Deco]\t{BORDER}" << endl; |
747 | break; | 753 | break; |
754 | case (FluxboxWindow::DECORM_BORDER | ||
755 | | FluxboxWindow::DECORM_MENU | ||
756 | | FluxboxWindow::DECORM_TAB): | ||
757 | apps_file << " [Deco]\t{TAB}" << endl; | ||
758 | break; | ||
748 | default: | 759 | default: |
749 | apps_file << " [Deco]\t{0x"<<hex<<a.decostate<<dec<<"}"<<endl; | 760 | apps_file << " [Deco]\t{0x"<<hex<<a.decostate<<dec<<"}"<<endl; |
750 | break; | 761 | break; |
@@ -775,6 +786,12 @@ void Remember::save() { | |||
775 | } | 786 | } |
776 | apps_file << "[end]" << endl; | 787 | apps_file << "[end]" << endl; |
777 | } | 788 | } |
789 | apps_file.close(); | ||
790 | |||
791 | time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp(apps_string.c_str()); | ||
792 | if (timestamp > 0) | ||
793 | m_last_timestamp = timestamp; | ||
794 | |||
778 | } | 795 | } |
779 | 796 | ||
780 | bool Remember::isRemembered(WinClient &winclient, Attribute attrib) { | 797 | bool Remember::isRemembered(WinClient &winclient, Attribute attrib) { |
@@ -1040,6 +1057,7 @@ void Remember::setupClient(WinClient &winclient) { | |||
1040 | } | 1057 | } |
1041 | 1058 | ||
1042 | void Remember::updateClientClose(WinClient &winclient) { | 1059 | void Remember::updateClientClose(WinClient &winclient) { |
1060 | reconfigure(); // reload if it's changed | ||
1043 | Application *app = find(winclient); | 1061 | Application *app = find(winclient); |
1044 | 1062 | ||
1045 | if (app && (app->save_on_close_remember && app->save_on_close)) { | 1063 | if (app && (app->save_on_close_remember && app->save_on_close)) { |