From f3afe787c1209cf1357493924a4f7eb7864def54 Mon Sep 17 00:00:00 2001 From: markt Date: Wed, 24 Oct 2007 17:09:26 +0000 Subject: introduced workspacename for ClientPattern, and some miscellaneous cleanup --- ChangeLog | 3 +++ src/CascadePlacement.cc | 10 +++----- src/CascadePlacement.hh | 3 +-- src/ClientPattern.cc | 35 ++++++++++++++------------ src/ClientPattern.hh | 10 +++----- src/ColSmartPlacement.cc | 23 +++++++++++++---- src/ColSmartPlacement.hh | 3 +-- src/FbCommandFactory.cc | 6 ----- src/FbCommands.cc | 6 ++--- src/FocusControl.cc | 22 ++++++++--------- src/FocusControl.hh | 16 ++++++------ src/MinOverlapPlacement.cc | 25 ++++++++++++++----- src/MinOverlapPlacement.hh | 4 +-- src/PlacementStrategy.hh | 7 +++--- src/Remember.cc | 7 +++--- src/RowSmartPlacement.cc | 23 +++++++++++++---- src/RowSmartPlacement.hh | 3 +-- src/Screen.cc | 61 +++++----------------------------------------- src/Screen.hh | 21 ++++------------ src/ScreenPlacement.cc | 12 +++------ src/ScreenPlacement.hh | 3 +-- src/UnderMousePlacement.cc | 4 +-- src/UnderMousePlacement.hh | 3 +-- src/Window.cc | 44 ++++++++++++++++++++------------- src/Window.hh | 1 + src/Workspace.cc | 16 +----------- src/Workspace.hh | 2 +- src/WorkspaceCmd.cc | 20 +-------------- src/WorkspaceCmd.hh | 10 -------- 29 files changed, 164 insertions(+), 239 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61183e5..d38cf12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ (Format: Year/Month/Day) Changes for 1.0.1: *07/10/24: + * Introduced (workspacename=...) for pattern matching and changed + (workspace=...) to use the workspace number, indexed from 0 (Mark) + ClientPattern.cc/hh * Reenabled raising window if window was moved by mouse by 0 pixels (Mathias) Window.cc *07/10/23: diff --git a/src/CascadePlacement.cc b/src/CascadePlacement.cc index bd20e66..10b23b0 100644 --- a/src/CascadePlacement.cc +++ b/src/CascadePlacement.cc @@ -27,14 +27,12 @@ #include "Screen.hh" CascadePlacement::CascadePlacement(const BScreen &screen) { - // +1 ? m_cascade_x = new int[screen.numHeads() + 1]; m_cascade_y = new int[screen.numHeads() + 1]; for (int i=0; i < screen.numHeads() + 1; i++) { - m_cascade_x[i] = 32 + screen.maxLeft(i); - m_cascade_y[i] = 32 + screen.maxTop(i); + m_cascade_x[i] = screen.maxRight(i); + m_cascade_y[i] = screen.maxBottom(i); } - } CascadePlacement::~CascadePlacement() { @@ -42,11 +40,9 @@ CascadePlacement::~CascadePlacement() { delete [] m_cascade_y; } -bool CascadePlacement::placeWindow(const std::list &windowlist, - const FluxboxWindow &win, +bool CascadePlacement::placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y) { - int head = (signed) win.getOnHead(); int head_left = (signed) win.screen().maxLeft(head); int head_right = (signed) win.screen().maxRight(head); int head_top = (signed) win.screen().maxTop(head); diff --git a/src/CascadePlacement.hh b/src/CascadePlacement.hh index 8fa39a0..ca11bab 100644 --- a/src/CascadePlacement.hh +++ b/src/CascadePlacement.hh @@ -34,8 +34,7 @@ class CascadePlacement: public PlacementStrategy, public: explicit CascadePlacement(const BScreen &screen); ~CascadePlacement(); - bool placeWindow(const std::list &windowlist, - const FluxboxWindow &window, + bool placeWindow(const FluxboxWindow &window, int head, int &place_x, int &place_y); private: int *m_cascade_x; ///< need a cascade for each head (Xinerama) diff --git a/src/ClientPattern.cc b/src/ClientPattern.cc index f8238dd..9ee1848 100644 --- a/src/ClientPattern.cc +++ b/src/ClientPattern.cc @@ -129,6 +129,8 @@ ClientPattern::ClientPattern(const char *str, bool default_no_transient): prop = ICONHIDDEN; } else if (strcasecmp(memstr.c_str(), "workspace") == 0) { prop = WORKSPACE; + } else if (strcasecmp(memstr.c_str(), "workspacename") == 0) { + prop = WORKSPACENAME; } else if (strcasecmp(memstr.c_str(), "head") == 0) { prop = HEAD; } else if (strcasecmp(memstr.c_str(), "layer") == 0) { @@ -236,6 +238,9 @@ string ClientPattern::toString() const { case WORKSPACE: pat.append("workspace="); break; + case WORKSPACENAME: + pat.append("workspacename="); + break; case HEAD: pat.append("head="); break; @@ -268,20 +273,11 @@ bool ClientPattern::match(const Focusable &win) const { Terms::const_iterator it_end = m_terms.end(); for (; it != it_end; ++it) { if ((*it)->orig == "[current]") { - // workspaces don't necessarily have unique names, so we want to - // compare numbers instead of strings - if ((*it)->prop == WORKSPACE && (!win.fbwindow() || - !((*it)->negate ^ - (win.fbwindow()->workspaceNumber() == - win.screen().currentWorkspaceID())))) + WinClient *focused = FocusControl::focusedWindow(); + if (!focused || !((*it)->negate ^ + (getProperty((*it)->prop, win) == + getProperty((*it)->prop, *focused)))) return false; - else { - WinClient *focused = FocusControl::focusedWindow(); - if (!focused || !((*it)->negate ^ - (getProperty((*it)->prop, win) == - getProperty((*it)->prop, *focused)))) - return false; - } } else if ((*it)->prop == HEAD && (*it)->orig == "[mouse]") { int mouse_head = win.screen().getCurrHead(); @@ -315,8 +311,7 @@ bool ClientPattern::addTerm(const string &str, WinProperty prop, bool negate) { return true; } -string ClientPattern::getProperty(WinProperty prop, - const Focusable &client) const { +string ClientPattern::getProperty(WinProperty prop, const Focusable &client) { // we need this for some of the window properties const FluxboxWindow *fbwin = client.fbwindow(); @@ -357,6 +352,14 @@ string ClientPattern::getProperty(WinProperty prop, case WORKSPACE: { if (!fbwin) return ""; + char tmpstr[128]; + sprintf(tmpstr, "%d", fbwin->workspaceNumber()); + return std::string(tmpstr); + break; + } + case WORKSPACENAME: { + if (!fbwin) + return ""; const Workspace *w = client.screen().getWorkspace(fbwin->workspaceNumber()); return w ? w->name() : ""; break; @@ -377,7 +380,7 @@ string ClientPattern::getProperty(WinProperty prop, return client.getWMClassName(); } -bool ClientPattern::equals(const ClientPattern &pat) const { +bool ClientPattern::operator ==(const ClientPattern &pat) const { // we require the terms to be identical (order too) Terms::const_iterator it = m_terms.begin(); Terms::const_iterator it_end = m_terms.end(); diff --git a/src/ClientPattern.hh b/src/ClientPattern.hh index 4e9f1ac..a6d1ede 100644 --- a/src/ClientPattern.hh +++ b/src/ClientPattern.hh @@ -56,7 +56,7 @@ public: enum WinProperty { TITLE, CLASS, NAME, ROLE, TRANSIENT, MAXIMIZED, MINIMIZED, SHADED, STUCK, FOCUSHIDDEN, ICONHIDDEN, - WORKSPACE, HEAD, LAYER + WORKSPACE, WORKSPACENAME, HEAD, LAYER }; /// Does this client match this pattern? @@ -72,12 +72,8 @@ public: inline void addMatch() { ++m_nummatches; } - inline bool operator == (const Focusable &win) const { - return match(win); - } - // whether this pattern has identical matching criteria - bool equals(const ClientPattern &pat) const; + bool operator ==(const ClientPattern &pat) const; /** * If there are no terms, then there is assumed to be an error @@ -85,7 +81,7 @@ public: */ inline int error() const { return m_terms.empty() ? 1 : 0; } - std::string getProperty(WinProperty prop, const Focusable &winclient) const; + static std::string getProperty(WinProperty prop, const Focusable &client); private: /** diff --git a/src/ColSmartPlacement.cc b/src/ColSmartPlacement.cc index 995a2f9..bdffa41 100644 --- a/src/ColSmartPlacement.cc +++ b/src/ColSmartPlacement.cc @@ -23,16 +23,29 @@ #include "ColSmartPlacement.hh" +#include "FocusControl.hh" #include "Screen.hh" #include "ScreenPlacement.hh" #include "Window.hh" -bool ColSmartPlacement::placeWindow(const std::list &windowlist, - const FluxboxWindow &win, +bool ColSmartPlacement::placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y) { + std::list windowlist; + const std::list focusables = + win.screen().focusControl().focusedOrderWinList(); + std::list::const_iterator foc_it = focusables.begin(), + foc_it_end = focusables.end(); + unsigned int workspace = win.workspaceNumber(); + for (; foc_it != foc_it_end; ++foc_it) { + // make sure it's a FluxboxWindow + if (*foc_it == (*foc_it)->fbwindow() && + (workspace == (*foc_it)->fbwindow()->workspaceNumber() || + (*foc_it)->fbwindow()->isStuck())) + windowlist.push_back((*foc_it)->fbwindow()); + } + // xinerama head constraints - int head = (signed) win.getOnHead(); int head_left = (signed) win.screen().maxLeft(head); int head_right = (signed) win.screen().maxRight(head); int head_top = (signed) win.screen().maxTop(head); @@ -40,8 +53,7 @@ bool ColSmartPlacement::placeWindow(const std::list &windowlist bool placed = false; int next_x, next_y; - const ScreenPlacement &screen_placement = - dynamic_cast(win.screen().placementStrategy()); + const ScreenPlacement &screen_placement = win.screen().placementStrategy(); bool top_bot = screen_placement.colDirection() == ScreenPlacement::TOPBOTTOM; bool left_right = screen_placement.rowDirection() == ScreenPlacement::LEFTRIGHT; @@ -90,6 +102,7 @@ bool ColSmartPlacement::placeWindow(const std::list &windowlist std::list::const_iterator it_end = windowlist.end(); for (; it != it_end && placed; ++it) { + if (*it == &win) continue; int curr_x = (*it)->x() - (*it)->xOffset(); int curr_y = (*it)->y() - (*it)->yOffset(); int curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2 + (*it)->widthOffset(); diff --git a/src/ColSmartPlacement.hh b/src/ColSmartPlacement.hh index f8c85cf..073e6c9 100644 --- a/src/ColSmartPlacement.hh +++ b/src/ColSmartPlacement.hh @@ -28,8 +28,7 @@ class ColSmartPlacement: public PlacementStrategy { public: - bool placeWindow(const std::list &windowlist, - const FluxboxWindow &win, + bool placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y); }; diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index be37403..d347878 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc @@ -176,7 +176,6 @@ FbCommandFactory::FbCommandFactory() { "taketoprevworkspace", "togglecmd", "toggledecor", - "typeaheadfocus", "windowmenu", "workspace", /* NOTE: The following are DEPRECATED and subject to removal */ @@ -547,11 +546,6 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, parseNextWindowArgs(arguments, opts, pat); opts |= FocusControl::CYCLEGROUPS; return new PrevWindowCmd(opts, pat); - } else if (command == "typeaheadfocus") { - int opts; - string pat; - parseNextWindowArgs(arguments, opts, pat); - return new TypeAheadFocusCmd(opts, pat); } else if (command == "gotowindow") { int num, opts; string args, pat; diff --git a/src/FbCommands.cc b/src/FbCommands.cc index 1d063e7..698f2db 100644 --- a/src/FbCommands.cc +++ b/src/FbCommands.cc @@ -277,7 +277,7 @@ void ShowClientMenuCmd::execute() { return; // TODO: ClientMenu only accepts lists of FluxboxWindows for now - FocusControl::Focusables *win_list = 0; + const FocusControl::Focusables *win_list = 0; // if (m_option & FocusControl::CYCLEGROUPS) { win_list = (m_option & FocusControl::CYCLELINEAR) ? &screen->focusControl().creationOrderWinList() : @@ -289,8 +289,8 @@ void ShowClientMenuCmd::execute() { } */ m_list.clear(); - FocusControl::Focusables::iterator it = win_list->begin(), - it_end = win_list->end(); + FocusControl::Focusables::const_iterator it = win_list->begin(), + it_end = win_list->end(); for (; it != it_end; ++it) { if (typeid(**it) == typeid(FluxboxWindow) && m_pat.match(**it)) m_list.push_back(static_cast(*it)); diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 6ccc9a1..2ab51eb 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc @@ -86,8 +86,8 @@ FocusControl::FocusControl(BScreen &screen): } -void FocusControl::cycleFocus(Focusables &window_list, const ClientPattern *pat, - bool cycle_reverse) { +void FocusControl::cycleFocus(const Focusables &window_list, + const ClientPattern *pat, bool cycle_reverse) { if (!m_cycling_list) { if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard()) @@ -98,15 +98,15 @@ void FocusControl::cycleFocus(Focusables &window_list, const ClientPattern *pat, } 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(); + Focusables::const_iterator it_begin = window_list.begin(); + Focusables::const_iterator it_end = window_list.end(); // too many things can go wrong with remembering this 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); - Focusables::iterator it = m_cycling_window; + Focusables::const_iterator it = m_cycling_window; FluxboxWindow *fbwin = 0; WinClient *last_client = 0; WinClient *was_iconic = 0; @@ -167,12 +167,12 @@ void FocusControl::cycleFocus(Focusables &window_list, const ClientPattern *pat, } -void FocusControl::goToWindowNumber(Focusables &winlist, int num, +void FocusControl::goToWindowNumber(const Focusables &winlist, int num, const ClientPattern *pat) { Focusable *last_matched = 0; if (num > 0) { - Focusables::iterator it = winlist.begin(); - Focusables::iterator it_end = winlist.end(); + Focusables::const_iterator it = winlist.begin(); + Focusables::const_iterator it_end = winlist.end(); for (; it != it_end; ++it) { if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { --num; @@ -181,8 +181,8 @@ void FocusControl::goToWindowNumber(Focusables &winlist, int num, } } } else if (num < 0) { - Focusables::reverse_iterator it = winlist.rbegin(); - Focusables::reverse_iterator it_end = winlist.rend(); + Focusables::const_reverse_iterator it = winlist.rbegin(); + Focusables::const_reverse_iterator it_end = winlist.rend(); for (; it != it_end; ++it) { if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { ++num; @@ -255,7 +255,7 @@ void FocusControl::stopCyclingFocus() { if (m_cycling_list == 0) return; - Focusables::iterator it_end = m_cycling_list->end(); + Focusables::const_iterator it_end = m_cycling_list->end(); m_cycling_last = 0; m_cycling_list = 0; diff --git a/src/FocusControl.hh b/src/FocusControl.hh index 0790110..4e2ceab 100644 --- a/src/FocusControl.hh +++ b/src/FocusControl.hh @@ -77,10 +77,10 @@ public: * @param pat pattern for matching focusables * @param reverse reverse the cycle order */ - void cycleFocus(Focusables &winlist, const ClientPattern *pat = 0, + void cycleFocus(const Focusables &winlist, const ClientPattern *pat = 0, bool reverse = false); - void goToWindowNumber(Focusables &winlist, int num, + void goToWindowNumber(const Focusables &winlist, int num, const ClientPattern *pat = 0); /// sets the focused window on a screen void setScreenFocusedWindow(WinClient &win_client); @@ -122,11 +122,11 @@ public: WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0); /// @return focus list in creation order - Focusables &creationOrderList() { return m_creation_order_list; } + const Focusables &creationOrderList() const { return m_creation_order_list; } /// @return the focus list in focused order - Focusables &focusedOrderList() { return m_focused_list; } - Focusables &creationOrderWinList() { return m_creation_order_win_list; } - Focusables &focusedOrderWinList() { return m_focused_win_list; } + const Focusables &focusedOrderList() const { return m_focused_list; } + const Focusables &creationOrderWinList() const { return m_creation_order_win_list; } + const Focusables &focusedOrderWinList() const { return m_focused_win_list; } /// remove client from focus list void removeClient(WinClient &client); @@ -158,8 +158,8 @@ private: Focusables m_focused_win_list; Focusables m_creation_order_win_list; - Focusables::iterator m_cycling_window; - Focusables *m_cycling_list; + Focusables::const_iterator m_cycling_window; + const Focusables *m_cycling_list; Focusable *m_was_iconic; WinClient *m_cycling_last; diff --git a/src/MinOverlapPlacement.cc b/src/MinOverlapPlacement.cc index 68301c6..510f66e 100644 --- a/src/MinOverlapPlacement.cc +++ b/src/MinOverlapPlacement.cc @@ -23,6 +23,7 @@ #include "MinOverlapPlacement.hh" +#include "FocusControl.hh" #include "Window.hh" #include "Screen.hh" @@ -34,19 +35,30 @@ MinOverlapPlacement::MinOverlapPlacement(ScreenPlacement::PlacementPolicy policy s_policy = policy; } -bool MinOverlapPlacement::placeWindow( - const std::list &windowlist, - const FluxboxWindow &win, int &place_x, int &place_y) { +bool MinOverlapPlacement::placeWindow(const FluxboxWindow &win, int head, + int &place_x, int &place_y) { + + std::list windowlist; + const std::list focusables = + win.screen().focusControl().focusedOrderWinList(); + std::list::const_iterator foc_it = focusables.begin(), + foc_it_end = focusables.end(); + unsigned int workspace = win.workspaceNumber(); + for (; foc_it != foc_it_end; ++foc_it) { + // make sure it's a FluxboxWindow + if (*foc_it == (*foc_it)->fbwindow() && + (workspace == (*foc_it)->fbwindow()->workspaceNumber() || + (*foc_it)->fbwindow()->isStuck())) + windowlist.push_back((*foc_it)->fbwindow()); + } // view (screen + head) constraints - int head = (signed) win.getOnHead(); int head_left = (signed) win.screen().maxLeft(head); int head_right = (signed) win.screen().maxRight(head); int head_top = (signed) win.screen().maxTop(head); int head_bot = (signed) win.screen().maxBottom(head); - const ScreenPlacement &screen_placement = - dynamic_cast(win.screen().placementStrategy()); + const ScreenPlacement &screen_placement = win.screen().placementStrategy(); s_row_dir = screen_placement.rowDirection(); s_col_dir = screen_placement.colDirection(); @@ -70,6 +82,7 @@ bool MinOverlapPlacement::placeWindow( std::list::const_reverse_iterator it = windowlist.rbegin(), it_end = windowlist.rend(); for (; it != it_end; ++it) { + if (*it == &win) continue; // get the dimensions of the window int left = (*it)->x() - (*it)->xOffset(); diff --git a/src/MinOverlapPlacement.hh b/src/MinOverlapPlacement.hh index 20b5c95..e818d4b 100644 --- a/src/MinOverlapPlacement.hh +++ b/src/MinOverlapPlacement.hh @@ -30,8 +30,7 @@ class MinOverlapPlacement: public PlacementStrategy { public: MinOverlapPlacement(ScreenPlacement::PlacementPolicy policy); - bool placeWindow(const std::list &windowlist, - const FluxboxWindow &win, + bool placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y); private: @@ -50,7 +49,6 @@ private: // do all STL set implementations use this for sorting? bool operator <(const Region &o) const { - // for now, I'm assuming RowSmartPlacement, so y is more important switch (MinOverlapPlacement::s_policy) { case ScreenPlacement::ROWMINOVERLAPPLACEMENT: // if we're making rows, y-value is most important diff --git a/src/PlacementStrategy.hh b/src/PlacementStrategy.hh index e8b0e96..5cd5c39 100644 --- a/src/PlacementStrategy.hh +++ b/src/PlacementStrategy.hh @@ -26,20 +26,19 @@ #include -class FluxboxWindow; +#include "Window.hh" struct PlacementStrategy { /** * Calculates a placement for @win and returns suggested placement in @place_x and @place_y - * @param windowlist the windows that are on the same workspace * @param win the window that needs to be placed * @param place_x x placement of specific strategy * @param place_y y placement of specific strategy * @return true if the strategy found a placement for the window */ - virtual bool placeWindow(const std::list &windowlist, - const FluxboxWindow &win, + virtual bool placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y) = 0; + virtual ~PlacementStrategy() { } }; diff --git a/src/Remember.cc b/src/Remember.cc index 41f91c4..a415c70 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -551,12 +551,13 @@ Application *Remember::findMatchingPatterns(ClientPattern *pat, Patterns *patlis Patterns::iterator it = patlist->begin(); Patterns::iterator it_end = patlist->end(); for (; it != it_end; ++it) { - if (it->first->equals(*pat) && is_group == it->second->is_grouped && + if (*it->first == *pat && is_group == it->second->is_grouped && ((match_pat == 0 && *it->second->group_pattern == 0) || - (match_pat && match_pat->equals(**it->second->group_pattern)))) { + (match_pat && *match_pat == **it->second->group_pattern))) { Application *ret = it->second; - // find any previous or subsequent matching ones and delete + if (!is_group) return ret; + // find the rest of the group and remove it from the list // rewind Patterns::iterator tmpit = it; diff --git a/src/RowSmartPlacement.cc b/src/RowSmartPlacement.cc index ec6078f..6457d59 100644 --- a/src/RowSmartPlacement.cc +++ b/src/RowSmartPlacement.cc @@ -23,26 +23,38 @@ #include "RowSmartPlacement.hh" +#include "FocusControl.hh" #include "Window.hh" #include "Screen.hh" #include "ScreenPlacement.hh" -bool RowSmartPlacement::placeWindow(const std::list &windowlist, - const FluxboxWindow &win, +bool RowSmartPlacement::placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y) { + std::list windowlist; + const std::list focusables = + win.screen().focusControl().focusedOrderWinList(); + std::list::const_iterator foc_it = focusables.begin(), + foc_it_end = focusables.end(); + unsigned int workspace = win.workspaceNumber(); + for (; foc_it != foc_it_end; ++foc_it) { + // make sure it's a FluxboxWindow + if (*foc_it == (*foc_it)->fbwindow() && + (workspace == (*foc_it)->fbwindow()->workspaceNumber() || + (*foc_it)->fbwindow()->isStuck())) + windowlist.push_back((*foc_it)->fbwindow()); + } + bool placed = false; int next_x, next_y; // view (screen + head) constraints - int head = (signed) win.getOnHead(); int head_left = (signed) win.screen().maxLeft(head); int head_right = (signed) win.screen().maxRight(head); int head_top = (signed) win.screen().maxTop(head); int head_bot = (signed) win.screen().maxBottom(head); - const ScreenPlacement &screen_placement = - dynamic_cast(win.screen().placementStrategy()); + const ScreenPlacement &screen_placement = win.screen().placementStrategy(); bool top_bot = screen_placement.colDirection() == ScreenPlacement::TOPBOTTOM; @@ -102,6 +114,7 @@ bool RowSmartPlacement::placeWindow(const std::list &windowlist for (; win_it != win_it_end && placed; ++win_it) { FluxboxWindow &window = **win_it; + if (&window == &win) continue; int curr_x = window.x() - window.xOffset(); // minus offset to get back up to fake place int curr_y = window.y() - window.yOffset(); diff --git a/src/RowSmartPlacement.hh b/src/RowSmartPlacement.hh index 7b54fc1..c6eec81 100644 --- a/src/RowSmartPlacement.hh +++ b/src/RowSmartPlacement.hh @@ -28,8 +28,7 @@ class RowSmartPlacement: public PlacementStrategy { public: - bool placeWindow(const std::list &windowlist, - const FluxboxWindow &win, + bool placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y); }; diff --git a/src/Screen.cc b/src/Screen.cc index 55517d8..541b30a 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -373,7 +373,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, m_altname(altscreenname), m_focus_control(new FocusControl(*this)), m_placement_strategy(new ScreenPlacement(*this)), - m_cycling(false), m_typing_ahead(false), m_cycle_opts(0), + m_cycling(false), m_cycle_opts(0), m_xinerama_headinfo(0), m_restart(false), m_shutdown(false) { @@ -826,45 +826,9 @@ void BScreen::propertyNotify(Atom atom) { } void BScreen::keyPressEvent(XKeyEvent &ke) { - if (!m_typing_ahead) { - WindowCmd::setWindow(FocusControl::focusedFbWindow()); - Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, - Keys::GLOBAL|Keys::ON_DESKTOP); - return; - } - - KeySym ks; - char keychar[1]; - XLookupString(&ke, keychar, 1, &ks, 0); - // a modifier key by itself doesn't do anything - if (IsModifierKey(ks)) - return; - - switch (ks) { - case XK_Escape: - case XK_KP_Enter: - case XK_Return: - m_type_ahead.reset(); - FbTk::EventManager::instance()->ungrabKeyboard(); - break; - case XK_BackSpace: - m_type_ahead.putBackSpace(); - m_matches = m_type_ahead.matched(); - break; - case XK_Tab: - case XK_ISO_Left_Tab: - m_type_ahead.seek(); - focusControl().cycleFocus(m_matches, m_cycle_opts, (bool)(ke.state & ShiftMask)); - break; - default: - m_matches = m_type_ahead.putCharacter(keychar[0]); - // if focused win doesn't match new search string, find the next one - if (!m_matches.empty() && - std::find(m_matches.begin(), m_matches.end(), - FocusControl::focusedWindow()) == m_matches.end()) - focusControl().cycleFocus(m_matches, m_cycle_opts); - break; - } + WindowCmd::setWindow(FocusControl::focusedFbWindow()); + Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, + Keys::GLOBAL|Keys::ON_DESKTOP); } void BScreen::keyReleaseEvent(XKeyEvent &ke) { @@ -889,22 +853,9 @@ void BScreen::buttonPressEvent(XButtonEvent &be) { void BScreen::notifyUngrabKeyboard() { m_cycling = false; - m_typing_ahead = false; - m_type_ahead.reset(); focusControl().stopCyclingFocus(); } -void BScreen::startTypeAheadFocus(std::list &winlist, - const ClientPattern *pat) { - 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()); - m_cycle_opts = pat; - m_typing_ahead = true; -} - void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { // get modifiers from event that causes this for focus order cycling XEvent ev = Fluxbox::instance()->lastEvent(); @@ -914,7 +865,7 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { else if (ev.type == ButtonPress) mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); - if (!m_cycling && !m_typing_ahead && mods) { + if (!m_cycling && mods) { m_cycling = true; FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window()); } @@ -922,7 +873,7 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { if (mods == 0) // can't stacked cycle unless there is a mod to grab options |= FocusControl::CYCLELINEAR; - FocusControl::Focusables *win_list = 0; + const FocusControl::Focusables *win_list = 0; if (options & FocusControl::CYCLEGROUPS) { win_list = (options & FocusControl::CYCLELINEAR) ? &focusControl().creationOrderWinList() : diff --git a/src/Screen.hh b/src/Screen.hh index 37edaa7..f5641e2 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -30,10 +30,8 @@ #include "FbWinFrame.hh" #include "FbRootWindow.hh" #include "MenuTheme.hh" -#include "PlacementStrategy.hh" #include "FbTk/EventHandler.hh" -#include "FbTk/TypeAhead.hh" #include "FbTk/Resource.hh" #include "FbTk/Subject.hh" #include "FbTk/MultLayers.hh" @@ -67,7 +65,7 @@ class Strut; class Slit; class HeadArea; class FocusControl; -class PlacementStrategy; +class ScreenPlacement; namespace FbTk { class Menu; @@ -240,13 +238,6 @@ public: void notifyUngrabKeyboard(); /** - * Prepares type a head focus - * @param winlist a list of focusables - * @param pat pattern to match windows with - */ - void startTypeAheadFocus(std::list &winlist, - const ClientPattern *pat = 0); - /** * Cycles focus of windows * @param opts focus options * @param pat specific pattern to match windows with @@ -313,8 +304,8 @@ public: bool isShuttingdown() const { return m_shutdown; } bool isRestart(); - PlacementStrategy &placementStrategy() { return *m_placement_strategy; } - const PlacementStrategy &placementStrategy() const { return *m_placement_strategy; } + ScreenPlacement &placementStrategy() { return *m_placement_strategy; } + const ScreenPlacement &placementStrategy() const { return *m_placement_strategy; } int addWorkspace(); int removeLastWorkspace(); @@ -579,17 +570,15 @@ private: const std::string m_name, m_altname; FocusControl *m_focus_control; - PlacementStrategy *m_placement_strategy; + ScreenPlacement *m_placement_strategy; // This is a map of windows to clients for clients that had a left // window set, but that window wasn't present at the time typedef std::map Groupables; Groupables m_expecting_groups; - bool m_cycling, m_typing_ahead; + bool m_cycling; const ClientPattern *m_cycle_opts; - FbTk::TypeAhead, Focusable *> m_type_ahead; - std::list m_matches; // Xinerama related private data bool m_xinerama_avail; diff --git a/src/ScreenPlacement.cc b/src/ScreenPlacement.cc index e8d1592..6d95860 100644 --- a/src/ScreenPlacement.cc +++ b/src/ScreenPlacement.cc @@ -58,8 +58,7 @@ ScreenPlacement::ScreenPlacement(BScreen &screen): { } -bool ScreenPlacement::placeWindow(const std::list &windowlist, - const FluxboxWindow &win, +bool ScreenPlacement::placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y) { @@ -88,7 +87,6 @@ bool ScreenPlacement::placeWindow(const std::list &windowlist, } // view (screen + head) constraints - int head = (signed) win.getOnHead(); int head_left = (signed) win.screen().maxLeft(head); int head_right = (signed) win.screen().maxRight(head); int head_top = (signed) win.screen().maxTop(head); @@ -100,9 +98,7 @@ bool ScreenPlacement::placeWindow(const std::list &windowlist, bool placed = false; try { - placed = m_strategy->placeWindow(windowlist, - win, - place_x, place_y); + placed = m_strategy->placeWindow(win, head, place_x, place_y); } catch (std::bad_cast cast) { // This should not happen. // If for some reason we change the PlacementStrategy in Screen @@ -117,9 +113,7 @@ bool ScreenPlacement::placeWindow(const std::list &windowlist, if (m_fallback_strategy.get() == 0) m_fallback_strategy.reset(new CascadePlacement(win.screen())); - m_fallback_strategy->placeWindow(windowlist, - win, - place_x, place_y); + m_fallback_strategy->placeWindow(win, head, place_x, place_y); } diff --git a/src/ScreenPlacement.hh b/src/ScreenPlacement.hh index 79d6c21..515691f 100644 --- a/src/ScreenPlacement.hh +++ b/src/ScreenPlacement.hh @@ -64,8 +64,7 @@ public: virtual ~ScreenPlacement() {} /// placeWindow is guaranteed to succeed, ignore return value /// @return true - bool placeWindow(const std::list &windowlist, - const FluxboxWindow &window, + bool placeWindow(const FluxboxWindow &window, int head, int &place_x, int &place_y); RowDirection rowDirection() const { return *m_row_direction; } diff --git a/src/UnderMousePlacement.cc b/src/UnderMousePlacement.cc index c20e988..65079cf 100644 --- a/src/UnderMousePlacement.cc +++ b/src/UnderMousePlacement.cc @@ -27,8 +27,7 @@ #include "Screen.hh" #include "Window.hh" -bool UnderMousePlacement::placeWindow(const std::list &list, - const FluxboxWindow &win, +bool UnderMousePlacement::placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y) { int root_x, root_y, ignore_i; @@ -51,7 +50,6 @@ bool UnderMousePlacement::placeWindow(const std::list &list, int test_y = root_y - (win_h / 2); // keep the window inside the screen - int head = (signed) win.getOnHead(); int head_left = (signed) win.screen().maxLeft(head); int head_right = (signed) win.screen().maxRight(head); int head_top = (signed) win.screen().maxTop(head); diff --git a/src/UnderMousePlacement.hh b/src/UnderMousePlacement.hh index 7f95e0c..aa7d844 100644 --- a/src/UnderMousePlacement.hh +++ b/src/UnderMousePlacement.hh @@ -28,8 +28,7 @@ class UnderMousePlacement: public PlacementStrategy { public: - bool placeWindow(const std::list &windowlist, - const FluxboxWindow &win, + bool placeWindow(const FluxboxWindow &win, int head, int &place_x, int &place_y); }; diff --git a/src/Window.cc b/src/Window.cc index fe3a43b..3452ce2 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -44,6 +44,7 @@ #include "FocusControl.hh" #include "Layer.hh" #include "IconButton.hh" +#include "ScreenPlacement.hh" #include "FbTk/Compose.hh" #include "FbTk/EventManager.hh" @@ -452,20 +453,6 @@ void FluxboxWindow::init() { wattrib.width, wattrib.height, m_client->gravity(), m_client->old_bw); - Fluxbox::instance()->attachSignals(*this); - - // this window is managed, we are now allowed to modify actual state - m_initialized = true; - - applyDecorations(true); - - grabButtons(); - - restoreAttributes(); - - if (m_workspace_number >= screen().numberOfWorkspaces()) - m_workspace_number = screen().currentWorkspaceID(); - if (fluxbox.isStartup()) m_placed = true; else if (m_client->isTransient() || @@ -480,9 +467,23 @@ void FluxboxWindow::init() { real_y <= (signed) screen().height()) m_placed = true; - } else if (!m_placed) { + } else setOnHead(screen().getCurrHead()); - } + + Fluxbox::instance()->attachSignals(*this); + + // this window is managed, we are now allowed to modify actual state + m_initialized = true; + + applyDecorations(true); + + grabButtons(); + + restoreAttributes(); + + if (m_workspace_number >= screen().numberOfWorkspaces()) + m_workspace_number = screen().currentWorkspaceID(); + /* if (wattrib.width <= 0) wattrib.width = 1; @@ -514,7 +515,8 @@ void FluxboxWindow::init() { if (m_placed) moveResize(frame().x(), frame().y(), real_width, real_height); - screen().getWorkspace(m_workspace_number)->addWindow(*this, !m_placed); + if (!m_placed) placeWindow(getOnHead()); + screen().getWorkspace(m_workspace_number)->addWindow(*this); setFocusFlag(false); // update graphics before mapping @@ -4120,3 +4122,11 @@ void FluxboxWindow::setOnHead(int head) { m_placed = placed; } } + +void FluxboxWindow::placeWindow(int head) { + int place_x, place_y; + // we ignore the return value, + // the screen placement strategy is guaranteed to succeed. + screen().placementStrategy().placeWindow(*this, head, place_x, place_y); + move(place_x, place_y); +} diff --git a/src/Window.hh b/src/Window.hh index b5c5dd2..4304037 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -309,6 +309,7 @@ public: int getOnHead() const; void setOnHead(int head); /// sets the window focus hidden state + void placeWindow(int head); void setFocusHidden(bool value); /// sets the window icon hidden state void setIconHidden(bool value); diff --git a/src/Workspace.cc b/src/Workspace.cc index cce8dfe..73ed077 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -85,16 +85,13 @@ Workspace::Workspace(BScreen &scrn, const string &name, unsigned int id): Workspace::~Workspace() { } -void Workspace::addWindow(FluxboxWindow &w, bool place) { +void Workspace::addWindow(FluxboxWindow &w) { // we don't need to add a window that already exist in our list if (find(m_windowlist.begin(), m_windowlist.end(), &w) != m_windowlist.end()) return; w.setWorkspace(m_id); - if (place) - placeWindow(w); - m_windowlist.push_back(&w); m_clientlist_sig.notify(); @@ -197,14 +194,3 @@ void Workspace::shutdown() { void Workspace::updateClientmenu() { m_clientlist_sig.notify(); } - -void Workspace::placeWindow(FluxboxWindow &win) { - int place_x, place_y; - // we ignore the return value, - // the screen placement strategy is guaranteed to succeed. - screen().placementStrategy().placeWindow(m_windowlist, - win, - place_x, place_y); - - win.moveResize(place_x, place_y, win.width(), win.height()); -} diff --git a/src/Workspace.hh b/src/Workspace.hh index 3f865ed..a834174 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -57,7 +57,7 @@ public: void shutdown(); /// Add @a win to this workspace, placing it if @a place is true - void addWindow(FluxboxWindow &win, bool place = false); + void addWindow(FluxboxWindow &win); int removeWindow(FluxboxWindow *win, bool still_alive); void updateClientmenu(); diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index e7d92ee..567d86e 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc @@ -92,28 +92,10 @@ void PrevWindowCmd::execute() { screen->cycleFocus(m_option, &m_pat, true); } -void TypeAheadFocusCmd::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->startTypeAheadFocus(*win_list, &m_pat); - } -} - void GoToWindowCmd::execute() { BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen != 0) { - FocusControl::Focusables *win_list = 0; + const FocusControl::Focusables *win_list = 0; if (m_option & FocusControl::CYCLEGROUPS) { win_list = (m_option & FocusControl::CYCLELINEAR) ? &screen->focusControl().creationOrderWinList() : diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh index 8053dc9..a530ae8 100644 --- a/src/WorkspaceCmd.hh +++ b/src/WorkspaceCmd.hh @@ -74,16 +74,6 @@ private: const ClientPattern m_pat; }; -class TypeAheadFocusCmd: public FbTk::Command { -public: - explicit TypeAheadFocusCmd(int option, std::string &pat): - m_option(option), m_pat(pat.c_str()) { } - void execute(); -private: - const int m_option; - const ClientPattern m_pat; -}; - class GoToWindowCmd: public FbTk::Command { public: GoToWindowCmd(int num, int option, std::string &pat): -- cgit v0.11.2