From 1829dd5780c9cd818884cb84ae1ea51a4d4d35ca Mon Sep 17 00:00:00 2001 From: markt Date: Sat, 24 Mar 2007 16:31:13 +0000 Subject: colossal multi-patch, encompassing all of what I did yesterday without internet access --- ChangeLog | 12 +++++ src/Ewmh.cc | 19 ++++--- src/FbCommandFactory.cc | 8 ++- src/FbTk/TypeAhead.hh | 2 + src/FocusControl.cc | 117 ++++++++++++++++++++++++++++++++---------- src/FocusControl.hh | 31 ++++++++---- src/Focusable.hh | 42 +++++++++++++--- src/IconButton.cc | 131 ++---------------------------------------------- src/IconButton.hh | 13 +++-- src/IconbarTool.cc | 117 +++++++++++++++++++++++++++++++++++++++--- src/Makefile.am | 1 - src/Screen.cc | 14 ++++-- src/Screen.hh | 7 +-- src/WinClient.cc | 3 +- src/WinClient.hh | 9 +--- src/WinClientUtil.cc | 32 ------------ src/WinClientUtil.hh | 19 ------- src/Window.cc | 93 ++++++++++++++++++++-------------- src/Window.hh | 11 ++-- src/Workspace.cc | 2 +- src/WorkspaceCmd.cc | 31 ++++++++++-- src/WorkspaceCmd.hh | 9 ++++ 22 files changed, 412 insertions(+), 311 deletions(-) delete mode 100644 src/WinClientUtil.cc delete mode 100644 src/WinClientUtil.hh diff --git a/ChangeLog b/ChangeLog index 7c4354e..79b63cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ (Format: Year/Month/Day) Changes for 1.0rc3: +*07/03/24: + * Added new key command GoToWindow (Mark) + - Syntax is GoToWindow [], where the int gives the position + of the desired window with respect to a list of windows, and the bitmask + is the same as for NextWindow. A negative number for will count + back from the end of the list. + - Particularly useful examples are GoToWindow 9 and + GoToWindow 25, which will focus the window at position in the + iconbar modes Workspace and WorkspaceNoIcons, respectively. + * Fixed creation order window cycling with tabbed windows (Mark) + * Workspace Menu wasn't updating when windows changed titles (Mark) + * Some other minor changes/code cleanup (Mark) *07/03/21: * HideMenus didn't work on CustomMenus, and also fixed a memleak with CustomMenu (Mark + thanks Julien Trolet) diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 147b7d3..ea73807 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -28,7 +28,6 @@ #include "WinClient.hh" #include "Workspace.hh" #include "Layer.hh" -#include "WinClientUtil.hh" #include "fluxbox.hh" #include "FbWinFrameTheme.hh" #include "FocusControl.hh" @@ -383,7 +382,10 @@ void Ewmh::updateClientClose(WinClient &winclient){ void Ewmh::updateClientList(BScreen &screen) { - list creation_order_list = screen.focusControl().creationOrderList(); + if (screen.isShuttingdown()) + return; + + list creation_order_list = screen.focusControl().creationOrderList(); size_t num = creation_order_list.size(); Window *wl = FB_new_nothrow Window[num]; @@ -395,10 +397,13 @@ void Ewmh::updateClientList(BScreen &screen) { } int win=0; - list::iterator client_it = creation_order_list.begin(); - list::iterator client_it_end = creation_order_list.end(); - for (; client_it != client_it_end; ++client_it) - wl[win++] = (*client_it)->window(); + list::iterator client_it = creation_order_list.begin(); + list::iterator client_it_end = creation_order_list.end(); + for (; client_it != client_it_end; ++client_it) { + WinClient *client = dynamic_cast(*client_it); + if (client) + wl[win++] = client->window(); + } /* From Extended Window Manager Hints, draft 1.3: * @@ -1167,7 +1172,7 @@ void Ewmh::updateActions(FluxboxWindow &win) { actions.push_back(m_net_wm_action_minimize); unsigned int max_width, max_height; - WinClientUtil::maxSize(win.clientList(), max_width, max_height); + win.maxSize(max_width, max_height); // if unlimited max width we can maximize horizontal if (max_width == 0) { diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index bd20c39..378a2b8 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc @@ -78,6 +78,7 @@ FbCommandFactory::FbCommandFactory() { "focusleft", "focusright", "fullscreen", + "gotowindow", "hidemenus", "iconify", "keymode", @@ -422,7 +423,12 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, return new PrevWindowCmd(atoi(arguments.c_str())); else if (command == "typeaheadfocus") return new TypeAheadFocusCmd(atoi(arguments.c_str())); - else if (command == "focusup") + else if (command == "gotowindow") { + FbTk_istringstream is(arguments.c_str()); + int num = 0, options = 0; + is >> num >> options; + return new GoToWindowCmd(num, options); + } else if (command == "focusup") return new DirFocusCmd(FocusControl::FOCUSUP); else if (command == "focusdown") return new DirFocusCmd(FocusControl::FOCUSDOWN); diff --git a/src/FbTk/TypeAhead.hh b/src/FbTk/TypeAhead.hh index 15246b9..b28c803 100644 --- a/src/FbTk/TypeAhead.hh +++ b/src/FbTk/TypeAhead.hh @@ -103,6 +103,8 @@ public: if (!m_search_results.empty()) fillValues(m_search_results.back().result(), last_matched); + else + return *m_ref; return last_matched; } diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 2314f33..e653e22 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc @@ -60,18 +60,16 @@ FocusControl::FocusControl(BScreen &screen): m_was_iconic(false), m_cycling_last(0) { - m_cycling_window = m_focused_list.end(); + m_cycling_window = m_focused_win_list.end(); } // true if the windows should be skiped else false -bool doSkipWindow(const WinClient &winclient, int opts) { +bool doSkipWindow(const Focusable &winclient, int opts) { const FluxboxWindow *win = winclient.fbwindow(); return (!win || // skip if stuck (opts & FocusControl::CYCLESKIPSTUCK) != 0 && win->isStuck() || - // skip if not active client (i.e. only visit each fbwin once) - (opts & FocusControl::CYCLEGROUPS) != 0 && win->winClient().window() != winclient.window() || // skip if shaded (opts & FocusControl::CYCLESKIPSHADED) != 0 && win->isShaded() || // skip if iconic @@ -82,6 +80,15 @@ bool doSkipWindow(const WinClient &winclient, int opts) { } void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_reverse) { + Focusables tmp_list; + FocusedWindows::iterator it = window_list->begin(); + FocusedWindows::iterator it_end = window_list->end(); + for (; it != it_end; ++it) + tmp_list.push_back(*it); + cycleFocus(&tmp_list, opts, cycle_reverse); +} + +void FocusControl::cycleFocus(Focusables *window_list, int opts, bool cycle_reverse) { if (!m_cycling_list) { if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard()) @@ -92,12 +99,15 @@ void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_ } else if (m_cycling_list != window_list) m_cycling_list = window_list; + Focusables::iterator it_begin = window_list->begin(); + Focusables::iterator it_end = window_list->end(); + // too many things can go wrong with remembering this - m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); + m_cycling_window = find(it_begin, it_end, s_focused_window); + if (m_cycling_window == it_end) + m_cycling_window = find(it_begin, it_end, s_focused_fbwindow); - FocusedWindows::iterator it = m_cycling_window; - FocusedWindows::iterator it_begin = window_list->begin(); - FocusedWindows::iterator it_end = window_list->end(); + Focusables::iterator it = m_cycling_window; // find the next window in the list that works while (true) { @@ -121,7 +131,7 @@ void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_ // keep track of the originally selected window in a set WinClient &last_client = fbwin->winClient(); - if (! (doSkipWindow(**it, opts) || !fbwin->setCurrentClient(**it)) ) { + if (! (doSkipWindow(**it, opts) || !(*it)->focus()) ) { // moved onto a new fbwin if (!m_cycling_last || m_cycling_last->fbwindow() != fbwin) { if (m_cycling_last) { @@ -151,6 +161,38 @@ void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_ m_cycling_window = it; } +void FocusControl::goToWindowNumber(Focusables *winlist, int num, int options) { + if (num > 0 && winlist) { + Focusables::iterator it = winlist->begin(); + Focusables::iterator it_end = winlist->end(); + for (; it != it_end; ++it) { + if (!doSkipWindow(**it, options) && (*it)->acceptsFocus()) { + --num; + if (!num) { + if ((*it)->fbwindow() && (*it)->fbwindow()->isIconic()) + (*it)->fbwindow()->deiconify(); + (*it)->focus(); + return; + } + } + } + } else if (num < 0 && winlist) { + Focusables::reverse_iterator it = winlist->rbegin(); + Focusables::reverse_iterator it_end = winlist->rend(); + for (; it != it_end; ++it) { + if (!doSkipWindow(**it, options) && (*it)->acceptsFocus()) { + ++num; + if (!num) { + if ((*it)->fbwindow() && (*it)->fbwindow()->isIconic()) + (*it)->fbwindow()->deiconify(); + (*it)->focus(); + return; + } + } + } + } +} + void FocusControl::addFocusBack(WinClient &client) { m_focused_list.push_back(&client); m_creation_order_list.push_back(&client); @@ -161,6 +203,16 @@ void FocusControl::addFocusFront(WinClient &client) { m_creation_order_list.push_back(&client); } +void FocusControl::addFocusWinBack(Focusable &win) { + m_focused_win_list.push_back(&win); + m_creation_order_win_list.push_back(&win); +} + +void FocusControl::addFocusWinFront(Focusable &win) { + m_focused_win_list.push_front(&win); + m_creation_order_win_list.push_back(&win); +} + // move all clients in given window to back of focused list void FocusControl::setFocusBack(FluxboxWindow *fbwin) { // do nothing if there are no windows open @@ -168,9 +220,9 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { if (m_focused_list.empty() || s_reverting) return; - FocusedWindows::iterator it = m_focused_list.begin(); + Focusables::iterator it = m_focused_list.begin(); // use back to avoid an infinite loop - FocusedWindows::iterator it_back = --m_focused_list.end(); + Focusables::iterator it_back = --m_focused_list.end(); while (it != it_back) { if ((*it)->fbwindow() == fbwin) { @@ -184,6 +236,10 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { m_focused_list.push_back(*it); m_focused_list.erase(it); } + + m_focused_win_list.remove(fbwin); + m_focused_win_list.push_back(fbwin); + } void FocusControl::stopCyclingFocus() { @@ -191,7 +247,7 @@ void FocusControl::stopCyclingFocus() { if (m_cycling_list == 0) return; - FocusedWindows::iterator it_end = m_cycling_list->end(); + Focusables::iterator it_end = m_cycling_list->end(); m_cycling_last = 0; m_cycling_list = 0; @@ -200,10 +256,9 @@ void FocusControl::stopCyclingFocus() { // in which case we'll do a proper revert focus if (m_cycling_window != it_end && (*m_cycling_window)->fbwindow() && (*m_cycling_window)->fbwindow()->isVisible()) { - WinClient *client = *m_cycling_window; - m_focused_list.remove(client); - m_focused_list.push_front(client); - client->fbwindow()->raise(); + (*m_cycling_window)->fbwindow()->raise(); + if (s_focused_window) + setScreenFocusedWindow(*s_focused_window); } else revertFocus(m_screen); } @@ -213,13 +268,13 @@ void FocusControl::stopCyclingFocus() { * If workspace is outside the ID range, then the absolute last focused window * is given. */ -WinClient *FocusControl::lastFocusedWindow(int workspace) { +Focusable *FocusControl::lastFocusedWindow(int workspace) { if (m_focused_list.empty()) return 0; if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces()) return m_focused_list.front(); - FocusedWindows::iterator it = m_focused_list.begin(); - FocusedWindows::iterator it_end = m_focused_list.end(); + Focusables::iterator it = m_focused_win_list.begin(); + Focusables::iterator it_end = m_focused_win_list.end(); for (; it != it_end; ++it) { if ((*it)->fbwindow() && ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || @@ -238,12 +293,12 @@ WinClient *FocusControl::lastFocusedWindow(int workspace) { WinClient *FocusControl::lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client) { if (m_focused_list.empty()) return 0; - FocusedWindows::iterator it = m_focused_list.begin(); - FocusedWindows::iterator it_end = m_focused_list.end(); + Focusables::iterator it = m_focused_list.begin(); + Focusables::iterator it_end = m_focused_list.end(); for (; it != it_end; ++it) { if (((*it)->fbwindow() == &group) && (*it) != ignore_client) - return *it; + return dynamic_cast(*it); } return 0; } @@ -257,6 +312,8 @@ void FocusControl::setScreenFocusedWindow(WinClient &win_client) { !Fluxbox::instance()->isStartup()) { m_focused_list.remove(&win_client); m_focused_list.push_front(&win_client); + m_focused_win_list.remove(win_client.fbwindow()); + m_focused_win_list.push_front(win_client.fbwindow()); } } @@ -371,7 +428,7 @@ void FocusControl::removeClient(WinClient &client) { if (client.screen().isShuttingdown()) return; - WinClient *cyc = 0; + Focusable *cyc = 0; if (m_cycling_list && m_cycling_window != m_cycling_list->end()) cyc = *m_cycling_window; @@ -384,12 +441,18 @@ void FocusControl::removeClient(WinClient &client) { } } +void FocusControl::removeWindow(Focusable &win) { + m_focused_win_list.remove(&win); + m_creation_order_win_list.remove(&win); +} + void FocusControl::shutdown() { // restore windows backwards so they get put back correctly on restart - FocusedWindows::reverse_iterator it = m_focused_list.rbegin(); + Focusables::reverse_iterator it = m_focused_list.rbegin(); for (; it != m_focused_list.rend(); ++it) { - if (*it && (*it)->fbwindow()) - (*it)->fbwindow()->restore(*it, true); + WinClient *client = dynamic_cast(*it); + if (client && client->fbwindow()) + client->fbwindow()->restore(client, true); } } @@ -406,7 +469,7 @@ void FocusControl::revertFocus(BScreen &screen) { FocusControl::s_reverting = true; - WinClient *next_focus = + Focusable *next_focus = screen.focusControl().lastFocusedWindow(screen.currentWorkspaceID()); // if setting focus fails, or isn't possible, fallback correctly diff --git a/src/FocusControl.hh b/src/FocusControl.hh index ee66b9e..f7c40d9 100644 --- a/src/FocusControl.hh +++ b/src/FocusControl.hh @@ -30,6 +30,7 @@ class WinClient; class FluxboxWindow; +class Focusable; class BScreen; /** @@ -39,6 +40,7 @@ class BScreen; class FocusControl { public: typedef std::list FocusedWindows; + typedef std::list Focusables; enum FocusModel { MOUSEFOCUS = 0, ///< focus follows @@ -70,7 +72,9 @@ public: void prevFocus() { cycleFocus(&m_focused_list, 0, true); } void nextFocus() { cycleFocus(&m_focused_list, 0, false); } + void cycleFocus(Focusables *winlist, int options, bool reverse = false); void cycleFocus(FocusedWindows *winlist, int options, bool reverse = false); + void goToWindowNumber(Focusables *winlist, int num, int options); void setScreenFocusedWindow(WinClient &win_client); void setFocusModel(FocusModel model); @@ -84,19 +88,24 @@ public: bool isCycling() const { return m_cycling_list != 0; } void addFocusBack(WinClient &client); void addFocusFront(WinClient &client); + void addFocusWinBack(Focusable &win); + void addFocusWinFront(Focusable &win); void setFocusBack(FluxboxWindow *fbwin); FocusModel focusModel() const { return *m_focus_model; } TabFocusModel tabFocusModel() const { return *m_tab_focus_model; } bool focusNew() const { return *m_focus_new; } - WinClient *lastFocusedWindow(int workspace); - WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client); + Focusable *lastFocusedWindow(int workspace); + WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0); - FocusedWindows &creationOrderList() { return m_creation_order_list; } - FocusedWindows &focusedOrderList() { return m_focused_list; } + Focusables &creationOrderList() { return m_creation_order_list; } + Focusables &focusedOrderList() { return m_focused_list; } + Focusables &creationOrderWinList() { return m_creation_order_win_list; } + Focusables &focusedOrderWinList() { return m_focused_win_list; } void removeClient(WinClient &client); + void removeWindow(Focusable &win); void shutdown(); static void revertFocus(BScreen &screen); @@ -116,12 +125,14 @@ private: // This list keeps the order of window focusing for this screen // Screen global so it works for sticky windows too. - FocusedWindows m_focused_list; - FocusedWindows m_creation_order_list; - - FocusedWindows::iterator m_cycling_window; - FocusedWindows *m_cycling_list; - WinClient *m_was_iconic; + Focusables m_focused_list; + Focusables m_creation_order_list; + Focusables m_focused_win_list; + Focusables m_creation_order_win_list; + + Focusables::iterator m_cycling_window; + Focusables *m_cycling_list; + Focusable *m_was_iconic; WinClient *m_cycling_last; static WinClient *s_focused_window; diff --git a/src/Focusable.hh b/src/Focusable.hh index 21baffa..e2c7e50 100644 --- a/src/Focusable.hh +++ b/src/Focusable.hh @@ -23,19 +23,34 @@ #define FOCUSABLE_HH #include "FbTk/FbPixmap.hh" +#include "FbTk/ITypeAheadable.hh" +#include "FbTk/Subject.hh" #include +class BScreen; class FluxboxWindow; // base class for any object that might be "focused" -class Focusable { +class Focusable: public FbTk::ITypeAheadable { public: - Focusable(FluxboxWindow *fbwin = 0): m_fbwin(fbwin) { } + Focusable(BScreen &scr, FluxboxWindow *fbwin = 0): + m_screen(scr), m_fbwin(fbwin), + m_focused(false), m_titlesig(*this) { } virtual ~Focusable() { } virtual bool focus() { return false; } + virtual bool isFocused() const { return m_focused; } + virtual bool acceptsFocus() const { return true; } + + inline BScreen &screen() { return m_screen; } + inline const BScreen &screen() const { return m_screen; } + + // for accessing window properties, like shaded, minimized, etc. + inline const FluxboxWindow *fbwindow() const { return m_fbwin; } + inline FluxboxWindow *fbwindow() { return m_fbwin; } + // so we can make nice buttons, menu entries, etc. virtual const FbTk::FbPixmap &iconPixmap() const { return m_icon_pixmap; } virtual bool usePixmap() const { return iconPixmap().drawable() != None; } @@ -45,15 +60,30 @@ public: virtual const std::string &title() const { return m_title; } virtual const std::string &iconTitle() const { return m_icon_title; } + const std::string &iTypeString() const { return title(); } - // for accessing window properties, like shaded, minimized, etc. - inline const FluxboxWindow *fbwindow() const { return m_fbwin; } - inline FluxboxWindow *fbwindow() { return m_fbwin; } + class FocusSubject: public FbTk::Subject { + public: + FocusSubject(Focusable &w):m_win(w) { } + Focusable &win() { return m_win; } + const Focusable &win() const { return m_win; } + private: + Focusable &m_win; + }; + + // used for both title and icon changes + FbTk::Subject &titleSig() { return m_titlesig; } + const FbTk::Subject &titleSig() const { return m_titlesig; } protected: + BScreen &m_screen; + FluxboxWindow *m_fbwin; + + bool m_focused; std::string m_title, m_icon_title; FbTk::FbPixmap m_icon_pixmap, m_icon_mask; - FluxboxWindow *m_fbwin; + + FocusSubject m_titlesig; }; #endif // FOCUSABLE_HH diff --git a/src/IconButton.cc b/src/IconButton.cc index 545ee1d..8530c83 100644 --- a/src/IconButton.cc +++ b/src/IconButton.cc @@ -25,12 +25,8 @@ #include "IconButton.hh" #include "IconbarTool.hh" -#include "fluxbox.hh" #include "Screen.hh" -#include "Window.hh" -#include "WinClient.hh" -#include "CommandParser.hh" -#include "WindowCmd.hh" +#include "Focusable.hh" #include "FbTk/App.hh" #include "FbTk/SimpleCommand.hh" @@ -49,123 +45,15 @@ #include #endif // SHAPE -typedef FbTk::RefCount RefCmd; - -namespace { - -class ShowMenu: public FbTk::Command { -public: - explicit ShowMenu(FluxboxWindow &win):m_win(win) { } - void execute() { - // hide the menu if it's already showing for this FluxboxWindow - if (m_win.menu().isVisible() && WindowCmd::window() == &m_win) { - m_win.screen().hideMenus(); - return; - } - m_win.screen().hideMenus(); - // 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.showMenu(x, y); - } -private: - FluxboxWindow &m_win; -}; - -class FocusCommand: public FbTk::Command { -public: - explicit FocusCommand(const IconbarTool& tool, FluxboxWindow &win) : - m_win(win), m_tool(tool) { } - void execute() { - // this needs to be a local variable, as this object could be destroyed - // if the workspace is changed. - FluxboxWindow &win = m_win; - if(win.isIconic() || !win.isFocused()) { - switch(win.screen().getUserFollowModel()) { - case BScreen::SEMIFOLLOW_ACTIVE_WINDOW: - if (win.isIconic()) { - win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win); - } else { - win.screen().changeWorkspaceID(win.workspaceNumber()); - } - break; - case BScreen::FETCH_ACTIVE_WINDOW: - win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win); - break; - case BScreen::FOLLOW_ACTIVE_WINDOW: - if (!win.isStuck()) - win.screen().changeWorkspaceID(win.workspaceNumber()); - default: - break; - }; - win.raiseAndFocus(); - } else - win.iconify(); - } - -private: - FluxboxWindow &m_win; - const IconbarTool& m_tool; -}; - -// simple forwarding of wheeling, but only -// if desktopwheeling is enabled -class WheelWorkspaceCmd : public FbTk::Command { -public: - explicit WheelWorkspaceCmd(const IconbarTool& tool, FluxboxWindow &win, const char* cmd) : - m_win(win), m_cmd(CommandParser::instance().parseLine(cmd)), m_tool(tool) { } - void execute() { - - switch(m_tool.wheelMode()) { - case IconbarTool::ON: - m_cmd->execute(); - break; - case IconbarTool::SCREEN: - if(m_win.screen().isDesktopWheeling()) - m_cmd->execute(); - break; - case IconbarTool::OFF: - default: - break; - }; - } - -private: - FluxboxWindow &m_win; - RefCmd m_cmd; - const IconbarTool& m_tool; -}; -} // end anonymous namespace - - - -IconButton::IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent, - FbTk::Font &font, FluxboxWindow &win): - FbTk::TextButton(parent, font, win.winClient().title()), +IconButton::IconButton(const FbTk::FbWindow &parent, FbTk::Font &font, + Focusable &win): + FbTk::TextButton(parent, font, win.title()), m_win(win), m_icon_window(*this, 1, 1, 1, 1, ExposureMask | ButtonPressMask | ButtonReleaseMask), m_use_pixmap(true) { - - RefCmd next_workspace(new ::WheelWorkspaceCmd(tool, m_win, "nextworkspace")); - RefCmd prev_workspace(new ::WheelWorkspaceCmd(tool, m_win, "prevworkspace")); - - RefCmd focus_cmd(new ::FocusCommand(tool, m_win)); - RefCmd menu_cmd(new ::ShowMenu(m_win)); - setOnClick(focus_cmd, 1); - setOnClick(menu_cmd, 3); - if(win.screen().isReverseWheeling()) { - setOnClick(next_workspace, 5); - setOnClick(prev_workspace, 4); - } else { - setOnClick(next_workspace, 4); - setOnClick(prev_workspace, 5); - } - - m_win.hintSig().attach(this); m_win.titleSig().attach(this); FbTk::EventManager::instance()->add(*this, m_icon_window); @@ -227,10 +115,6 @@ void IconButton::update(FbTk::Subject *subj) { // icon pixmap was updated, // so we refresh everything - // we need to check our client first - if (m_win.clientList().empty()) - return; - Display *display = FbTk::App::instance()->display(); int screen = m_win.screen().screenNumber(); @@ -298,13 +182,8 @@ void IconButton::update(FbTk::Subject *subj) { } void IconButton::setupWindow() { - m_icon_window.clear(); - - if (!m_win.clientList().empty()) { - setText(m_win.winClient().title()); - // draw with x offset and y offset - } + setText(m_win.title()); FbTk::TextButton::clear(); } diff --git a/src/IconButton.hh b/src/IconButton.hh index b8a7ef0..54dae1d 100644 --- a/src/IconButton.hh +++ b/src/IconButton.hh @@ -29,13 +29,12 @@ #include "FbTk/Observer.hh" #include "FbTk/TextButton.hh" -class FluxboxWindow; -class IconbarTool; +class Focusable; class IconButton: public FbTk::TextButton, public FbTk::Observer { public: - IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent, - FbTk::Font &font, FluxboxWindow &window); + IconButton(const FbTk::FbWindow &parent, FbTk::Font &font, + Focusable &window); virtual ~IconButton(); void exposeEvent(XExposeEvent &event); @@ -50,8 +49,8 @@ public: void update(FbTk::Subject *subj); void setPixmap(bool use); - FluxboxWindow &win() { return m_win; } - const FluxboxWindow &win() const { return m_win; } + Focusable &win() { return m_win; } + const Focusable &win() const { return m_win; } bool setOrientation(FbTk::Orientation orient); @@ -60,7 +59,7 @@ protected: private: void setupWindow(); - FluxboxWindow &m_win; + Focusable &m_win; FbTk::FbWindow m_icon_window; FbTk::FbPixmap m_icon_pixmap; FbTk::FbPixmap m_icon_mask; diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index da9fb59..25b0cf8 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc @@ -24,6 +24,8 @@ #include "IconbarTool.hh" +#include "fluxbox.hh" +#include "WindowCmd.hh" #include "Screen.hh" #include "IconbarTheme.hh" #include "Window.hh" @@ -332,6 +334,92 @@ void removeDuplicate(const IconbarTool::IconList &iconlist, list RefCmd; + +class ShowMenu: public FbTk::Command { +public: + explicit ShowMenu(FluxboxWindow &win):m_win(win) { } + void execute() { + // hide the menu if it's already showing for this FluxboxWindow + if (m_win.menu().isVisible() && WindowCmd::window() == &m_win) { + m_win.screen().hideMenus(); + return; + } + m_win.screen().hideMenus(); + // 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.showMenu(x, y); + } +private: + FluxboxWindow &m_win; +}; + +class FocusCommand: public FbTk::Command { +public: + explicit FocusCommand(const IconbarTool& tool, FluxboxWindow &win) : + m_win(win), m_tool(tool) { } + void execute() { + // this needs to be a local variable, as this object could be destroyed + // if the workspace is changed. + FluxboxWindow &win = m_win; + if(win.isIconic() || !win.isFocused()) { + switch(win.screen().getUserFollowModel()) { + case BScreen::SEMIFOLLOW_ACTIVE_WINDOW: + if (win.isIconic()) { + win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win); + } else { + win.screen().changeWorkspaceID(win.workspaceNumber()); + } + break; + case BScreen::FETCH_ACTIVE_WINDOW: + win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win); + break; + case BScreen::FOLLOW_ACTIVE_WINDOW: + if (!win.isStuck()) + win.screen().changeWorkspaceID(win.workspaceNumber()); + default: + break; + }; + win.raiseAndFocus(); + } else + win.iconify(); + } + +private: + FluxboxWindow &m_win; + const IconbarTool& m_tool; +}; + +// simple forwarding of wheeling, but only +// if desktopwheeling is enabled +class WheelWorkspaceCmd : public FbTk::Command { +public: + explicit WheelWorkspaceCmd(const IconbarTool& tool, FluxboxWindow &win, const char* cmd) : + m_win(win), m_cmd(CommandParser::instance().parseLine(cmd)), m_tool(tool) { } + void execute() { + + switch(m_tool.wheelMode()) { + case IconbarTool::ON: + m_cmd->execute(); + break; + case IconbarTool::SCREEN: + if(m_win.screen().isDesktopWheeling()) + m_cmd->execute(); + break; + case IconbarTool::OFF: + default: + break; + }; + } + +private: + FluxboxWindow &m_win; + RefCmd m_cmd; + const IconbarTool& m_tool; +}; + }; // end anonymous namespace IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScreen &screen, @@ -779,8 +867,7 @@ void IconbarTool::removeWindow(FluxboxWindow &win) { win.dieSig().detach(this); win.workspaceSig().detach(this); win.stateSig().detach(this); - win.titleSig().detach(this); - + win.attentionSig().detach(this); // remove from list and render theme again IconButton *button = *it; @@ -799,12 +886,26 @@ void IconbarTool::addWindow(FluxboxWindow &win) { #ifdef DEBUG cerr<<"IconbarTool::addWindow(0x"<<&win<<" title = "<setOnClick(focus_cmd, 1); + button->setOnClick(menu_cmd, 3); + if(win.screen().isReverseWheeling()) { + button->setOnClick(next_workspace, 5); + button->setOnClick(prev_workspace, 4); + } else { + button->setOnClick(next_workspace, 4); + button->setOnClick(prev_workspace, 5); + } + renderButton(*button, false); // update the attributes, but don't clear it m_icon_container.insertItem(button); m_icon_list.push_back(button); @@ -818,10 +919,10 @@ void IconbarTool::addWindow(FluxboxWindow &win) { } void IconbarTool::updateList() { - list ordered_list = - m_screen.focusControl().creationOrderList(); - list::iterator it = ordered_list.begin(); - list::iterator it_end = ordered_list.end(); + list ordered_list = + m_screen.focusControl().creationOrderWinList(); + list::iterator it = ordered_list.begin(); + list::iterator it_end = ordered_list.end(); for (; it != it_end; ++it) { if ((*it)->fbwindow() && checkAddWindow(mode(), *(*it)->fbwindow()) && !checkDuplicate(*(*it)->fbwindow())) diff --git a/src/Makefile.am b/src/Makefile.am index 5b74800..a353b52 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -136,7 +136,6 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ RowSmartPlacement.hh RowSmartPlacement.cc \ ScreenPlacement.hh ScreenPlacement.cc \ UnderMousePlacement.hh UnderMousePlacement.cc \ - WinClientUtil.hh WinClientUtil.cc \ AttentionNoticeHandler.hh AttentionNoticeHandler.cc \ STLUtil.hh \ ${newwmspec_SOURCE} ${gnome_SOURCE} \ diff --git a/src/Screen.cc b/src/Screen.cc index 4bcc988..fca932d 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -853,8 +853,9 @@ void BScreen::notifyUngrabKeyboard() { focusControl().stopCyclingFocus(); } -void BScreen::startTypeAheadFocus(std::list &winlist, int opts) { +void BScreen::startTypeAheadFocus(std::list &winlist, int opts) { m_type_ahead.init(winlist); + m_matches = winlist; FbTk::EventManager *evm = FbTk::EventManager::instance(); if (!m_typing_ahead && !m_cycling) evm->grabKeyboard(*this, rootWindow().window()); @@ -879,12 +880,19 @@ void BScreen::cycleFocus(int options, bool reverse) { if (mods == 0) // can't stacked cycle unless there is a mod to grab options |= FocusControl::CYCLELINEAR; - FocusControl::FocusedWindows *win_list = - (options & FocusControl::CYCLELINEAR) ? + FocusControl::Focusables *win_list = 0; + if (options & FocusControl::CYCLEGROUPS) { + win_list = (options & FocusControl::CYCLELINEAR) ? + &focusControl().creationOrderWinList() : + &focusControl().focusedOrderWinList(); + } else { + win_list = (options & FocusControl::CYCLELINEAR) ? &focusControl().creationOrderList() : &focusControl().focusedOrderList(); + } focusControl().cycleFocus(win_list, options, reverse); + } FbTk::Menu *BScreen::createMenu(const string &label) { diff --git a/src/Screen.hh b/src/Screen.hh index c2e493b..352a015 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -55,6 +55,7 @@ #include #include +class Focusable; class FluxboxWindow; class Netizen; class FbWinFrameTheme; @@ -217,7 +218,7 @@ public: void buttonPressEvent(XButtonEvent &be); void notifyUngrabKeyboard(); - void startTypeAheadFocus(std::list &winlist, int opts); + void startTypeAheadFocus(std::list &winlist, int opts); void cycleFocus(int opts, bool reverse); FbTk::Menu *createMenu(const std::string &label); @@ -488,8 +489,8 @@ private: bool m_cycling, m_typing_ahead; int m_cycle_opts; - FbTk::TypeAhead, WinClient *> m_type_ahead; - std::list m_matches; + FbTk::TypeAhead, Focusable *> m_type_ahead; + std::list m_matches; // Xinerama related private data bool m_xinerama_avail; diff --git a/src/WinClient.cc b/src/WinClient.cc index 83f2af3..6ede82c 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -58,7 +58,7 @@ using std::dec; WinClient::TransientWaitMap WinClient::s_transient_wait; WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin): - Focusable(fbwin), FbTk::FbWindow(win), + Focusable(screen, fbwin), FbTk::FbWindow(win), transient_for(0), window_group(0), x(0), y(0), old_bw(0), @@ -82,7 +82,6 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin): m_mwm_hint(0), m_focus_mode(F_PASSIVE), m_diesig(*this), m_focussig(*this), - m_screen(screen), m_strut(0) { updateWMProtocols(); updateBlackboxHints(); diff --git a/src/WinClient.hh b/src/WinClient.hh index 7d2c734..671b7d4 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -29,7 +29,6 @@ #include "Subject.hh" #include "FbWindow.hh" #include "FbTk/FbString.hh" -#include "FbTk/ITypeAheadable.hh" #include @@ -37,8 +36,7 @@ class BScreen; class Strut; /// Holds client window info -class WinClient: public Focusable, public FbTk::ITypeAheadable, - public FbTk::FbWindow { +class WinClient: public Focusable, public FbTk::FbWindow { public: typedef std::list TransientList; // this structure only contains 3 elements... the Motif 2.0 structure contains @@ -117,8 +115,6 @@ public: /// @return class member of class structure const std::string &getWMClassClass() const; - BScreen &screen() { return m_screen; } - const BScreen &screen() const { return m_screen; } /// notifies when this client dies FbTk::Subject &dieSig() { return m_diesig; } /// notifies when this client becomes focused @@ -145,8 +141,6 @@ public: inline unsigned int maxWidth() const { return max_width; } inline unsigned int maxHeight() const { return max_height; } - const std::string &iTypeString() const { return m_title; } - static const int PropBlackboxHintsElements = 5; static const int PropMwmHintsElements = 3; @@ -200,7 +194,6 @@ private: WinClientSubj m_diesig; WinClientSubj m_focussig; - BScreen &m_screen; Strut *m_strut; // map transient_for X window to winclient transient diff --git a/src/WinClientUtil.cc b/src/WinClientUtil.cc deleted file mode 100644 index a6460a2..0000000 --- a/src/WinClientUtil.cc +++ /dev/null @@ -1,32 +0,0 @@ -#include "WinClientUtil.hh" -#include "WinClient.hh" - -#include - -namespace WinClientUtil { - -void maxSize(const FluxboxWindow::ClientList &clients, - unsigned int &max_width, unsigned int &max_height) { - FluxboxWindow::ClientList::const_iterator it = clients.begin(); - FluxboxWindow::ClientList::const_iterator it_end = clients.end(); - max_width = (unsigned int) ~0; // unlimited - max_height = (unsigned int) ~0; // unlimited - for (; it != it_end; ++it) { - // special case for max height/width == 0 - // 0 indicates unlimited size, so we skip them - // and set max size to 0 if max size == ~0 after the loop - if ((*it)->maxHeight() != 0) - max_height = std::min( (*it)->maxHeight(), max_height ); - if ((*it)->maxWidth() != 0) - max_width = std::min( (*it)->maxWidth(), max_width ); - } - - if (max_width == (unsigned int) ~0) - max_width = 0; - if (max_height == (unsigned int) ~0) - max_height = 0; -} - -} - - diff --git a/src/WinClientUtil.hh b/src/WinClientUtil.hh deleted file mode 100644 index 8ad0a03..0000000 --- a/src/WinClientUtil.hh +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef WINCLIENTUTIL_H -#define WINCLIENTUTIL_H - -#include "Window.hh" - -/// window client utilities -namespace WinClientUtil { - -/** - * Calculates the min of all maximum width/heights of all clients - * @param clients the client list - * @param width the return value of minimum of all max width of all clients - * @param height the return value of mimimum of all max heights of all clients - */ -void maxSize(const FluxboxWindow::ClientList &clients, - unsigned int &width, unsigned int &height); -} - -#endif // WINCLIENTUTIL_H diff --git a/src/Window.cc b/src/Window.cc index 1eb214a..ce14d08 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -239,7 +239,7 @@ int FluxboxWindow::s_num_grabs = 0; FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm, FbTk::XLayer &layer): - Focusable(this), + Focusable(client.screen(), this), oplock(false), m_hintsig(*this), m_statesig(*this), @@ -247,15 +247,12 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm, m_workspacesig(*this), m_diesig(*this), m_focussig(*this), - m_titlesig(*this), m_attentionsig(*this), m_themelistener(*this), - moving(false), resizing(false), shaded(false), - iconic(false), focused(false), + moving(false), resizing(false), shaded(false), iconic(false), stuck(false), m_initialized(false), fullscreen(false), maximized(MAX_NONE), m_attaching_tab(0), - m_screen(client.screen()), display(FbTk::App::instance()->display()), m_button_grab_x(0), m_button_grab_y(0), m_last_move_x(0), m_last_move_y(0), @@ -281,6 +278,17 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm, tm.reconfigSig().attach(&m_themelistener); init(); + + if (!isManaged()) + return; + + // add the window to the focus list + // always add to front on startup to keep the focus order the same + if (screen().focusControl().focusNew() || Fluxbox::instance()->isStartup()) + screen().focusControl().addFocusWinFront(*this); + else + screen().focusControl().addFocusWinBack(*this); + } @@ -330,7 +338,9 @@ FluxboxWindow::~FluxboxWindow() { } } - // deal with extra menus + if (!screen().isShuttingdown()) + screen().focusControl().removeWindow(*this); + #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<fbwindow() == this || (*it)->fbwindow() == old_win) - focused_win = *it; - } - } ClientList::iterator client_insert_pos = getClientInsertPosition(x, y); FbTk::TextButton *button_insert_pos = NULL; @@ -668,13 +668,11 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) { // and we don't seem to get a FocusIn event from setInputFocus setCurrentClient(client); FocusControl::setFocusedWindow(&client); - } else if (focused_win) - setCurrentClient(*focused_win, false); - else - // reparenting puts the new client on top, but the old client is keeping - // the focus, so we raise it - m_client->raise(); - + } else { + WinClient *last = screen().focusControl().lastFocusedWindow(*this); + if (last) + setCurrentClient(*last, false); + } frame().reconfigure(); } @@ -975,8 +973,6 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { if (client.fbwindow() != this) return false; - if (&client != m_client) - m_screen.focusControl().setScreenFocusedWindow(client); m_client = &client; m_client->raise(); m_client->focusSig().notify(); @@ -1063,7 +1059,7 @@ void FluxboxWindow::reconfigure() { applyDecorations(); - setFocusFlag(focused); + setFocusFlag(m_focused); moveResize(frame().x(), frame().y(), frame().width(), frame().height()); @@ -1272,7 +1268,7 @@ void FluxboxWindow::moveResize(int new_x, int new_y, } frame().moveResize(new_x, new_y, new_width, new_height); - setFocusFlag(focused); + setFocusFlag(m_focused); shaded = false; send_event = true; @@ -1299,7 +1295,7 @@ void FluxboxWindow::moveResizeForClient(int new_x, int new_y, if (!m_initialized) m_old_pos_x = 1; frame().moveResizeForClient(new_x, new_y, new_width, new_height, gravity, client_bw); - setFocusFlag(focused); + setFocusFlag(m_focused); shaded = false; sendConfigureNotify(); @@ -1312,8 +1308,26 @@ void FluxboxWindow::moveResizeForClient(int new_x, int new_y, } +void FluxboxWindow::maxSize(unsigned int &max_width, unsigned int &max_height) { + ClientList::const_iterator it = clientList().begin(); + ClientList::const_iterator it_end = clientList().end(); + max_width = (unsigned int) ~0; // unlimited + max_height = (unsigned int) ~0; // unlimited + for (; it != it_end; ++it) { + // special case for max height/width == 0 + // 0 indicates unlimited size, so we skip them + // and set max size to 0 if max size == ~0 after the loop + if ((*it)->maxHeight() != 0) + max_height = std::min( (*it)->maxHeight(), max_height ); + if ((*it)->maxWidth() != 0) + max_width = std::min( (*it)->maxWidth(), max_width ); + } - + if (max_width == (unsigned int) ~0) + max_width = 0; + if (max_height == (unsigned int) ~0) + max_height = 0; +} // returns whether the focus was "set" to this window // it doesn't guarantee that it has focus, but says that we have @@ -1976,7 +1990,7 @@ void FluxboxWindow::setIconHidden(bool value) { // so now we make it a focused frame etc void FluxboxWindow::setFocusFlag(bool focus) { bool was_focused = isFocused(); - focused = focus; + m_focused = focus; #ifdef DEBUG cerr<<"FluxboxWindow("<getModKey())) { - if (!focused) //check focus + if (!m_focused) //check focus focus(); if (frame().window().window() == be.window || frame().tabcontainer().window() == be.window) { @@ -3664,12 +3680,16 @@ FbTk::Menu &FluxboxWindow::menu() { return screen().windowMenu(); } +bool FluxboxWindow::acceptsFocus() const { + return (m_client ? m_client->acceptsFocus() : false); +} + const FbTk::FbPixmap &FluxboxWindow::iconPixmap() const { - return m_client->iconPixmap(); + return (m_client ? m_client->iconPixmap() : m_icon_pixmap); } const FbTk::FbPixmap &FluxboxWindow::iconMask() const { - return m_client->iconMask(); + return (m_client ? m_client->iconMask() : m_icon_mask); } const FbTk::Menu &FluxboxWindow::menu() const { @@ -4086,7 +4106,6 @@ void FluxboxWindow::updateButtons() { dir[i], frame().titlebar(), 0, 0, 10, 10); - hintSig().attach(winbtn); titleSig().attach(winbtn); winbtn->setOnClick(show_menu_cmd); break; diff --git a/src/Window.hh b/src/Window.hh index 726b747..9991bb6 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -263,6 +263,7 @@ public: void moveResize(int x, int y, unsigned int width, unsigned int height, bool send_event = false); /// move to pos x,y and resize client window to size width, height void moveResizeForClient(int x, int y, unsigned int width, unsigned int height, int gravity = ForgetGravity, unsigned int client_bw = 0); + void maxSize(unsigned int &width, unsigned int &height); void setWorkspace(int n); void changeBlackboxHints(const BlackboxHints &bh); void updateFunctions(); @@ -334,7 +335,6 @@ public: inline bool isFocusHidden() const { return m_focus_hidden; } inline bool isIconHidden() const { return m_icon_hidden; } inline bool isManaged() const { return m_initialized; } - inline bool isFocused() const { return focused; } bool isVisible() const; inline bool isIconic() { return iconic; } inline bool isIconic() const { return iconic; } @@ -361,9 +361,6 @@ public: inline WinClient &winClient() { return *m_client; } inline const WinClient &winClient() const { return *m_client; } - inline const BScreen &screen() const { return m_screen; } - inline BScreen &screen() { return m_screen; } - inline const FbTk::XLayerItem &layerItem() const { return m_frame.layerItem(); } inline FbTk::XLayerItem &layerItem() { return m_frame.layerItem(); } @@ -378,6 +375,7 @@ public: const FbTk::FbWindow &parent() const { return m_parent; } FbTk::FbWindow &parent() { return m_parent; } + bool acceptsFocus() const; const FbTk::FbPixmap &iconPixmap() const; const FbTk::FbPixmap &iconMask() const; const std::string &title() const; @@ -421,7 +419,6 @@ public: FbTk::Subject &dieSig() { return m_diesig; } const FbTk::Subject &dieSig() const { return m_diesig; } FbTk::Subject &focusSig() { return m_focussig; } - FbTk::Subject &titleSig() { return m_titlesig; } FbTk::Subject &attentionSig() { return m_attentionsig; } /** @} */ // end group signals @@ -493,7 +490,6 @@ private: m_layersig, m_workspacesig, m_diesig, m_focussig, - m_titlesig, m_attentionsig; class ThemeListener: public FbTk::Observer { @@ -509,14 +505,13 @@ private: // Window states bool moving, resizing, shaded, iconic, - focused, stuck, m_initialized, fullscreen; + stuck, m_initialized, fullscreen; int maximized; WinClient *m_attaching_tab; bool m_attention_state; - BScreen &m_screen; /// screen on which this window exist FbTk::Timer m_timer; Display *display; /// display connection BlackboxAttributes m_blackbox_attrib; diff --git a/src/Workspace.cc b/src/Workspace.cc index 4b367ac..66dd4a6 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -362,7 +362,7 @@ bool Workspace::loadGroups(const string &filename) { } void Workspace::update(FbTk::Subject *subj) { - menu().updateMenu(); + updateClientmenu(); } diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index f92418f..93ea830 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc @@ -54,19 +54,40 @@ void PrevWindowCmd::execute() { } void TypeAheadFocusCmd::execute() { - Fluxbox *fb = Fluxbox::instance(); - BScreen *screen = fb->keyScreen(); + BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen != 0) { - int options = m_option; - FocusControl::FocusedWindows *win_list = - (options & FocusControl::CYCLELINEAR) ? + FocusControl::Focusables *win_list = 0; + if (m_option & FocusControl::CYCLEGROUPS) { + win_list = (m_option & FocusControl::CYCLELINEAR) ? + &screen->focusControl().creationOrderWinList() : + &screen->focusControl().focusedOrderWinList(); + } else { + win_list = (m_option & FocusControl::CYCLELINEAR) ? &screen->focusControl().creationOrderList() : &screen->focusControl().focusedOrderList(); + } screen->startTypeAheadFocus(*win_list, m_option); } } +void GoToWindowCmd::execute() { + BScreen *screen = Fluxbox::instance()->keyScreen(); + if (screen != 0) { + FocusControl::Focusables *win_list = 0; + if (m_option & FocusControl::CYCLEGROUPS) { + win_list = (m_option & FocusControl::CYCLELINEAR) ? + &screen->focusControl().creationOrderWinList() : + &screen->focusControl().focusedOrderWinList(); + } else { + win_list = (m_option & FocusControl::CYCLELINEAR) ? + &screen->focusControl().creationOrderList() : + &screen->focusControl().focusedOrderList(); + } + screen->focusControl().goToWindowNumber(win_list, m_num, m_option); + } +} + void DirFocusCmd::execute() { BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen == 0) diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh index d0a6713..31ffb04 100644 --- a/src/WorkspaceCmd.hh +++ b/src/WorkspaceCmd.hh @@ -53,6 +53,15 @@ private: const int m_option; }; +class GoToWindowCmd: public FbTk::Command { +public: + GoToWindowCmd(int num, int option): m_num(num), m_option(option) { } + void execute(); +private: + const int m_num; + const int m_option; +}; + class DirFocusCmd: public FbTk::Command { public: explicit DirFocusCmd(const FocusControl::FocusDir dir): m_dir(dir) { } -- cgit v0.11.2