From f0ffaf890f65d9902ba23e2cd019de5ddba071c5 Mon Sep 17 00:00:00 2001 From: Mathias Gumz Date: Thu, 24 Feb 2011 11:21:16 +0100 Subject: moved Menu placement into ScreenPlacement::placeAndShowMenu() --- src/FbCommands.cc | 40 ++++++++++++---------------------------- src/IconbarTool.cc | 6 ++---- src/ScreenPlacement.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- src/ScreenPlacement.hh | 7 +++++++ src/Slit.cc | 18 +++--------------- src/ToolFactory.cc | 25 +++++++------------------ src/Toolbar.cc | 20 ++++---------------- src/Window.cc | 26 +++++--------------------- 8 files changed, 88 insertions(+), 103 deletions(-) diff --git a/src/FbCommands.cc b/src/FbCommands.cc index 4dffd8d..be52e47 100644 --- a/src/FbCommands.cc +++ b/src/FbCommands.cc @@ -22,6 +22,7 @@ #include "FbCommands.hh" #include "fluxbox.hh" #include "Screen.hh" +#include "ScreenPlacement.hh" #include "CommandDialog.hh" #include "FocusControl.hh" #include "Workspace.hh" @@ -71,7 +72,7 @@ using std::ios; namespace { -void showMenu(const BScreen &screen, FbTk::Menu &menu) { +void showMenu(BScreen &screen, FbTk::Menu &menu) { // check if menu has changed if (typeid(menu) == typeid(FbMenu)) { @@ -82,36 +83,19 @@ void showMenu(const BScreen &screen, FbTk::Menu &menu) { FbMenu::setWindow(FocusControl::focusedFbWindow()); - Window root_ret; // not used - Window window_ret; // not used + Window ignored_w; + int ignored_i; + unsigned int ignored_ui; - int rx = 0, ry = 0; - int wx, wy; // not used - unsigned int mask; // not used + int x = 0; + int y = 0; XQueryPointer(menu.fbwindow().display(), - screen.rootWindow().window(), &root_ret, &window_ret, - &rx, &ry, &wx, &wy, &mask); - - int borderw = menu.fbwindow().borderWidth(); - int head = screen.getHead(rx, ry); - - menu.updateMenu(); - pair m = - screen.clampToHead(head, - rx - menu.width() / 2, - ry - menu.titleWindow().height() / 2, - menu.width() + 2*borderw, - menu.height() + 2*borderw); - - menu.move(m.first, m.second); - menu.setScreen(screen.getHeadX(head), - screen.getHeadY(head), - screen.getHeadWidth(head), - screen.getHeadHeight(head)); - - menu.show(); - menu.grabInputFocus(); + screen.rootWindow().window(), &ignored_w, &ignored_w, + &x, &y, &ignored_i, &ignored_i, &ignored_ui); + + screen.placementStrategy() + .placeAndShowMenu(menu, x, y, false); } } diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index 62eae0d..932121f 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc @@ -212,10 +212,8 @@ public: explicit ShowMenu(FluxboxWindow &win):m_win(win) { } void execute() { // get last button pos - const XEvent &event = Fluxbox::instance()->lastEvent(); - int x = event.xbutton.x_root - (m_win.menu().width() / 2); - int y = event.xbutton.y_root - (m_win.menu().height() / 2); - m_win.popupMenu(x, y); + const XEvent &e = Fluxbox::instance()->lastEvent(); + m_win.popupMenu(e.xbutton.x_root, e.xbutton.y_root); } private: FluxboxWindow &m_win; diff --git a/src/ScreenPlacement.cc b/src/ScreenPlacement.cc index 3e0c377..46ff718 100644 --- a/src/ScreenPlacement.cc +++ b/src/ScreenPlacement.cc @@ -30,6 +30,8 @@ #include "Screen.hh" #include "Window.hh" +#include "FbTk/Menu.hh" + #include #include #ifdef HAVE_CSTRING @@ -51,7 +53,8 @@ ScreenPlacement::ScreenPlacement(BScreen &screen): screen.name()+".windowPlacement", screen.altName()+".WindowPlacement"), m_old_policy(ROWSMARTPLACEMENT), - m_strategy(0) + m_strategy(0), + m_screen(screen) { } @@ -128,7 +131,51 @@ bool ScreenPlacement::placeWindow(const FluxboxWindow &win, int head, return true; } +bool ScreenPlacement::placeAndShowMenu(FbTk::Menu& menu, int x, int y, bool respect_struts) { + + int head = m_screen.getHead(x, y); + + menu.setScreen(m_screen.getHeadX(head), + m_screen.getHeadY(head), + m_screen.getHeadWidth(head), + m_screen.getHeadHeight(head)); + + menu.updateMenu(); // recalculate the size + + x = x - (menu.width() / 2); + if (menu.isTitleVisible()) + y = y - (menu.titleWindow().height() / 2); + + // adjust (x, y) to fit on the screen + if (!respect_struts) { + + int bw = 2 * menu.fbwindow().borderWidth(); + std::pair pos = m_screen.clampToHead(head, x, y, menu.width() + bw, menu.height() + bw); + x = pos.first; + y = pos.second; + } else { // do not cover toolbar if no title + + int top = static_cast(m_screen.maxTop(head)); + int bottom = static_cast(m_screen.maxBottom(head)); + int left = static_cast(m_screen.maxLeft(head)); + int right = static_cast(m_screen.maxRight(head)); + + if (y < top) + y = top; + else if (y + static_cast(menu.height()) >= bottom) + y = bottom - menu.height() - 1 - menu.fbwindow().borderWidth(); + + if (x < left) + x = left; + else if (x + static_cast(menu.width()) >= right) + x = right - static_cast(menu.width()) - 1; + } + + menu.move(x, y); + menu.show(); + menu.grabInputFocus(); +} ////////////////////// Placement Resources namespace FbTk { diff --git a/src/ScreenPlacement.hh b/src/ScreenPlacement.hh index b60726f..7093c9b 100644 --- a/src/ScreenPlacement.hh +++ b/src/ScreenPlacement.hh @@ -27,6 +27,9 @@ #include +namespace FbTk { + class Menu; +} class BScreen; /** @@ -65,6 +68,9 @@ public: bool placeWindow(const FluxboxWindow &window, int head, int &place_x, int &place_y); + // places and show 'menu' at 'x','y' + bool placeAndShowMenu(FbTk::Menu& menu, int x, int y, bool respect_struts); + RowDirection rowDirection() const { return *m_row_direction; } ColumnDirection colDirection() const { return *m_col_direction; } @@ -75,6 +81,7 @@ private: PlacementPolicy m_old_policy; ///< holds old policy, used to determine if resources has changed std::auto_ptr m_strategy; ///< main strategy std::auto_ptr m_fallback_strategy; ///< a fallback strategy if the main strategy fails + BScreen& m_screen; }; #endif // SCREENPLACEMENT_HH diff --git a/src/Slit.cc b/src/Slit.cc index aa62997..8ad83dd 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -34,6 +34,7 @@ #endif // HAVE_CONFIG_H #include "Screen.hh" +#include "ScreenPlacement.hh" #include "FbTk/ImageControl.hh" #include "FbTk/RefCount.hh" #include "FbTk/EventManager.hh" @@ -952,21 +953,8 @@ void Slit::buttonPressEvent(XButtonEvent &be) { if (be.button == Button3) { if (! m_slitmenu.isVisible()) { - int head = screen().getHead(be.x_root, be.y_root); - int borderw = m_slitmenu.fbwindow().borderWidth(); - pair m = screen().clampToHead(head, - be.x_root - (m_slitmenu.width() / 2), - be.y_root - (m_slitmenu.titleWindow().height() / 2), - m_slitmenu.width() + 2*borderw, - m_slitmenu.height() + 2*borderw); - - m_slitmenu.setScreen(screen().getHeadX(head), - screen().getHeadY(head), - screen().getHeadWidth(head), - screen().getHeadHeight(head)); - m_slitmenu.move(m.first, m.second); - m_slitmenu.show(); - m_slitmenu.grabInputFocus(); + screen().placementStrategy() + .placeAndShowMenu(m_slitmenu, be.x_root, be.y_root, false); } else m_slitmenu.hide(); } diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc index 84184eb..b998a88 100644 --- a/src/ToolFactory.cc +++ b/src/ToolFactory.cc @@ -35,32 +35,21 @@ #include "FbTk/CommandParser.hh" #include "Screen.hh" +#include "ScreenPlacement.hh" #include "Toolbar.hh" #include "fluxbox.hh" -#include - namespace { class ShowMenuAboveToolbar: public FbTk::Command { public: explicit ShowMenuAboveToolbar(Toolbar &tbar):m_tbar(tbar) { } void execute() { - // get last button pos - const XEvent &event = Fluxbox::instance()->lastEvent(); - int head = m_tbar.screen().getHead(event.xbutton.x_root, event.xbutton.y_root); - std::pair m = - m_tbar.screen().clampToHead( head, - event.xbutton.x_root - (m_tbar.menu().width() / 2), - event.xbutton.y_root - (m_tbar.menu().height() / 2), - m_tbar.menu().width(), - m_tbar.menu().height()); - m_tbar.menu().setScreen(m_tbar.screen().getHeadX(head), - m_tbar.screen().getHeadY(head), - m_tbar.screen().getHeadWidth(head), - m_tbar.screen().getHeadHeight(head)); - m_tbar.menu().move(m.first, m.second); - m_tbar.menu().show(); - m_tbar.menu().grabInputFocus(); + + const XEvent& e= Fluxbox::instance()->lastEvent(); + + m_tbar.screen() + .placementStrategy() + .placeAndShowMenu(m_tbar.menu(), e.xbutton.x_root, e.xbutton.y_root, false); } private: Toolbar &m_tbar; diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 896268f..cb1a956 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -33,6 +33,7 @@ #include "fluxbox.hh" #include "Keys.hh" #include "Screen.hh" +#include "ScreenPlacement.hh" #include "WindowCmd.hh" #include "Strut.hh" @@ -520,22 +521,9 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) { if (be.button != 3) return; - int head = screen().getHead(be.x_root, be.y_root); - int borderw = menu().fbwindow().borderWidth(); - pair m = screen().clampToHead(head, - be.x_root - (menu().width() / 2), - be.y_root - (menu().titleWindow().height() / 2), - menu().width() + 2*borderw, - menu().height() + 2*borderw); - - menu().setScreen(screen().getHeadX(head), - screen().getHeadY(head), - screen().getHeadWidth(head), - screen().getHeadHeight(head)); - menu().move(m.first, m.second); - menu().show(); - menu().grabInputFocus(); - + screen() + .placementStrategy() + .placeAndShowMenu(menu(), be.x_root, be.y_root, false); } void Toolbar::enterNotifyEvent(XCrossingEvent &ce) { diff --git a/src/Window.cc b/src/Window.cc index c87180d..51a66df 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1880,30 +1880,14 @@ bool FluxboxWindow::getState() { } /** - Show the window menu at pos mx, my + Show the window menu at pos x, y */ -void FluxboxWindow::showMenu(int menu_x, int menu_y) { - menu().reloadHelper()->checkReload(); - - int head = screen().getHead(menu_x, menu_y); - - menu().updateMenu(); // recalculate the menu size - - // move menu directly under titlebar but not off the screen - if (menu_y < static_cast(screen().maxTop(head))) - menu_y = screen().maxTop(head); - else if (menu_y + menu().height() >= screen().maxBottom(head)) - menu_y = screen().maxBottom(head) - menu().height() - 1 - menu().fbwindow().borderWidth(); - - if (menu_x < static_cast(screen().maxLeft(head))) - menu_x = screen().maxLeft(head); - else if (menu_x + static_cast(menu().width()) >= static_cast(screen().maxRight(head))) - menu_x = screen().maxRight(head) - menu().width() - 1; +void FluxboxWindow::showMenu(int x, int y) { + menu().reloadHelper()->checkReload(); FbMenu::setWindow(this); - menu().move(menu_x, menu_y); - menu().show(); - menu().grabInputFocus(); + screen().placementStrategy() + .placeAndShowMenu(menu(), x, y, true); } void FluxboxWindow::popupMenu(int x, int y) { -- cgit v0.11.2