From 3490c73f570cb43fcdea5c2f8770a379d721a73d Mon Sep 17 00:00:00 2001 From: fluxgen Date: Tue, 30 Dec 2003 20:56:41 +0000 Subject: fixed focus issue --- src/WinClient.cc | 6 +- src/Window.cc | 40 ++++++-------- src/Window.hh | 6 +- src/fluxbox.cc | 164 +++++++++++-------------------------------------------- src/fluxbox.hh | 41 +++----------- 5 files changed, 61 insertions(+), 196 deletions(-) diff --git a/src/WinClient.cc b/src/WinClient.cc index 111e51d..2524106 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: WinClient.cc,v 1.36 2003/12/21 15:24:28 rathnor Exp $ +// $Id: WinClient.cc,v 1.37 2003/12/30 20:56:41 fluxgen Exp $ #include "WinClient.hh" @@ -118,10 +118,8 @@ WinClient::~WinClient() { if (m_blackbox_hint != 0) XFree(m_blackbox_hint); - if (window()) { + if (window()) fluxbox->removeWindowSearch(window()); - fluxbox->removeRedirectEvent(None, window()); - } m_win = 0; } diff --git a/src/Window.cc b/src/Window.cc index be790ca..6cc3af9 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.257 2003/12/21 23:23:03 fluxgen Exp $ +// $Id: Window.cc,v 1.258 2003/12/30 20:56:40 fluxgen Exp $ #include "Window.hh" @@ -516,6 +516,8 @@ void FluxboxWindow::init() { if (!place_window) moveResize(frame().x(), frame().y(), frame().width(), frame().height()); + + screen().getWorkspace(m_workspace_number)->addWindow(*this, place_window); if (shaded) { // start shaded @@ -895,14 +897,14 @@ void FluxboxWindow::updateClientLeftWindow() { } } -bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput, long ignore_event) { +bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { // make sure it's in our list if (client.m_win != this) return false; m_client = &client; m_client->raise(); - if (setinput && setInputFocus(ignore_event)) { + if (setinput && setInputFocus()) { frame().setLabelButtonFocus(*m_labelbuttons[m_client]); return true; } @@ -1154,7 +1156,7 @@ void FluxboxWindow::moveResize(int new_x, int new_y, // tried. A FocusqIn event should eventually arrive for that // window if it actually got the focus, then setFocusedFlag is called, // which updates all the graphics etc -bool FluxboxWindow::setInputFocus(long ignore_event) { +bool FluxboxWindow::setInputFocus() { if (((signed) (frame().x() + frame().width())) < 0) { if (((signed) (frame().y() + frame().height())) < 0) { @@ -1215,13 +1217,6 @@ bool FluxboxWindow::setInputFocus(long ignore_event) { ret = m_client->sendFocus(); } - - // People can ignore an event until the focus comes through - // this is most likely to be an EnterNotify for sloppy focus - if (ret && m_client->getFocusMode() != WinClient::F_NOINPUT && ignore_event != None) - Fluxbox::instance()->addRedirectEvent( - &screen(), ignore_event, None, - FocusIn, m_client->window(), None); return ret; } @@ -2656,7 +2651,7 @@ void FluxboxWindow::setDecoration(Decoration decoration) { // commit current decoration values to actual displayed things void FluxboxWindow::applyDecorations(bool initial) { frame().clientArea().setBorderWidth(0); // client area bordered by other things - bool client_move = false; + int grav_x=0, grav_y=0; // negate gravity @@ -2666,6 +2661,8 @@ void FluxboxWindow::applyDecorations(bool initial) { if (decorations.border) border_width = frame().theme().border().width(); + bool client_move = false; + if (initial || frame().window().borderWidth() != border_width) { client_move = true; frame().setBorderWidth(border_width); @@ -2768,16 +2765,7 @@ void FluxboxWindow::startMoving(Window win) { if (m_windowmenu.isVisible()) m_windowmenu.hide(); - // The "stop" window and event aren't going to happen (since it's - // grabbed, so they are just so we can remove it in stopMoving) - fluxbox->addRedirectEvent(&screen(), - MotionNotify, screen().rootWindow().window(), - MotionNotify, fbWindow().window(), - fbWindow().window()); - fluxbox->addRedirectEvent(&screen(), - ButtonRelease, screen().rootWindow().window(), - ButtonRelease, fbWindow().window(), - fbWindow().window()); + fluxbox->maskWindowEvents(screen().rootWindow().window(), this); m_last_move_x = frame().x(); m_last_move_y = frame().y(); @@ -2795,8 +2783,8 @@ void FluxboxWindow::stopMoving() { moving = false; Fluxbox *fluxbox = Fluxbox::instance(); - fluxbox->removeRedirectEvent(MotionNotify, fbWindow().window()); - fluxbox->removeRedirectEvent(ButtonRelease, fbWindow().window()); + fluxbox->maskWindowEvents(0, 0); + if (! screen().doOpaqueMove()) { parent().drawRectangle(screen().rootTheme().opGC(), @@ -3026,6 +3014,10 @@ void FluxboxWindow::attachTo(int x, int y) { if (client) attach_to_win = client->fbwindow(); + cerr<<"client = "< -void FbTk::Resource:: -setFromString(const char *strval) { - if (sscanf(strval, "%ld", &m_value) != 1) - setDefaultValue(); -} - //----------------------------------------------------------------- //---- manipulators for int, bool, and some enums with Resource --- //----------------------------------------------------------------- @@ -266,14 +259,6 @@ getString() { } template<> -string FbTk::Resource:: -getString() { - char tmpstr[128]; - sprintf(tmpstr, "%ld", m_value); - return string(tmpstr); -} - -template<> void FbTk::Resource:: setFromString(const char *strval) { int tempnum = 0; @@ -322,6 +307,20 @@ getString() { return string(tmpstr); } } +template<> +void FbTk::Resource:: +setFromString(const char *strval) { + if (sscanf(strval, "%ld", &m_value) != 1) + setDefaultValue(); +} + + +string FbTk::Resource:: +getString() { + char tmpstr[128]; + sprintf(tmpstr, "%ld", m_value); + return string(tmpstr); +} static Window last_bad_window = None; namespace { @@ -393,11 +392,12 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), m_rc_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"), - m_focused_window(0), + m_focused_window(0), m_masked_window(0), m_mousescreen(0), m_keyscreen(0), m_watching_screen(0), m_watch_keyrelease(0), m_last_time(0), + m_masked(0), m_rc_file(rcfilename ? rcfilename : ""), m_argv(argv), m_argc(argc), m_starting(true), @@ -405,9 +405,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile m_server_grabs(0), m_randr_event_type(0), m_RC_PATH("fluxbox"), - m_RC_INIT_FILE("init"), - m_focus_revert_screen(0) -{ + m_RC_INIT_FILE("init") { if (s_singleton != 0) @@ -552,7 +550,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile m_atomhandler[atomh]->initForScreen(*screen); } - revertFocus(*screen, false); // make sure focus style is correct + revertFocus(*screen); // make sure focus style is correct } // end init screens @@ -624,10 +622,6 @@ void Fluxbox::eventLoop() { } else { last_bad_window = None; handleEvent(&e); - if (m_focus_revert_screen != 0) { - revertFocus(*m_focus_revert_screen, false); - m_focus_revert_screen = 0; - } } } else { FbTk::Timer::updateTimers(ConnectionNumber(disp)); //handle all timers @@ -718,52 +712,18 @@ void Fluxbox::handleEvent(XEvent * const e) { m_last_event = *e; // it is possible (e.g. during moving) for a window - // to mask certain events to go somewhere (e.g. to that window) - if (!m_redirect_events.empty()) { - - bool drop_event = false; - RedirectEvents::iterator it = m_redirect_events.begin(); - RedirectEvents::iterator it_end = m_redirect_events.end(); - RedirectEvent *re = 0; - bool matched = false; - Window orig_win = e->xany.window; - - // look through all registered redirects - while (it != it_end) { - matched = false; - re = *it; - // do we affect this event? - if (e->type == re->catch_type && - (re->catch_win == None || - re->catch_win == orig_win)) { - matched = true; - // redirect? - if (re->redirect_win != None) { - e->xany.window = re->redirect_win; - } else { - drop_event = true; - } - } - - // does this event stop this redirect? - if (e->type == re->stop_type && - ((re->stop_win == None && matched) || - re->stop_win == orig_win)) { - RedirectEvents::iterator next_it = it; - ++next_it; - delete (*it); - m_redirect_events.erase(it); - it = next_it; - } else - ++it; - } - - // if one of the redirects says to drop it, we do - if (drop_event) + // to mask all events to go to it + if ((m_masked == e->xany.window) && m_masked_window) { + if (e->type == MotionNotify) { + m_last_time = e->xmotion.time; + m_masked_window->motionNotifyEvent(e->xmotion); return; + } else if (e->type == ButtonRelease) { + e->xbutton.window = m_masked_window->fbWindow().window(); + } + } - // update key/mouse screen and last time before we enter other eventhandlers if (e->type == KeyPress || e->type == KeyRelease) { @@ -1211,7 +1171,7 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { if (m_watching_screen && m_watch_keyrelease) { // mask the mod of the released key out // won't mask anything if it isn't a mod - ke.state &= ~FbTk::KeyUtil::keycodeToModmask(ke.keycode); + ke.state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); if ((m_watch_keyrelease & ke.state) == 0) { @@ -1628,6 +1588,7 @@ void Fluxbox::load_rc() { else // expand tilde *m_rc_stylefile = StringUtil::expandFilename(*m_rc_stylefile); + // expand tilde *m_rc_groupfile = StringUtil::expandFilename(*m_rc_groupfile); @@ -1934,35 +1895,15 @@ void Fluxbox::setFocusedWindow(WinClient *client) { * ignore_event means that it ignores the given event until * it gets a focusIn */ -void Fluxbox::revertFocus(BScreen &screen, bool wait_for_end) { +void Fluxbox::revertFocus(BScreen &screen) { // Relevant resources: // resource.focus_last = whether we focus last focused when changing workspace // BScreen::FocusModel = sloppy, click, whatever - if (wait_for_end) { - if (m_focus_revert_screen == 0) { - m_focus_revert_screen = &screen; - return; - } else if (m_focus_revert_screen == &screen) - return; - else - cerr<<"Unexpected screen in revertFocus()"<fbwindow() && - next_focus->fbwindow()->setCurrentClient(*next_focus, true, ignore_event))) { + next_focus->fbwindow()->setCurrentClient(*next_focus, true))) { setFocusedWindow(0); // so we don't get dangling m_focused_window pointer switch (screen.getFocusModel()) { case BScreen::SLOPPYFOCUS: @@ -1990,42 +1931,3 @@ void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { screen.rootWindow().window(), True, GrabModeAsync, GrabModeAsync, CurrentTime); } - -/** - * Allows people to create special event exclusions/redirects - * useful for getting around X followup events, or for - * effectively grabbing things - * The ignore is automatically removed when it finds the wakeup_win - * with an event matching the wakeup_mask - * ignore None means all windows - */ -void Fluxbox::addRedirectEvent(BScreen *screen, - long catch_type, Window catch_win, - long stop_type, Window stop_win, - Window redirect_win) { - RedirectEvent * re = new RedirectEvent(); - re->screen = screen; - re->catch_type = catch_type; - re->catch_win = catch_win; - re->stop_type = stop_type; - re->stop_win = stop_win; - re->redirect_win = redirect_win; - - m_redirect_events.push_back(re); -} - -// So that an object may remove the ignore on its own -// stop_type of None means remove all redirects for this window -void Fluxbox::removeRedirectEvent(long stop_type, Window stop_win) { - RedirectEvents::iterator it = m_redirect_events.begin(); - RedirectEvents::iterator it_end = m_redirect_events.end(); - RedirectEvent *re = 0; - for (; it != it_end; ++it) { - re = *it; - if (re->stop_win == stop_win && (stop_type == None || stop_type == re->stop_type)) { - m_redirect_events.erase(it); - delete re; - return; - } - } -} diff --git a/src/fluxbox.hh b/src/fluxbox.hh index 3056f4c..a02ece0 100644 --- a/src/fluxbox.hh +++ b/src/fluxbox.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.hh,v 1.79 2003/12/21 23:24:25 fluxgen Exp $ +// $Id: fluxbox.hh,v 1.80 2003/12/30 20:56:40 fluxgen Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH @@ -149,11 +149,13 @@ public: inline unsigned int getCacheLife() const { return *m_rc_cache_life * 60000; } inline unsigned int getCacheMax() const { return *m_rc_cache_max; } + inline void maskWindowEvents(Window w, FluxboxWindow *bw) + { m_masked = w; m_masked_window = bw; } + void watchKeyRelease(BScreen &screen, unsigned int mods); void setFocusedWindow(WinClient *w); - // focus revert gets delayed until the end of the event handle - void revertFocus(BScreen &screen, bool wait_for_end = true); + void revertFocus(BScreen &screen); void shutdown(); void load_rc(BScreen &scr); void loadRootCommand(BScreen &scr); @@ -202,21 +204,6 @@ public: // screen we are watching for modifier changes BScreen *watchingScreen() { return m_watching_screen; } const XEvent &lastEvent() const { return m_last_event; } - - /** - * Allows people to create special event exclusions/redirects - * useful for getting around X followup events, or for - * effectively grabbing things - * The ignore is automatically removed when it finds the stop_win - * with an event matching the stop_type - * ignore None means all windows - */ - void addRedirectEvent(BScreen *screen, long catch_type, Window catch_win, - long stop_type, Window stop_win, Window redirect_win); - - // So that an object may remove the ignore on its own - void removeRedirectEvent(long stop_type, Window stop_win); - private: typedef struct MenuTimestamp { @@ -259,7 +246,6 @@ private: FbTk::Resource m_rc_titlebar_left, m_rc_titlebar_right; FbTk::Resource m_rc_cache_life, m_rc_cache_max; FbTk::Resource m_rc_auto_raise_delay; - std::map m_window_search; std::map m_window_search_group; @@ -275,19 +261,8 @@ private: ScreenList m_screen_list; WinClient *m_focused_window; + FluxboxWindow *m_masked_window; - typedef struct RedirectEvent { - BScreen *screen; - long catch_type; - Window catch_win; - long stop_type; - Window stop_win; - Window redirect_win; - } RedirectEvent; - - typedef std::list RedirectEvents; - - RedirectEvents m_redirect_events; BScreen *m_mousescreen, *m_keyscreen; BScreen *m_watching_screen; unsigned int m_watch_keyrelease; @@ -296,6 +271,7 @@ private: bool m_reconfigure_wait, m_reread_menu_wait; Time m_last_time; + Window m_masked; std::string m_rc_file; ///< resource filename char **m_argv; int m_argc; @@ -320,9 +296,6 @@ private: const char *m_RC_PATH; const char *m_RC_INIT_FILE; Atom m_kwm1_dockwindow, m_kwm2_dockwindow; - - // each event can only affect one screen (right?) - BScreen *m_focus_revert_screen; }; -- cgit v0.11.2