summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--src/Remember.cc182
2 files changed, 104 insertions, 82 deletions
diff --git a/ChangeLog b/ChangeLog
index 665cc27..535be05 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
1(Format: Year/Month/Day) 1(Format: Year/Month/Day)
2Changes for 0.9.16: 2Changes 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
62namespace { 61namespace {
63 62
63bool getuint(const char *val, unsigned int &ret) {
64 return (sscanf(val, "%ui", &ret) == 1);
65}
66
64class RememberMenuItem : public FbTk::MenuItem { 67class RememberMenuItem : public FbTk::MenuItem {
65public: 68public:
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) {
154bool handleStartupItem(const string &line, int offset) { 159bool 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
780bool Remember::isRemembered(WinClient &winclient, Attribute attrib) { 797bool Remember::isRemembered(WinClient &winclient, Attribute attrib) {
@@ -1040,6 +1057,7 @@ void Remember::setupClient(WinClient &winclient) {
1040} 1057}
1041 1058
1042void Remember::updateClientClose(WinClient &winclient) { 1059void 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)) {