introduced workspacename for ClientPattern, and some miscellaneous cleanup
This commit is contained in:
parent
74eb584a31
commit
f3afe787c1
29 changed files with 164 additions and 239 deletions
|
@ -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:
|
||||
|
|
|
@ -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<FluxboxWindow *> &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);
|
||||
|
|
|
@ -34,8 +34,7 @@ class CascadePlacement: public PlacementStrategy,
|
|||
public:
|
||||
explicit CascadePlacement(const BScreen &screen);
|
||||
~CascadePlacement();
|
||||
bool placeWindow(const std::list<FluxboxWindow *> &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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
@ -355,6 +350,14 @@ string ClientPattern::getProperty(WinProperty prop,
|
|||
return (fbwin && fbwin->isIconHidden()) ? "yes" : "no";
|
||||
break;
|
||||
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());
|
||||
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
/**
|
||||
|
|
|
@ -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<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &win,
|
||||
bool ColSmartPlacement::placeWindow(const FluxboxWindow &win, int head,
|
||||
int &place_x, int &place_y) {
|
||||
|
||||
std::list<FluxboxWindow *> windowlist;
|
||||
const std::list<Focusable *> focusables =
|
||||
win.screen().focusControl().focusedOrderWinList();
|
||||
std::list<Focusable *>::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<FluxboxWindow *> &windowlist
|
|||
|
||||
bool placed = false;
|
||||
int next_x, next_y;
|
||||
const ScreenPlacement &screen_placement =
|
||||
dynamic_cast<const ScreenPlacement &>(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<FluxboxWindow *> &windowlist
|
|||
std::list<FluxboxWindow *>::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();
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
|
||||
class ColSmartPlacement: public PlacementStrategy {
|
||||
public:
|
||||
bool placeWindow(const std::list<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &win,
|
||||
bool placeWindow(const FluxboxWindow &win, int head,
|
||||
int &place_x, int &place_y);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<FluxboxWindow *>(*it));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<FluxboxWindow *> &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<FluxboxWindow *> windowlist;
|
||||
const std::list<Focusable *> focusables =
|
||||
win.screen().focusControl().focusedOrderWinList();
|
||||
std::list<Focusable *>::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<const ScreenPlacement &>(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<FluxboxWindow *>::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();
|
||||
|
|
|
@ -30,8 +30,7 @@ class MinOverlapPlacement: public PlacementStrategy {
|
|||
public:
|
||||
MinOverlapPlacement(ScreenPlacement::PlacementPolicy policy);
|
||||
|
||||
bool placeWindow(const std::list<FluxboxWindow *> &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
|
||||
|
|
|
@ -26,20 +26,19 @@
|
|||
|
||||
#include <list>
|
||||
|
||||
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<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &win,
|
||||
virtual bool placeWindow(const FluxboxWindow &win, int head,
|
||||
int &place_x, int &place_y) = 0;
|
||||
|
||||
virtual ~PlacementStrategy() { }
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &win,
|
||||
bool RowSmartPlacement::placeWindow(const FluxboxWindow &win, int head,
|
||||
int &place_x, int &place_y) {
|
||||
|
||||
std::list<FluxboxWindow *> windowlist;
|
||||
const std::list<Focusable *> focusables =
|
||||
win.screen().focusControl().focusedOrderWinList();
|
||||
std::list<Focusable *>::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<const ScreenPlacement &>(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<FluxboxWindow *> &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();
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
|
||||
class RowSmartPlacement: public PlacementStrategy {
|
||||
public:
|
||||
bool placeWindow(const std::list<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &win,
|
||||
bool placeWindow(const FluxboxWindow &win, int head,
|
||||
int &place_x, int &place_y);
|
||||
};
|
||||
|
||||
|
|
|
@ -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<void>::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<void>::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<Focusable *> &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() :
|
||||
|
|
|
@ -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;
|
||||
|
@ -239,13 +237,6 @@ public:
|
|||
void buttonPressEvent(XButtonEvent &be);
|
||||
void notifyUngrabKeyboard();
|
||||
|
||||
/**
|
||||
* Prepares type a head focus
|
||||
* @param winlist a list of focusables
|
||||
* @param pat pattern to match windows with
|
||||
*/
|
||||
void startTypeAheadFocus(std::list<Focusable *> &winlist,
|
||||
const ClientPattern *pat = 0);
|
||||
/**
|
||||
* Cycles focus of windows
|
||||
* @param opts focus options
|
||||
|
@ -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<Window, WinClient *> Groupables;
|
||||
Groupables m_expecting_groups;
|
||||
|
||||
bool m_cycling, m_typing_ahead;
|
||||
bool m_cycling;
|
||||
const ClientPattern *m_cycle_opts;
|
||||
FbTk::TypeAhead<std::list<Focusable *>, Focusable *> m_type_ahead;
|
||||
std::list<Focusable *> m_matches;
|
||||
|
||||
// Xinerama related private data
|
||||
bool m_xinerama_avail;
|
||||
|
|
|
@ -58,8 +58,7 @@ ScreenPlacement::ScreenPlacement(BScreen &screen):
|
|||
{
|
||||
}
|
||||
|
||||
bool ScreenPlacement::placeWindow(const std::list<FluxboxWindow *> &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<FluxboxWindow *> &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<FluxboxWindow *> &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<FluxboxWindow *> &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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ public:
|
|||
virtual ~ScreenPlacement() {}
|
||||
/// placeWindow is guaranteed to succeed, ignore return value
|
||||
/// @return true
|
||||
bool placeWindow(const std::list<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &window,
|
||||
bool placeWindow(const FluxboxWindow &window, int head,
|
||||
int &place_x, int &place_y);
|
||||
|
||||
RowDirection rowDirection() const { return *m_row_direction; }
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
#include "Screen.hh"
|
||||
#include "Window.hh"
|
||||
|
||||
bool UnderMousePlacement::placeWindow(const std::list<FluxboxWindow *> &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<FluxboxWindow *> &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);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
|
||||
class UnderMousePlacement: public PlacementStrategy {
|
||||
public:
|
||||
bool placeWindow(const std::list<FluxboxWindow *> &windowlist,
|
||||
const FluxboxWindow &win,
|
||||
bool placeWindow(const FluxboxWindow &win, int head,
|
||||
int &place_x, int &place_y);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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() :
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue