all repos — fluxbox @ f0ffaf890f65d9902ba23e2cd019de5ddba071c5

custom fork of the fluxbox windowmanager

moved Menu placement into ScreenPlacement::placeAndShowMenu()
Mathias Gumz akira at fluxbox dot org
commit

f0ffaf890f65d9902ba23e2cd019de5ddba071c5

parent

49623390b623bcf4851e5cdd972e4c37d5103ecf

M src/FbCommands.ccsrc/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 @@ }

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); + screen.rootWindow().window(), &ignored_w, &ignored_w, + &x, &y, &ignored_i, &ignored_i, &ignored_ui); - int borderw = menu.fbwindow().borderWidth(); - int head = screen.getHead(rx, ry); - - menu.updateMenu(); - pair<int, int> 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.placementStrategy() + .placeAndShowMenu(menu, x, y, false); } }
M src/IconbarTool.ccsrc/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;
M src/ScreenPlacement.ccsrc/ScreenPlacement.cc

@@ -30,6 +30,8 @@

#include "Screen.hh" #include "Window.hh" +#include "FbTk/Menu.hh" + #include <iostream> #include <exception> #ifdef HAVE_CSTRING

@@ -51,7 +53,8 @@ m_placement_policy(screen.resourceManager(), ROWMINOVERLAPPLACEMENT,

screen.name()+".windowPlacement", screen.altName()+".WindowPlacement"), m_old_policy(ROWSMARTPLACEMENT), - m_strategy(0) + m_strategy(0), + m_screen(screen) { }

@@ -128,7 +131,51 @@

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<int, int> 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<signed>(m_screen.maxTop(head)); + int bottom = static_cast<signed>(m_screen.maxBottom(head)); + int left = static_cast<signed>(m_screen.maxLeft(head)); + int right = static_cast<signed>(m_screen.maxRight(head)); + + if (y < top) + y = top; + else if (y + static_cast<signed>(menu.height()) >= bottom) + y = bottom - menu.height() - 1 - menu.fbwindow().borderWidth(); + + if (x < left) + x = left; + else if (x + static_cast<signed>(menu.width()) >= right) + x = right - static_cast<int>(menu.width()) - 1; + } + + menu.move(x, y); + menu.show(); + menu.grabInputFocus(); +} ////////////////////// Placement Resources namespace FbTk {
M src/ScreenPlacement.hhsrc/ScreenPlacement.hh

@@ -27,6 +27,9 @@ #include "FbTk/Resource.hh"

#include <memory> +namespace FbTk { + class Menu; +} class BScreen; /**

@@ -65,6 +68,9 @@ /// @return true

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 @@ FbTk::Resource<PlacementPolicy> m_placement_policy; ///< placement policy resource

PlacementPolicy m_old_policy; ///< holds old policy, used to determine if resources has changed std::auto_ptr<PlacementStrategy> m_strategy; ///< main strategy std::auto_ptr<PlacementStrategy> m_fallback_strategy; ///< a fallback strategy if the main strategy fails + BScreen& m_screen; }; #endif // SCREENPLACEMENT_HH
M src/Slit.ccsrc/Slit.cc

@@ -34,6 +34,7 @@ #include "config.h"

#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 @@ return;

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<int, int> 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(); }
M src/ToolFactory.ccsrc/ToolFactory.cc

@@ -35,32 +35,21 @@ #include "ButtonTheme.hh"

#include "FbTk/CommandParser.hh" #include "Screen.hh" +#include "ScreenPlacement.hh" #include "Toolbar.hh" #include "fluxbox.hh" - -#include <utility> namespace { class ShowMenuAboveToolbar: public FbTk::Command<void> { 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<int, int> 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;
M src/Toolbar.ccsrc/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 @@ raise();

if (be.button != 3) return; - int head = screen().getHead(be.x_root, be.y_root); - int borderw = menu().fbwindow().borderWidth(); - pair<int, int> 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) {
M src/Window.ccsrc/Window.cc

@@ -1880,30 +1880,14 @@ return ret;

} /** - 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<signed>(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(); +void FluxboxWindow::showMenu(int x, int y) { - if (menu_x < static_cast<signed>(screen().maxLeft(head))) - menu_x = screen().maxLeft(head); - else if (menu_x + static_cast<signed>(menu().width()) >= static_cast<signed>(screen().maxRight(head))) - menu_x = screen().maxRight(head) - menu().width() - 1; - + 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) {