move titlebar click handling to FluxboxWindow, fix buttons getting ungrabbed
This commit is contained in:
parent
2e96a07cf7
commit
08ebff4b31
9 changed files with 73 additions and 153 deletions
|
@ -59,6 +59,7 @@ public:
|
|||
virtual void enterNotifyEvent(XCrossingEvent &) { }
|
||||
|
||||
virtual void notifyUngrabKeyboard() { }
|
||||
virtual void grabButtons() { }
|
||||
};
|
||||
|
||||
} // end namespace FbTk
|
||||
|
|
|
@ -96,7 +96,6 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr
|
|||
m_shaded(false),
|
||||
m_focused_alpha(0),
|
||||
m_unfocused_alpha(0),
|
||||
m_double_click_time(0),
|
||||
m_themelistener(*this),
|
||||
m_shape(m_window, theme.shapePlace()),
|
||||
m_disable_themeshape(false) {
|
||||
|
@ -109,23 +108,6 @@ FbWinFrame::~FbWinFrame() {
|
|||
removeAllButtons();
|
||||
}
|
||||
|
||||
bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &ref, int mousebutton_num,
|
||||
bool double_click, bool pressed) {
|
||||
// find mousebutton_num
|
||||
if (mousebutton_num < 1 || mousebutton_num > 5)
|
||||
return false;
|
||||
if (double_click)
|
||||
m_commands[mousebutton_num - 1].double_click = ref;
|
||||
else {
|
||||
if (pressed)
|
||||
m_commands[mousebutton_num - 1].click_pressed = ref;
|
||||
else
|
||||
m_commands[mousebutton_num - 1].click = ref;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FbWinFrame::setTabMode(TabMode tabmode) {
|
||||
if (m_tabmode == tabmode)
|
||||
return false;
|
||||
|
@ -570,10 +552,6 @@ void FbWinFrame::setUseDefaultAlpha(bool default_alpha)
|
|||
}
|
||||
}
|
||||
|
||||
void FbWinFrame::setDoubleClickTime(unsigned int time) {
|
||||
m_double_click_time = time;
|
||||
}
|
||||
|
||||
void FbWinFrame::addLeftButton(FbTk::Button *btn) {
|
||||
if (btn == 0) // valid button?
|
||||
return;
|
||||
|
@ -685,7 +663,7 @@ void FbWinFrame::setClientWindow(FbTk::FbWindow &win) {
|
|||
win.reparent(m_window, 0, clientArea().y());
|
||||
// remask window so we get events
|
||||
win.setEventMask(PropertyChangeMask | StructureNotifyMask |
|
||||
FocusChangeMask);
|
||||
FocusChangeMask | KeyPressMask);
|
||||
|
||||
m_window.setEventMask(ButtonPressMask | ButtonReleaseMask |
|
||||
ButtonMotionMask | EnterWindowMask | SubstructureRedirectMask);
|
||||
|
@ -855,47 +833,6 @@ void FbWinFrame::removeEventHandler() {
|
|||
evm.remove(m_clientarea);
|
||||
}
|
||||
|
||||
void FbWinFrame::buttonPressEvent(XButtonEvent &event) {
|
||||
m_tab_container.tryButtonPressEvent(event);
|
||||
if (event.window == m_grip_right.window() ||
|
||||
event.window == m_grip_left.window() ||
|
||||
event.window == m_clientarea.window() ||
|
||||
event.window == m_window.window())
|
||||
return;
|
||||
// we handle only buttons 0 to 5
|
||||
if (event.button > 5 || event.button < 1)
|
||||
return;
|
||||
|
||||
if (*m_commands[event.button - 1].click_pressed)
|
||||
m_commands[event.button - 1].click_pressed->execute();
|
||||
}
|
||||
|
||||
void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) {
|
||||
// we continue even if a button got the event
|
||||
m_tab_container.tryButtonReleaseEvent(event);
|
||||
|
||||
if (event.window == m_grip_right.window() ||
|
||||
event.window == m_grip_left.window() ||
|
||||
event.window == m_clientarea.window() ||
|
||||
event.window == m_handle.window() ||
|
||||
event.window == m_window.window())
|
||||
return;
|
||||
|
||||
if (event.button < 1 || event.button > 5)
|
||||
return;
|
||||
|
||||
static Time last_release_time = 0;
|
||||
bool double_click = (event.time - last_release_time <= m_double_click_time);
|
||||
last_release_time = event.time;
|
||||
int real_button = event.button - 1;
|
||||
|
||||
if (double_click && *m_commands[real_button].double_click)
|
||||
m_commands[real_button].double_click->execute();
|
||||
else if (*m_commands[real_button].click)
|
||||
m_commands[real_button].click->execute();
|
||||
|
||||
}
|
||||
|
||||
void FbWinFrame::exposeEvent(XExposeEvent &event) {
|
||||
if (m_titlebar == event.window) {
|
||||
m_titlebar.clearArea(event.x, event.y, event.width, event.height);
|
||||
|
@ -1409,7 +1346,6 @@ void FbWinFrame::init() {
|
|||
m_button_pm = m_button_unfocused_pm = m_button_pressed_pm = 0;
|
||||
m_grip_unfocused_pm = m_grip_focused_pm = 0;
|
||||
|
||||
m_double_click_time = 200;
|
||||
m_button_size = 26;
|
||||
|
||||
m_clientarea.setBorderWidth(0);
|
||||
|
|
|
@ -88,10 +88,6 @@ public:
|
|||
/// destroy frame
|
||||
~FbWinFrame();
|
||||
|
||||
/// setup actions for titlebar
|
||||
bool setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &cmd, int button_num,
|
||||
bool double_click=false, bool pressed=false);
|
||||
|
||||
void hide();
|
||||
void show();
|
||||
inline bool isVisible() const { return m_visible; }
|
||||
|
@ -124,7 +120,6 @@ public:
|
|||
/// set focus/unfocus style
|
||||
void setFocus(bool newvalue);
|
||||
inline void setFocusTitle(const std::string &str) { m_label.setText(str); }
|
||||
void setDoubleClickTime(unsigned int time);
|
||||
bool setTabMode(TabMode tabmode);
|
||||
inline void updateTabProperties() { alignTabs(); }
|
||||
|
||||
|
@ -186,8 +181,6 @@ public:
|
|||
@name Event handlers
|
||||
*/
|
||||
//@{
|
||||
void buttonPressEvent(XButtonEvent &event);
|
||||
void buttonReleaseEvent(XButtonEvent &event);
|
||||
void exposeEvent(XExposeEvent &event);
|
||||
void configureNotifyEvent(XConfigureEvent &event);
|
||||
void handleEvent(XEvent &event);
|
||||
|
@ -377,13 +370,6 @@ private:
|
|||
bool m_shaded; ///< wheter we're shaded or not
|
||||
unsigned char m_focused_alpha; ///< focused alpha value
|
||||
unsigned char m_unfocused_alpha; ///< unfocused alpha value
|
||||
unsigned int m_double_click_time; ///< the time period that's considerd to be a double click
|
||||
struct MouseButtonAction {
|
||||
FbTk::RefCount<FbTk::Command> click; ///< what to do when we release mouse button
|
||||
FbTk::RefCount<FbTk::Command> click_pressed; ///< what to do when we press mouse button
|
||||
FbTk::RefCount<FbTk::Command> double_click; ///< what to do when we double click
|
||||
};
|
||||
MouseButtonAction m_commands[5]; ///< hardcoded to five ... //!! TODO, change this
|
||||
|
||||
class ThemeListener: public FbTk::Observer {
|
||||
public:
|
||||
|
|
|
@ -126,11 +126,11 @@ void FocusableList::update(FbTk::Subject *subj) {
|
|||
FocusableListSubject *fsubj =
|
||||
static_cast<FocusableListSubject *>(subj);
|
||||
if (subj == &m_parent->addSig()) {
|
||||
attachSignals(*fsubj->win());
|
||||
if (m_pat->match(*fsubj->win())) {
|
||||
insertFromParent(*fsubj->win());
|
||||
m_addsig.notify(fsubj->win());
|
||||
} else // we still want to watch it, in case it changes to match
|
||||
attachSignals(*fsubj->win());
|
||||
}
|
||||
} else if (subj == &m_parent->removeSig())
|
||||
remove(*fsubj->win());
|
||||
else if (subj == &m_parent->resetSig())
|
||||
|
|
12
src/Keys.cc
12
src/Keys.cc
|
@ -168,6 +168,7 @@ void Keys::grabWindow(Window win) {
|
|||
if (win_it == m_window_map.end())
|
||||
return;
|
||||
|
||||
m_handler_map[win]->grabButtons();
|
||||
keylist_t::iterator it = m_keylist->keylist.begin();
|
||||
keylist_t::iterator it_end = m_keylist->keylist.end();
|
||||
for (; it != it_end; ++it) {
|
||||
|
@ -428,8 +429,9 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key,
|
|||
}
|
||||
|
||||
/// adds the window to m_window_map, so we know to grab buttons on it
|
||||
void Keys::registerWindow(Window win, int context) {
|
||||
void Keys::registerWindow(Window win, FbTk::EventHandler &h, int context) {
|
||||
m_window_map[win] = context;
|
||||
m_handler_map[win] = &h;
|
||||
grabWindow(win);
|
||||
}
|
||||
|
||||
|
@ -437,6 +439,7 @@ void Keys::registerWindow(Window win, int context) {
|
|||
void Keys::unregisterWindow(Window win) {
|
||||
FbTk::KeyUtil::ungrabKeys(win);
|
||||
FbTk::KeyUtil::ungrabButtons(win);
|
||||
m_handler_map.erase(win);
|
||||
m_window_map.erase(win);
|
||||
}
|
||||
|
||||
|
@ -459,6 +462,13 @@ void Keys::keyMode(string keyMode) {
|
|||
void Keys::setKeyMode(t_key *keyMode) {
|
||||
ungrabKeys();
|
||||
ungrabButtons();
|
||||
|
||||
// notify handlers that their buttons have been ungrabbed
|
||||
HandlerMap::iterator h_it = m_handler_map.begin(),
|
||||
h_it_end = m_handler_map.end();
|
||||
for (; h_it != h_it_end; ++h_it)
|
||||
h_it->second->grabButtons();
|
||||
|
||||
keylist_t::iterator it = keyMode->keylist.begin();
|
||||
keylist_t::iterator it_end = keyMode->keylist.end();
|
||||
for (; it != it_end; ++it) {
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include "FbTk/Command.hh"
|
||||
#include "FbTk/KeyUtil.hh"
|
||||
|
||||
namespace FbTk {
|
||||
class EventHandler;
|
||||
}
|
||||
|
||||
class Keys:private FbTk::NotCopyable {
|
||||
public:
|
||||
|
||||
|
@ -78,7 +82,7 @@ public:
|
|||
bool doAction(int type, unsigned int mods, unsigned int key, int context);
|
||||
|
||||
/// register a window so that proper keys/buttons get grabbed on it
|
||||
void registerWindow(Window win, int context);
|
||||
void registerWindow(Window win, FbTk::EventHandler &handler, int context);
|
||||
/// unregister window
|
||||
void unregisterWindow(Window win);
|
||||
|
||||
|
@ -145,7 +149,9 @@ private:
|
|||
Display *m_display; ///< display connection
|
||||
|
||||
typedef std::map<Window, int> WindowMap;
|
||||
typedef std::map<Window, FbTk::EventHandler*> HandlerMap;
|
||||
WindowMap m_window_map;
|
||||
HandlerMap m_handler_map;
|
||||
};
|
||||
|
||||
#endif // KEYS_HH
|
||||
|
|
|
@ -431,7 +431,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
evm->add(*this, rootWindow());
|
||||
Keys *keys = Fluxbox::instance()->keys();
|
||||
if (keys)
|
||||
keys->registerWindow(rootWindow().window(),
|
||||
keys->registerWindow(rootWindow().window(), *this,
|
||||
Keys::GLOBAL|Keys::ON_DESKTOP);
|
||||
rootWindow().setCursor(XCreateFontCursor(disp, XC_left_ptr));
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
|
|||
scrn.resourceManager().unlock();
|
||||
// setup to listen to child events
|
||||
FbTk::EventManager::instance()->addParent(*this, window());
|
||||
Fluxbox::instance()->keys()->registerWindow(window().window(),
|
||||
Fluxbox::instance()->keys()->registerWindow(window().window(), *this,
|
||||
Keys::ON_TOOLBAR);
|
||||
// get everything together
|
||||
reconfigure();
|
||||
|
|
117
src/Window.cc
117
src/Window.cc
|
@ -289,7 +289,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm,
|
|||
screen().focusControl().addFocusWinBack(*this);
|
||||
|
||||
Fluxbox::instance()->keys()->registerWindow(frame().window().window(),
|
||||
Keys::ON_WINDOW);
|
||||
*this, Keys::ON_WINDOW);
|
||||
|
||||
}
|
||||
|
||||
|
@ -479,8 +479,6 @@ void FluxboxWindow::init() {
|
|||
|
||||
applyDecorations(true);
|
||||
|
||||
grabButtons();
|
||||
|
||||
restoreAttributes();
|
||||
|
||||
if (m_workspace_number >= screen().numberOfWorkspaces())
|
||||
|
@ -1062,9 +1060,6 @@ void FluxboxWindow::reconfigure() {
|
|||
|
||||
moveResize(frame().x(), frame().y(), frame().width(), frame().height());
|
||||
|
||||
grabButtons();
|
||||
|
||||
frame().setDoubleClickTime(Fluxbox::instance()->getDoubleClickInterval());
|
||||
m_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay());
|
||||
|
||||
updateButtons();
|
||||
|
@ -1072,29 +1067,6 @@ void FluxboxWindow::reconfigure() {
|
|||
|
||||
menu().reconfigure();
|
||||
|
||||
typedef FbTk::RefCount<FbTk::Command> CommandRef;
|
||||
typedef FbTk::SimpleCommand<FluxboxWindow> WindowCmd;
|
||||
CommandRef shade_on_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOn));
|
||||
CommandRef shade_off_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOff));
|
||||
CommandRef next_tab_cmd(new WindowCmd(*this, &FluxboxWindow::nextClient));
|
||||
CommandRef prev_tab_cmd(new WindowCmd(*this, &FluxboxWindow::prevClient));
|
||||
CommandRef null_cmd;
|
||||
|
||||
int reverse = 0;
|
||||
if (screen().getScrollReverse())
|
||||
reverse = 1;
|
||||
|
||||
if (StringUtil::toLower(screen().getScrollAction()) == string("shade")) {
|
||||
frame().setOnClickTitlebar(shade_on_cmd, 5 - reverse); // shade on mouse roll
|
||||
frame().setOnClickTitlebar(shade_off_cmd, 4 + reverse); // unshade if rolled oposite direction
|
||||
} else if (StringUtil::toLower(screen().getScrollAction()) == string("nexttab")) {
|
||||
frame().setOnClickTitlebar(next_tab_cmd, 5 - reverse); // next tab
|
||||
frame().setOnClickTitlebar(prev_tab_cmd, 4 + reverse); // previous tab
|
||||
} else {
|
||||
frame().setOnClickTitlebar(null_cmd, 4);
|
||||
frame().setOnClickTitlebar(null_cmd, 5);
|
||||
}
|
||||
|
||||
Client2ButtonMap::iterator it = m_labelbuttons.begin(),
|
||||
it_end = m_labelbuttons.end();
|
||||
for (; it != it_end; ++it)
|
||||
|
@ -2584,14 +2556,20 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
|
|||
return;
|
||||
}
|
||||
|
||||
// check frame events first
|
||||
frame().buttonPressEvent(be);
|
||||
|
||||
frame().tabcontainer().tryButtonPressEvent(be);
|
||||
if (be.button == 1) {
|
||||
if (!m_focused && acceptsFocus()) //check focus
|
||||
focus();
|
||||
|
||||
if (frame().window().window() == be.window || frame().tabcontainer().window() == be.window) {
|
||||
// click on titlebar
|
||||
if (frame().gripLeft().window() != be.window &&
|
||||
frame().gripRight().window() != be.window &&
|
||||
frame().clientArea().window() != be.window &&
|
||||
frame().window() != be.window)
|
||||
raise();
|
||||
|
||||
if (frame().window().window() == be.window ||
|
||||
frame().tabcontainer().window() == be.window) {
|
||||
if (screen().clickRaises())
|
||||
raise();
|
||||
#ifdef DEBUG
|
||||
|
@ -2618,8 +2596,44 @@ void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) {
|
|||
stopResizing();
|
||||
else if (m_attaching_tab)
|
||||
attachTo(re.x_root, re.y_root);
|
||||
else
|
||||
frame().buttonReleaseEvent(re);
|
||||
else {
|
||||
frame().tabcontainer().tryButtonReleaseEvent(re);
|
||||
if (frame().gripLeft().window() == re.window ||
|
||||
frame().gripRight().window() == re.window ||
|
||||
frame().clientArea().window() == re.window ||
|
||||
frame().handle().window() == re.window ||
|
||||
frame().window() == re.window)
|
||||
return;
|
||||
|
||||
static Time last_release_time = 0;
|
||||
bool double_click = (re.time - last_release_time <=
|
||||
Fluxbox::instance()->getDoubleClickInterval());
|
||||
last_release_time = re.time;
|
||||
|
||||
if (re.button == 1 && double_click)
|
||||
shade();
|
||||
if (re.button == 3)
|
||||
popupMenu();
|
||||
if (re.button == 2)
|
||||
lower();
|
||||
|
||||
unsigned int reverse = (screen().getScrollReverse() ? 1 : 0);
|
||||
if (re.button == 4 || re.button == 5) {
|
||||
if (StringUtil::toLower(screen().getScrollAction()) == "shade") {
|
||||
if (re.button == 5 - reverse)
|
||||
shadeOn();
|
||||
else
|
||||
shadeOff();
|
||||
}
|
||||
if (StringUtil::toLower(screen().getScrollAction()) == "nexttab") {
|
||||
if (re.button == 5 - reverse)
|
||||
nextClient();
|
||||
else
|
||||
prevClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -3774,19 +3788,6 @@ void FluxboxWindow::setupWindow() {
|
|||
// we allow both to be done at once to share the commands
|
||||
|
||||
using namespace FbTk;
|
||||
typedef RefCount<Command> CommandRef;
|
||||
typedef SimpleCommand<FluxboxWindow> WindowCmd;
|
||||
|
||||
CommandRef shade_cmd(new WindowCmd(*this, &FluxboxWindow::shade));
|
||||
CommandRef shade_on_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOn));
|
||||
CommandRef shade_off_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOff));
|
||||
CommandRef next_tab_cmd(new WindowCmd(*this, &FluxboxWindow::nextClient));
|
||||
CommandRef prev_tab_cmd(new WindowCmd(*this, &FluxboxWindow::prevClient));
|
||||
CommandRef lower_cmd(new WindowCmd(*this, &FluxboxWindow::lower));
|
||||
CommandRef raise_and_focus_cmd(new WindowCmd(*this, &FluxboxWindow::raiseAndFocus));
|
||||
CommandRef stick_cmd(new WindowCmd(*this, &FluxboxWindow::stick));
|
||||
CommandRef show_menu_cmd(new WindowCmd(*this, &FluxboxWindow::popupMenu));
|
||||
|
||||
typedef FbTk::Resource<vector<WinButton::Type> > WinButtonsResource;
|
||||
|
||||
string titlebar_name[2];
|
||||
|
@ -3842,26 +3843,6 @@ void FluxboxWindow::setupWindow() {
|
|||
|
||||
updateButtons();
|
||||
|
||||
// setup titlebar
|
||||
frame().setOnClickTitlebar(raise_and_focus_cmd, 1, false, true); // on press with button 1
|
||||
frame().setOnClickTitlebar(shade_cmd, 1, true); // doubleclick with button 1
|
||||
frame().setOnClickTitlebar(show_menu_cmd, 3); // on release with button 3
|
||||
frame().setOnClickTitlebar(lower_cmd, 2); // on release with button 2
|
||||
|
||||
int reverse = 0;
|
||||
if (screen().getScrollReverse())
|
||||
reverse = 1;
|
||||
|
||||
if (StringUtil::toLower(screen().getScrollAction()) == string("shade")) {
|
||||
frame().setOnClickTitlebar(shade_on_cmd, 5 - reverse); // shade on mouse roll
|
||||
frame().setOnClickTitlebar(shade_off_cmd, 4 + reverse); // unshade if rolled oposite direction
|
||||
} else if (StringUtil::toLower(screen().getScrollAction()) == string("nexttab")) {
|
||||
frame().setOnClickTitlebar(next_tab_cmd, 5 - reverse); // next tab
|
||||
frame().setOnClickTitlebar(prev_tab_cmd, 4 + reverse); // previous tab
|
||||
}
|
||||
|
||||
frame().setDoubleClickTime(Fluxbox::instance()->getDoubleClickInterval());
|
||||
|
||||
// end setup frame
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue