diff options
author | Mathias Gumz <akira@fluxbox.org> | 2015-01-21 21:16:19 (GMT) |
---|---|---|
committer | Mathias Gumz <akira@fluxbox.org> | 2015-01-21 21:16:19 (GMT) |
commit | e2dbdeeb2eb1dd1e2ff97499e894a86d47d9e3db (patch) | |
tree | b8c195be09bb46413025ed2a8f0c3cc7eadc8482 | |
parent | 145cf94ea67a7d58ccd0a90dae8cba8c38a3275a (diff) | |
download | fluxbox-e2dbdeeb2eb1dd1e2ff97499e894a86d47d9e3db.zip fluxbox-e2dbdeeb2eb1dd1e2ff97499e894a86d47d9e3db.tar.bz2 |
Fix segfault on shutdown
There was a problem deep within how the menus were connected and when and
what gets deleted. It was clearly related to a menu which was kind of
global. In order to better understand the code flow I eliminated the
ExtraMenu code: it was used only to get the Remember-Menu into the
Window-Menu. Instead of having a singleton of the Remember-Menu and fight
against the shaky interconnections we just create a new one on demand
and delete when the menu gets deleted. Looks like this fixes the problem.
The menu code needs more love anyway.
Closes #1118
-rw-r--r-- | src/MenuCreator.cc | 20 | ||||
-rw-r--r-- | src/Remember.cc | 10 | ||||
-rw-r--r-- | src/Remember.hh | 3 | ||||
-rw-r--r-- | src/Screen.cc | 52 | ||||
-rw-r--r-- | src/Screen.hh | 5 |
5 files changed, 29 insertions, 61 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc index a90e234..7f7445f 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc | |||
@@ -56,6 +56,10 @@ | |||
56 | #include <iostream> | 56 | #include <iostream> |
57 | #include <algorithm> | 57 | #include <algorithm> |
58 | 58 | ||
59 | #ifdef REMEMBER | ||
60 | #include "Remember.hh" | ||
61 | #endif // REMEMBER | ||
62 | |||
59 | using std::cerr; | 63 | using std::cerr; |
60 | using std::endl; | 64 | using std::endl; |
61 | using std::string; | 65 | using std::string; |
@@ -88,6 +92,8 @@ enum { | |||
88 | 92 | ||
89 | L_ALPHA, | 93 | L_ALPHA, |
90 | 94 | ||
95 | L_REMEMBER, | ||
96 | |||
91 | L_MENU_EXIT, | 97 | L_MENU_EXIT, |
92 | L_MENU_ICONS, | 98 | L_MENU_ICONS, |
93 | }; | 99 | }; |
@@ -112,6 +118,8 @@ const FbTk::FbString& _l(const FbTk::FbString& label, size_t type) { | |||
112 | 118 | ||
113 | _FB_XTEXT(Configmenu, Transparency, "Transparency", "Menu containing various transparency options"), | 119 | _FB_XTEXT(Configmenu, Transparency, "Transparency", "Menu containing various transparency options"), |
114 | 120 | ||
121 | _FB_XTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"), | ||
122 | |||
115 | _FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), | 123 | _FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), |
116 | _FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), | 124 | _FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), |
117 | }; | 125 | }; |
@@ -602,14 +610,13 @@ bool MenuCreator::createWindowMenuItem(const string &type, | |||
602 | } | 610 | } |
603 | #endif // HAVE_XRENDER | 611 | #endif // HAVE_XRENDER |
604 | } else if (type == "extramenus") { | 612 | } else if (type == "extramenus") { |
613 | #ifdef REMEMBER | ||
605 | BScreen* s = Fluxbox::instance()->findScreen(screen); | 614 | BScreen* s = Fluxbox::instance()->findScreen(screen); |
606 | BScreen::ExtraMenus::iterator it = s->extraWindowMenus().begin(); | 615 | if (s == 0) { |
607 | BScreen::ExtraMenus::iterator it_end = s->extraWindowMenus().end(); | 616 | return false; |
608 | for (; it != it_end; ++it) { | ||
609 | it->second->disableTitle(); | ||
610 | menu.insertSubmenu(it->first, it->second); | ||
611 | } | 617 | } |
612 | 618 | menu.insertSubmenu(_l("", L_REMEMBER), Remember::createMenu(*s)); | |
619 | #endif | ||
613 | } else if (type == "sendto") { | 620 | } else if (type == "sendto") { |
614 | menu.insertSubmenu(_l(label, L_SENDTO), | 621 | menu.insertSubmenu(_l(label, L_SENDTO), |
615 | new SendToMenu(*Fluxbox::instance()->findScreen(screen))); | 622 | new SendToMenu(*Fluxbox::instance()->findScreen(screen))); |
@@ -634,4 +641,3 @@ bool MenuCreator::createWindowMenuItem(const string &type, | |||
634 | return true; | 641 | return true; |
635 | } | 642 | } |
636 | 643 | ||
637 | |||
diff --git a/src/Remember.cc b/src/Remember.cc index f946ad0..19ea5f0 100644 --- a/src/Remember.cc +++ b/src/Remember.cc | |||
@@ -1442,10 +1442,10 @@ void Remember::updateClientClose(WinClient &winclient) { | |||
1442 | 1442 | ||
1443 | } | 1443 | } |
1444 | 1444 | ||
1445 | void Remember::initForScreen(BScreen &screen) { | 1445 | void Remember::initForScreen(BScreen &screen) { } |
1446 | // All windows get the remember menu. | 1446 | |
1447 | _FB_USES_NLS; | 1447 | FbTk::Menu* Remember::createMenu(BScreen& screen) { |
1448 | screen.addExtraWindowMenu(_FB_XTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"), | ||
1449 | createRememberMenu(screen)); | ||
1450 | 1448 | ||
1449 | return createRememberMenu(screen); | ||
1451 | } | 1450 | } |
1451 | |||
diff --git a/src/Remember.hh b/src/Remember.hh index a1abf5a..a6a980e 100644 --- a/src/Remember.hh +++ b/src/Remember.hh | |||
@@ -41,6 +41,7 @@ class Application; | |||
41 | 41 | ||
42 | namespace FbTk { | 42 | namespace FbTk { |
43 | class AutoReloadHelper; | 43 | class AutoReloadHelper; |
44 | class Menu; | ||
44 | } | 45 | } |
45 | 46 | ||
46 | /** | 47 | /** |
@@ -125,6 +126,8 @@ public: | |||
125 | 126 | ||
126 | void initForScreen(BScreen &screen); | 127 | void initForScreen(BScreen &screen); |
127 | 128 | ||
129 | static FbTk::Menu* createMenu(BScreen& screen); | ||
130 | |||
128 | // Functions we ignore (zero from AtomHandler) | 131 | // Functions we ignore (zero from AtomHandler) |
129 | // Leaving here in case they might be useful later | 132 | // Leaving here in case they might be useful later |
130 | 133 | ||
diff --git a/src/Screen.cc b/src/Screen.cc index 1d81191..2ae63a1 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -357,8 +357,8 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
357 | 357 | ||
358 | m_configmenu.reset(MenuCreator::createMenu(_FB_XTEXT(Menu, Configuration, | 358 | m_configmenu.reset(MenuCreator::createMenu(_FB_XTEXT(Menu, Configuration, |
359 | "Configuration", "Title of configuration menu"), *this)); | 359 | "Configuration", "Title of configuration menu"), *this)); |
360 | setupConfigmenu(*m_configmenu.get()); | ||
361 | m_configmenu->setInternalMenu(); | 360 | m_configmenu->setInternalMenu(); |
361 | setupConfigmenu(*m_configmenu.get()); | ||
362 | 362 | ||
363 | // check which desktop we should start on | 363 | // check which desktop we should start on |
364 | int first_desktop = 0; | 364 | int first_desktop = 0; |
@@ -388,9 +388,7 @@ BScreen::~BScreen() { | |||
388 | 388 | ||
389 | if (! managed) | 389 | if (! managed) |
390 | return; | 390 | return; |
391 | 391 | ||
392 | m_configmenu.reset(0); | ||
393 | |||
394 | m_toolbar.reset(0); | 392 | m_toolbar.reset(0); |
395 | 393 | ||
396 | FbTk::EventManager *evm = FbTk::EventManager::instance(); | 394 | FbTk::EventManager *evm = FbTk::EventManager::instance(); |
@@ -407,35 +405,6 @@ BScreen::~BScreen() { | |||
407 | // we need to destroy it before we destroy workspaces | 405 | // we need to destroy it before we destroy workspaces |
408 | m_workspacemenu.reset(0); | 406 | m_workspacemenu.reset(0); |
409 | 407 | ||
410 | if (m_extramenus.size()) { | ||
411 | // check whether extramenus are included in windowmenu | ||
412 | // if not, we clean them ourselves | ||
413 | bool extramenus_in_windowmenu = false; | ||
414 | for (size_t i = 0, n = m_windowmenu->numberOfItems(); i < n; i++) | ||
415 | if (m_windowmenu->find(i)->submenu() == m_extramenus.begin()->second) { | ||
416 | extramenus_in_windowmenu = true; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | ExtraMenus::iterator mit = m_extramenus.begin(); | ||
421 | ExtraMenus::iterator mit_end = m_extramenus.end(); | ||
422 | for (; mit != mit_end; ++mit) { | ||
423 | // we set them to NOT internal so that they will be deleted when the | ||
424 | // menu is cleaned up. We can't delete them here because they are | ||
425 | // still in the menu | ||
426 | // (They need to be internal for most of the time so that if we | ||
427 | // rebuild the menu, then they won't be removed. | ||
428 | if (! extramenus_in_windowmenu) { | ||
429 | // not attached to our windowmenu | ||
430 | // so we clean it up | ||
431 | delete mit->second; | ||
432 | } else { | ||
433 | // let the parent clean it up | ||
434 | mit->second->setInternalMenu(false); | ||
435 | } | ||
436 | } | ||
437 | } | ||
438 | |||
439 | removeWorkspaceNames(); | 408 | removeWorkspaceNames(); |
440 | using namespace FbTk::STLUtil; | 409 | using namespace FbTk::STLUtil; |
441 | destroyAndClear(m_workspaces_list); | 410 | destroyAndClear(m_workspaces_list); |
@@ -461,9 +430,10 @@ BScreen::~BScreen() { | |||
461 | // slit must be destroyed before headAreas (Struts) | 430 | // slit must be destroyed before headAreas (Struts) |
462 | m_slit.reset(0); | 431 | m_slit.reset(0); |
463 | 432 | ||
464 | delete m_rootmenu.release(); | 433 | m_windowmenu.reset(0); |
465 | delete m_workspacemenu.release(); | 434 | m_rootmenu.reset(0); |
466 | delete m_windowmenu.release(); | 435 | m_workspacemenu.reset(0); |
436 | m_configmenu.reset(0); | ||
467 | 437 | ||
468 | // TODO fluxgen: check if this is the right place | 438 | // TODO fluxgen: check if this is the right place |
469 | for (size_t i = 0; i < m_head_areas.size(); i++) | 439 | for (size_t i = 0; i < m_head_areas.size(); i++) |
@@ -471,6 +441,7 @@ BScreen::~BScreen() { | |||
471 | 441 | ||
472 | delete m_focus_control; | 442 | delete m_focus_control; |
473 | delete m_placement_strategy; | 443 | delete m_placement_strategy; |
444 | |||
474 | } | 445 | } |
475 | 446 | ||
476 | bool BScreen::isRestart() { | 447 | bool BScreen::isRestart() { |
@@ -736,13 +707,6 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { | |||
736 | 707 | ||
737 | } | 708 | } |
738 | 709 | ||
739 | void BScreen::addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu) { | ||
740 | menu->setInternalMenu(); | ||
741 | menu->disableTitle(); | ||
742 | m_extramenus.push_back(make_pair(label, menu)); | ||
743 | rereadWindowMenu(); | ||
744 | } | ||
745 | |||
746 | void BScreen::reconfigure() { | 710 | void BScreen::reconfigure() { |
747 | Fluxbox *fluxbox = Fluxbox::instance(); | 711 | Fluxbox *fluxbox = Fluxbox::instance(); |
748 | 712 | ||
@@ -754,7 +718,7 @@ void BScreen::reconfigure() { | |||
754 | 718 | ||
755 | m_menutheme->setDelay(*resource.menu_delay); | 719 | m_menutheme->setDelay(*resource.menu_delay); |
756 | 720 | ||
757 | // realize the number of workspaces from the init-file | 721 | // provide the number of workspaces from the init-file |
758 | const unsigned int nr_ws = *resource.workspaces; | 722 | const unsigned int nr_ws = *resource.workspaces; |
759 | if (nr_ws > m_workspaces_list.size()) { | 723 | if (nr_ws > m_workspaces_list.size()) { |
760 | while(nr_ws != m_workspaces_list.size()) { | 724 | while(nr_ws != m_workspaces_list.size()) { |
diff --git a/src/Screen.hh b/src/Screen.hh index 771899f..c9a6ede 100644 --- a/src/Screen.hh +++ b/src/Screen.hh | |||
@@ -82,7 +82,6 @@ public: | |||
82 | 82 | ||
83 | typedef std::vector<Workspace *> Workspaces; | 83 | typedef std::vector<Workspace *> Workspaces; |
84 | typedef std::vector<std::string> WorkspaceNames; | 84 | typedef std::vector<std::string> WorkspaceNames; |
85 | typedef std::list<std::pair<FbTk::FbString, FbTk::Menu *> > ExtraMenus; | ||
86 | 85 | ||
87 | BScreen(FbTk::ResourceManager &rm, | 86 | BScreen(FbTk::ResourceManager &rm, |
88 | const std::string &screenname, const std::string &altscreenname, | 87 | const std::string &screenname, const std::string &altscreenname, |
@@ -113,8 +112,6 @@ public: | |||
113 | FbMenu &configMenu() { return *m_configmenu.get(); } | 112 | FbMenu &configMenu() { return *m_configmenu.get(); } |
114 | const FbMenu &windowMenu() const { return *m_windowmenu.get(); } | 113 | const FbMenu &windowMenu() const { return *m_windowmenu.get(); } |
115 | FbMenu &windowMenu() { return *m_windowmenu.get(); } | 114 | FbMenu &windowMenu() { return *m_windowmenu.get(); } |
116 | ExtraMenus &extraWindowMenus() { return m_extramenus; } | ||
117 | const ExtraMenus &extraWindowMenus() const { return m_extramenus; } | ||
118 | 115 | ||
119 | FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; } | 116 | FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; } |
120 | 117 | ||
@@ -480,8 +477,6 @@ private: | |||
480 | std::auto_ptr<FbTk::ImageControl> m_image_control; | 477 | std::auto_ptr<FbTk::ImageControl> m_image_control; |
481 | std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu; | 478 | std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu; |
482 | 479 | ||
483 | ExtraMenus m_extramenus; | ||
484 | |||
485 | Icons m_icon_list; | 480 | Icons m_icon_list; |
486 | 481 | ||
487 | std::auto_ptr<Slit> m_slit; | 482 | std::auto_ptr<Slit> m_slit; |