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 /src/Screen.cc | |
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
Diffstat (limited to 'src/Screen.cc')
-rw-r--r-- | src/Screen.cc | 52 |
1 files changed, 8 insertions, 44 deletions
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()) { |