moved Menu placement into ScreenPlacement::placeAndShowMenu()

This commit is contained in:
Mathias Gumz 2011-02-24 11:21:16 +01:00
parent 49623390b6
commit f0ffaf890f
8 changed files with 87 additions and 102 deletions

View file

@ -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);
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);
}
}

View file

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

View file

@ -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 @@ 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<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 {

View file

@ -27,6 +27,9 @@
#include <memory>
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<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

View file

@ -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<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();
}

View file

@ -35,32 +35,21 @@
#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;

View file

@ -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<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) {

View file

@ -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) {
void FluxboxWindow::showMenu(int x, int 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();
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;
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) {