diff options
author | markt <markt> | 2007-11-12 21:59:43 (GMT) |
---|---|---|
committer | markt <markt> | 2007-11-12 21:59:43 (GMT) |
commit | 5d7043320da1378e7dd3b10f7e425f3b47455b28 (patch) | |
tree | 305db18a58ab6768b78ab230074da576d09e372d /src | |
parent | 807a1b557552e43dbdc169c1e7a3065a3f12aac7 (diff) | |
download | fluxbox-5d7043320da1378e7dd3b10f7e425f3b47455b28.zip fluxbox-5d7043320da1378e7dd3b10f7e425f3b47455b28.tar.bz2 |
allow arbitrary window patterns in iconbar
Diffstat (limited to 'src')
-rw-r--r-- | src/ClientPattern.cc | 36 | ||||
-rw-r--r-- | src/ClientPattern.hh | 6 | ||||
-rw-r--r-- | src/ColSmartPlacement.cc | 2 | ||||
-rw-r--r-- | src/Ewmh.cc | 3 | ||||
-rw-r--r-- | src/FbCommandFactory.cc | 39 | ||||
-rw-r--r-- | src/FbCommands.cc | 18 | ||||
-rw-r--r-- | src/FbCommands.hh | 3 | ||||
-rw-r--r-- | src/FbTk/Subject.cc | 24 | ||||
-rw-r--r-- | src/FocusControl.cc | 127 | ||||
-rw-r--r-- | src/FocusControl.hh | 31 | ||||
-rw-r--r-- | src/Focusable.hh | 2 | ||||
-rw-r--r-- | src/FocusableList.cc | 293 | ||||
-rw-r--r-- | src/FocusableList.hh | 121 | ||||
-rw-r--r-- | src/IconbarTool.cc | 315 | ||||
-rw-r--r-- | src/IconbarTool.hh | 38 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/MinOverlapPlacement.cc | 2 | ||||
-rw-r--r-- | src/RowSmartPlacement.cc | 2 | ||||
-rw-r--r-- | src/Screen.cc | 16 | ||||
-rw-r--r-- | src/Screen.hh | 3 | ||||
-rw-r--r-- | src/Window.cc | 6 | ||||
-rw-r--r-- | src/WorkspaceCmd.cc | 16 | ||||
-rw-r--r-- | src/fluxbox.cc | 28 | ||||
-rw-r--r-- | src/fluxbox.hh | 6 |
24 files changed, 687 insertions, 452 deletions
diff --git a/src/ClientPattern.cc b/src/ClientPattern.cc index 9ee1848..d094e63 100644 --- a/src/ClientPattern.cc +++ b/src/ClientPattern.cc | |||
@@ -274,9 +274,19 @@ bool ClientPattern::match(const Focusable &win) const { | |||
274 | for (; it != it_end; ++it) { | 274 | for (; it != it_end; ++it) { |
275 | if ((*it)->orig == "[current]") { | 275 | if ((*it)->orig == "[current]") { |
276 | WinClient *focused = FocusControl::focusedWindow(); | 276 | WinClient *focused = FocusControl::focusedWindow(); |
277 | if (!focused || !((*it)->negate ^ | 277 | if ((*it)->prop == WORKSPACE) { |
278 | (getProperty((*it)->prop, win) == | 278 | char tmpstr[128]; |
279 | getProperty((*it)->prop, *focused)))) | 279 | sprintf(tmpstr, "%d", win.screen().currentWorkspaceID()); |
280 | if (!(*it)->negate ^ (getProperty((*it)->prop, win) == tmpstr)) | ||
281 | return false; | ||
282 | } else if ((*it)->prop == WORKSPACENAME) { | ||
283 | const Workspace *w = win.screen().currentWorkspace(); | ||
284 | if (!w || (!(*it)->negate ^ | ||
285 | (getProperty((*it)->prop, win) == w->name()))) | ||
286 | return false; | ||
287 | } else if (!focused || (!(*it)->negate ^ | ||
288 | (getProperty((*it)->prop, win) == | ||
289 | getProperty((*it)->prop, *focused)))) | ||
280 | return false; | 290 | return false; |
281 | } else if ((*it)->prop == HEAD && | 291 | } else if ((*it)->prop == HEAD && |
282 | (*it)->orig == "[mouse]") { | 292 | (*it)->orig == "[mouse]") { |
@@ -293,6 +303,26 @@ bool ClientPattern::match(const Focusable &win) const { | |||
293 | return true; | 303 | return true; |
294 | } | 304 | } |
295 | 305 | ||
306 | bool ClientPattern::dependsOnFocusedWindow() const { | ||
307 | Terms::const_iterator it = m_terms.begin(), it_end = m_terms.end(); | ||
308 | for (; it != it_end; ++it) { | ||
309 | if ((*it)->prop != WORKSPACE && (*it)->prop != WORKSPACENAME && | ||
310 | (*it)->orig == "[current]") | ||
311 | return true; | ||
312 | } | ||
313 | return false; | ||
314 | } | ||
315 | |||
316 | bool ClientPattern::dependsOnCurrentWorkspace() const { | ||
317 | Terms::const_iterator it = m_terms.begin(), it_end = m_terms.end(); | ||
318 | for (; it != it_end; ++it) { | ||
319 | if (((*it)->prop == WORKSPACE || (*it)->prop == WORKSPACENAME) && | ||
320 | (*it)->orig == "[current]") | ||
321 | return true; | ||
322 | } | ||
323 | return false; | ||
324 | } | ||
325 | |||
296 | // add an expression to match against | 326 | // add an expression to match against |
297 | // The first argument is a regular expression, the second is the member | 327 | // The first argument is a regular expression, the second is the member |
298 | // function that we wish to match against. | 328 | // function that we wish to match against. |
diff --git a/src/ClientPattern.hh b/src/ClientPattern.hh index a6d1ede..b76aef8 100644 --- a/src/ClientPattern.hh +++ b/src/ClientPattern.hh | |||
@@ -62,6 +62,12 @@ public: | |||
62 | /// Does this client match this pattern? | 62 | /// Does this client match this pattern? |
63 | bool match(const Focusable &win) const; | 63 | bool match(const Focusable &win) const; |
64 | 64 | ||
65 | /// Does this pattern depend on the focused window? | ||
66 | bool dependsOnFocusedWindow() const; | ||
67 | |||
68 | /// Does this pattern depend on the current workspace? | ||
69 | bool dependsOnCurrentWorkspace() const; | ||
70 | |||
65 | /** | 71 | /** |
66 | * Add an expression to match against | 72 | * Add an expression to match against |
67 | * @param str is a regular expression | 73 | * @param str is a regular expression |
diff --git a/src/ColSmartPlacement.cc b/src/ColSmartPlacement.cc index bdffa41..0fbae68 100644 --- a/src/ColSmartPlacement.cc +++ b/src/ColSmartPlacement.cc | |||
@@ -33,7 +33,7 @@ bool ColSmartPlacement::placeWindow(const FluxboxWindow &win, int head, | |||
33 | 33 | ||
34 | std::list<FluxboxWindow *> windowlist; | 34 | std::list<FluxboxWindow *> windowlist; |
35 | const std::list<Focusable *> focusables = | 35 | const std::list<Focusable *> focusables = |
36 | win.screen().focusControl().focusedOrderWinList(); | 36 | win.screen().focusControl().focusedOrderWinList().clientList(); |
37 | std::list<Focusable *>::const_iterator foc_it = focusables.begin(), | 37 | std::list<Focusable *>::const_iterator foc_it = focusables.begin(), |
38 | foc_it_end = focusables.end(); | 38 | foc_it_end = focusables.end(); |
39 | unsigned int workspace = win.workspaceNumber(); | 39 | unsigned int workspace = win.workspaceNumber(); |
diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 3e01e36..ee98944 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc | |||
@@ -345,7 +345,8 @@ void Ewmh::updateClientList(BScreen &screen) { | |||
345 | if (screen.isShuttingdown()) | 345 | if (screen.isShuttingdown()) |
346 | return; | 346 | return; |
347 | 347 | ||
348 | list<Focusable *> creation_order_list = screen.focusControl().creationOrderList(); | 348 | list<Focusable *> creation_order_list = |
349 | screen.focusControl().creationOrderList().clientList(); | ||
349 | 350 | ||
350 | size_t num = creation_order_list.size(); | 351 | size_t num = creation_order_list.size(); |
351 | Window *wl = FB_new_nothrow Window[num]; | 352 | Window *wl = FB_new_nothrow Window[num]; |
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index d347878..72de740 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "FbCommandFactory.hh" | 25 | #include "FbCommandFactory.hh" |
26 | 26 | ||
27 | #include "FocusableList.hh" | ||
27 | #include "CurrentWindowCmd.hh" | 28 | #include "CurrentWindowCmd.hh" |
28 | #include "FbCommands.hh" | 29 | #include "FbCommands.hh" |
29 | #include "Window.hh" | 30 | #include "Window.hh" |
@@ -59,26 +60,6 @@ static int getint(const char *str, int defaultvalue) { | |||
59 | return defaultvalue; | 60 | return defaultvalue; |
60 | } | 61 | } |
61 | 62 | ||
62 | void parseNextWindowArgs(const string &in, int &opts, string &pat) { | ||
63 | string options; | ||
64 | int err = FbTk::StringUtil::getStringBetween(options, in.c_str(), '{', '}'); | ||
65 | |||
66 | // the rest of the string is a ClientPattern | ||
67 | pat = in.c_str() + err; | ||
68 | |||
69 | // now parse the options | ||
70 | vector<string> args; | ||
71 | FbTk::StringUtil::stringtok(args, options); | ||
72 | vector<string>::iterator it = args.begin(), it_end = args.end(); | ||
73 | opts = 0; | ||
74 | for (; it != it_end; ++it) { | ||
75 | if (strcasecmp((*it).c_str(), "static") == 0) | ||
76 | opts |= FocusControl::CYCLELINEAR; | ||
77 | else if (strcasecmp((*it).c_str(), "groups") == 0) | ||
78 | opts |= FocusControl::CYCLEGROUPS; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | }; // end anonymous namespace | 63 | }; // end anonymous namespace |
83 | 64 | ||
84 | FbCommandFactory::FbCommandFactory() { | 65 | FbCommandFactory::FbCommandFactory() { |
@@ -522,29 +503,29 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
522 | } else if (command == "attach") { | 503 | } else if (command == "attach") { |
523 | int opts; // not used | 504 | int opts; // not used |
524 | string pat; | 505 | string pat; |
525 | parseNextWindowArgs(arguments, opts, pat); | 506 | FocusableList::parseArgs(arguments, opts, pat); |
526 | return new AttachCmd(pat); | 507 | return new AttachCmd(pat); |
527 | } else if (command == "nextwindow") { | 508 | } else if (command == "nextwindow") { |
528 | int opts; | 509 | int opts; |
529 | string pat; | 510 | string pat; |
530 | parseNextWindowArgs(arguments, opts, pat); | 511 | FocusableList::parseArgs(arguments, opts, pat); |
531 | return new NextWindowCmd(opts, pat); | 512 | return new NextWindowCmd(opts, pat); |
532 | } else if (command == "nextgroup") { | 513 | } else if (command == "nextgroup") { |
533 | int opts; | 514 | int opts; |
534 | string pat; | 515 | string pat; |
535 | parseNextWindowArgs(arguments, opts, pat); | 516 | FocusableList::parseArgs(arguments, opts, pat); |
536 | opts |= FocusControl::CYCLEGROUPS; | 517 | opts |= FocusableList::LIST_GROUPS; |
537 | return new NextWindowCmd(opts, pat); | 518 | return new NextWindowCmd(opts, pat); |
538 | } else if (command == "prevwindow") { | 519 | } else if (command == "prevwindow") { |
539 | int opts; | 520 | int opts; |
540 | string pat; | 521 | string pat; |
541 | parseNextWindowArgs(arguments, opts, pat); | 522 | FocusableList::parseArgs(arguments, opts, pat); |
542 | return new PrevWindowCmd(opts, pat); | 523 | return new PrevWindowCmd(opts, pat); |
543 | } else if (command == "prevgroup") { | 524 | } else if (command == "prevgroup") { |
544 | int opts; | 525 | int opts; |
545 | string pat; | 526 | string pat; |
546 | parseNextWindowArgs(arguments, opts, pat); | 527 | FocusableList::parseArgs(arguments, opts, pat); |
547 | opts |= FocusControl::CYCLEGROUPS; | 528 | opts |= FocusableList::LIST_GROUPS; |
548 | return new PrevWindowCmd(opts, pat); | 529 | return new PrevWindowCmd(opts, pat); |
549 | } else if (command == "gotowindow") { | 530 | } else if (command == "gotowindow") { |
550 | int num, opts; | 531 | int num, opts; |
@@ -554,12 +535,12 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
554 | string::size_type pos = arguments.find_first_of("({"); | 535 | string::size_type pos = arguments.find_first_of("({"); |
555 | if (pos != string::npos && pos != arguments.size()) | 536 | if (pos != string::npos && pos != arguments.size()) |
556 | args = arguments.c_str() + pos; | 537 | args = arguments.c_str() + pos; |
557 | parseNextWindowArgs(args, opts, pat); | 538 | FocusableList::parseArgs(args, opts, pat); |
558 | return new GoToWindowCmd(num, opts, pat); | 539 | return new GoToWindowCmd(num, opts, pat); |
559 | } else if (command == "clientmenu") { | 540 | } else if (command == "clientmenu") { |
560 | int opts; | 541 | int opts; |
561 | string pat; | 542 | string pat; |
562 | parseNextWindowArgs(arguments, opts, pat); | 543 | FocusableList::parseArgs(arguments, opts, pat); |
563 | return new ShowClientMenuCmd(opts, pat); | 544 | return new ShowClientMenuCmd(opts, pat); |
564 | } else if (command == "focusup") | 545 | } else if (command == "focusup") |
565 | return new DirFocusCmd(FocusControl::FOCUSUP); | 546 | return new DirFocusCmd(FocusControl::FOCUSUP); |
diff --git a/src/FbCommands.cc b/src/FbCommands.cc index 698f2db..28c0a30 100644 --- a/src/FbCommands.cc +++ b/src/FbCommands.cc | |||
@@ -277,20 +277,12 @@ void ShowClientMenuCmd::execute() { | |||
277 | return; | 277 | return; |
278 | 278 | ||
279 | // TODO: ClientMenu only accepts lists of FluxboxWindows for now | 279 | // TODO: ClientMenu only accepts lists of FluxboxWindows for now |
280 | const FocusControl::Focusables *win_list = 0; | 280 | // when that's fixed, use a FocusableList for m_list |
281 | // if (m_option & FocusControl::CYCLEGROUPS) { | 281 | const FocusableList *list = |
282 | win_list = (m_option & FocusControl::CYCLELINEAR) ? | 282 | FocusableList::getListFromOptions(*screen, m_option); |
283 | &screen->focusControl().creationOrderWinList() : | ||
284 | &screen->focusControl().focusedOrderWinList(); | ||
285 | /* } else { | ||
286 | win_list = (m_option & FocusControl::CYCLELINEAR) ? | ||
287 | &screen->focusControl().creationOrderList() : | ||
288 | &screen->focusControl().focusedOrderList(); | ||
289 | } */ | ||
290 | |||
291 | m_list.clear(); | 283 | m_list.clear(); |
292 | FocusControl::Focusables::const_iterator it = win_list->begin(), | 284 | FocusControl::Focusables::const_iterator it = list->clientList().begin(), |
293 | it_end = win_list->end(); | 285 | it_end = list->clientList().end(); |
294 | for (; it != it_end; ++it) { | 286 | for (; it != it_end; ++it) { |
295 | if (typeid(**it) == typeid(FluxboxWindow) && m_pat.match(**it)) | 287 | if (typeid(**it) == typeid(FluxboxWindow) && m_pat.match(**it)) |
296 | m_list.push_back(static_cast<FluxboxWindow *>(*it)); | 288 | m_list.push_back(static_cast<FluxboxWindow *>(*it)); |
diff --git a/src/FbCommands.hh b/src/FbCommands.hh index c563899..c130050 100644 --- a/src/FbCommands.hh +++ b/src/FbCommands.hh | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "FbTk/RefCount.hh" | 31 | #include "FbTk/RefCount.hh" |
32 | #include "ClientMenu.hh" | 32 | #include "ClientMenu.hh" |
33 | #include "ClientPattern.hh" | 33 | #include "ClientPattern.hh" |
34 | #include "FocusableList.hh" | ||
34 | 35 | ||
35 | #include <list> | 36 | #include <list> |
36 | #include <string> | 37 | #include <string> |
@@ -118,7 +119,7 @@ public: | |||
118 | class ShowClientMenuCmd: public FbTk::Command { | 119 | class ShowClientMenuCmd: public FbTk::Command { |
119 | public: | 120 | public: |
120 | ShowClientMenuCmd(int option, std::string &pat): | 121 | ShowClientMenuCmd(int option, std::string &pat): |
121 | m_option(option), m_pat(pat.c_str()) { } | 122 | m_option(option|FocusableList::LIST_GROUPS), m_pat(pat.c_str()) { } |
122 | void execute(); | 123 | void execute(); |
123 | private: | 124 | private: |
124 | const int m_option; | 125 | const int m_option; |
diff --git a/src/FbTk/Subject.cc b/src/FbTk/Subject.cc index 08a211c..7ff80cf 100644 --- a/src/FbTk/Subject.cc +++ b/src/FbTk/Subject.cc | |||
@@ -58,16 +58,22 @@ void Subject::detach(Observer *obj) { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | void Subject::notify() { | 60 | void Subject::notify() { |
61 | m_notify_mode = true; | 61 | ObserverList::iterator it = m_observerlist.begin(), |
62 | std::for_each(m_observerlist.begin(), m_observerlist.end(), | 62 | it_end = m_observerlist.end(); |
63 | std::bind2nd(std::mem_fun(&Observer::update), this)); | 63 | for (; it != it_end; ++it) { |
64 | m_notify_mode = false; | 64 | m_notify_mode = true; |
65 | (*it)->update(this); | ||
66 | ObserverList::iterator d_it = m_dead_observers.begin(), | ||
67 | d_it_end = m_dead_observers.end(); | ||
68 | m_notify_mode = false; | ||
65 | 69 | ||
66 | // remove dead observers | 70 | // there might be dead observers later in the list, so we must remove |
67 | if (!m_dead_observers.empty()) { | 71 | // them now |
68 | std::for_each(m_dead_observers.begin(), | 72 | for (; d_it != d_it_end; ++d_it) { |
69 | m_dead_observers.end(), | 73 | if (*d_it == *it) |
70 | std::bind1st(std::mem_fun(&Subject::detach), this)); | 74 | --it; // don't invalidate our iterator |
75 | detach(*d_it); | ||
76 | } | ||
71 | m_dead_observers.clear(); | 77 | m_dead_observers.clear(); |
72 | } | 78 | } |
73 | } | 79 | } |
diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 7bc1db4..ae5b5e3 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc | |||
@@ -78,15 +78,17 @@ FocusControl::FocusControl(BScreen &screen): | |||
78 | m_focus_new(screen.resourceManager(), true, | 78 | m_focus_new(screen.resourceManager(), true, |
79 | screen.name()+".focusNewWindows", | 79 | screen.name()+".focusNewWindows", |
80 | screen.altName()+".FocusNewWindows"), | 80 | screen.altName()+".FocusNewWindows"), |
81 | m_focused_list(screen), m_creation_order_list(screen), | ||
82 | m_focused_win_list(screen), m_creation_order_win_list(screen), | ||
81 | m_cycling_list(0), | 83 | m_cycling_list(0), |
82 | m_was_iconic(false), | 84 | m_was_iconic(false), |
83 | m_cycling_last(0) { | 85 | m_cycling_last(0) { |
84 | 86 | ||
85 | m_cycling_window = m_focused_win_list.end(); | 87 | m_cycling_window = m_focused_list.clientList().end(); |
86 | 88 | ||
87 | } | 89 | } |
88 | 90 | ||
89 | void FocusControl::cycleFocus(const Focusables &window_list, | 91 | void FocusControl::cycleFocus(const FocusableList &window_list, |
90 | const ClientPattern *pat, bool cycle_reverse) { | 92 | const ClientPattern *pat, bool cycle_reverse) { |
91 | 93 | ||
92 | if (!m_cycling_list) { | 94 | if (!m_cycling_list) { |
@@ -98,8 +100,8 @@ void FocusControl::cycleFocus(const Focusables &window_list, | |||
98 | } else if (m_cycling_list != &window_list) | 100 | } else if (m_cycling_list != &window_list) |
99 | m_cycling_list = &window_list; | 101 | m_cycling_list = &window_list; |
100 | 102 | ||
101 | Focusables::const_iterator it_begin = window_list.begin(); | 103 | Focusables::const_iterator it_begin = window_list.clientList().begin(); |
102 | Focusables::const_iterator it_end = window_list.end(); | 104 | Focusables::const_iterator it_end = window_list.clientList().end(); |
103 | 105 | ||
104 | // too many things can go wrong with remembering this | 106 | // too many things can go wrong with remembering this |
105 | m_cycling_window = find(it_begin, it_end, s_focused_window); | 107 | m_cycling_window = find(it_begin, it_end, s_focused_window); |
@@ -165,10 +167,10 @@ void FocusControl::cycleFocus(const Focusables &window_list, | |||
165 | 167 | ||
166 | } | 168 | } |
167 | 169 | ||
168 | void FocusControl::goToWindowNumber(const Focusables &winlist, int num, | 170 | void FocusControl::goToWindowNumber(const FocusableList &winlist, int num, |
169 | const ClientPattern *pat) { | 171 | const ClientPattern *pat) { |
170 | Focusables::const_iterator it = winlist.begin(); | 172 | Focusables::const_iterator it = winlist.clientList().begin(); |
171 | Focusables::const_iterator it_end = winlist.end(); | 173 | Focusables::const_iterator it_end = winlist.clientList().end(); |
172 | for (; it != it_end && num; ++it) { | 174 | for (; it != it_end && num; ++it) { |
173 | if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { | 175 | if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { |
174 | num > 0 ? --num : ++num; | 176 | num > 0 ? --num : ++num; |
@@ -182,61 +184,43 @@ void FocusControl::goToWindowNumber(const Focusables &winlist, int num, | |||
182 | } | 184 | } |
183 | 185 | ||
184 | void FocusControl::addFocusBack(WinClient &client) { | 186 | void FocusControl::addFocusBack(WinClient &client) { |
185 | m_focused_list.push_back(&client); | 187 | m_focused_list.pushBack(client); |
186 | m_creation_order_list.push_back(&client); | 188 | m_creation_order_list.pushBack(client); |
187 | } | 189 | } |
188 | 190 | ||
189 | void FocusControl::addFocusFront(WinClient &client) { | 191 | void FocusControl::addFocusFront(WinClient &client) { |
190 | m_focused_list.push_front(&client); | 192 | m_focused_list.pushFront(client); |
191 | m_creation_order_list.push_back(&client); | 193 | m_creation_order_list.pushBack(client); |
192 | } | 194 | } |
193 | 195 | ||
194 | void FocusControl::addFocusWinBack(Focusable &win) { | 196 | void FocusControl::addFocusWinBack(Focusable &win) { |
195 | m_focused_win_list.push_back(&win); | 197 | m_focused_win_list.pushBack(win); |
196 | m_creation_order_win_list.push_back(&win); | 198 | m_creation_order_win_list.pushBack(win); |
197 | } | 199 | } |
198 | 200 | ||
199 | void FocusControl::addFocusWinFront(Focusable &win) { | 201 | void FocusControl::addFocusWinFront(Focusable &win) { |
200 | m_focused_win_list.push_front(&win); | 202 | m_focused_win_list.pushFront(win); |
201 | m_creation_order_win_list.push_back(&win); | 203 | m_creation_order_win_list.pushBack(win); |
202 | } | 204 | } |
203 | 205 | ||
204 | // move all clients in given window to back of focused list | 206 | // move all clients in given window to back of focused list |
205 | void FocusControl::setFocusBack(FluxboxWindow *fbwin) { | 207 | void FocusControl::setFocusBack(FluxboxWindow &fbwin) { |
206 | // do nothing if there are no windows open | 208 | // do nothing if there are no windows open |
207 | // don't change focus order while cycling | 209 | // don't change focus order while cycling |
208 | if (m_focused_list.empty() || s_reverting) | 210 | if (m_focused_list.empty() || s_reverting) |
209 | return; | 211 | return; |
210 | 212 | ||
211 | // if the window isn't already in this list, we could accidentally add it | 213 | m_focused_win_list.moveToBack(fbwin); |
212 | Focusables::iterator win_begin = m_focused_win_list.begin(), | ||
213 | win_end = m_focused_win_list.end(); | ||
214 | Focusables::iterator win_it = find(win_begin, win_end, fbwin); | ||
215 | if (win_it == win_end) | ||
216 | return; | ||
217 | |||
218 | m_focused_win_list.erase(win_it); | ||
219 | m_focused_win_list.push_back(fbwin); | ||
220 | 214 | ||
221 | Focusables::iterator it = m_focused_list.begin(); | 215 | // we need to move its clients to the back while preserving their order |
222 | // use back to avoid an infinite loop | 216 | Focusables list = m_focused_list.clientList(); |
223 | Focusables::iterator it_back = --m_focused_list.end(); | 217 | Focusables::iterator it = list.begin(), it_end = list.end(); |
224 | 218 | for (; it != it_end; ++it) { | |
225 | while (it != it_back) { | 219 | if ((*it)->fbwindow() == &fbwin) |
226 | if ((*it)->fbwindow() == fbwin) { | 220 | m_focused_list.moveToBack(**it); |
227 | m_focused_list.push_back(*it); | ||
228 | it = m_focused_list.erase(it); | ||
229 | } else | ||
230 | ++it; | ||
231 | } | ||
232 | // move the last one, if necessary, in order to preserve focus order | ||
233 | if ((*it)->fbwindow() == fbwin) { | ||
234 | m_focused_list.push_back(*it); | ||
235 | m_focused_list.erase(it); | ||
236 | } | 221 | } |
237 | |||
238 | } | 222 | } |
239 | 223 | ||
240 | void FocusControl::stopCyclingFocus() { | 224 | void FocusControl::stopCyclingFocus() { |
241 | // nothing to do | 225 | // nothing to do |
242 | if (m_cycling_list == 0) | 226 | if (m_cycling_list == 0) |
@@ -262,10 +246,10 @@ void FocusControl::stopCyclingFocus() { | |||
262 | Focusable *FocusControl::lastFocusedWindow(int workspace) { | 246 | Focusable *FocusControl::lastFocusedWindow(int workspace) { |
263 | if (m_focused_list.empty() || m_screen.isShuttingdown()) return 0; | 247 | if (m_focused_list.empty() || m_screen.isShuttingdown()) return 0; |
264 | if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces()) | 248 | if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces()) |
265 | return m_focused_list.front(); | 249 | return m_focused_list.clientList().front(); |
266 | 250 | ||
267 | Focusables::iterator it = m_focused_list.begin(); | 251 | Focusables::iterator it = m_focused_list.clientList().begin(); |
268 | Focusables::iterator it_end = m_focused_list.end(); | 252 | Focusables::iterator it_end = m_focused_list.clientList().end(); |
269 | for (; it != it_end; ++it) { | 253 | for (; it != it_end; ++it) { |
270 | if ((*it)->fbwindow() && | 254 | if ((*it)->fbwindow() && |
271 | ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || | 255 | ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || |
@@ -285,8 +269,8 @@ WinClient *FocusControl::lastFocusedWindow(FluxboxWindow &group, WinClient *igno | |||
285 | if (m_focused_list.empty() || m_screen.isShuttingdown()) | 269 | if (m_focused_list.empty() || m_screen.isShuttingdown()) |
286 | return 0; | 270 | return 0; |
287 | 271 | ||
288 | Focusables::iterator it = m_focused_list.begin(); | 272 | Focusables::iterator it = m_focused_list.clientList().begin(); |
289 | Focusables::iterator it_end = m_focused_list.end(); | 273 | Focusables::iterator it_end = m_focused_list.clientList().end(); |
290 | for (; it != it_end; ++it) { | 274 | for (; it != it_end; ++it) { |
291 | if (((*it)->fbwindow() == &group) && | 275 | if (((*it)->fbwindow() == &group) && |
292 | (*it) != ignore_client) | 276 | (*it) != ignore_client) |
@@ -300,27 +284,9 @@ void FocusControl::setScreenFocusedWindow(WinClient &win_client) { | |||
300 | // raise newly focused window to the top of the focused list | 284 | // raise newly focused window to the top of the focused list |
301 | // don't change the order if we're cycling or shutting down | 285 | // don't change the order if we're cycling or shutting down |
302 | if (!isCycling() && !m_screen.isShuttingdown() && !s_reverting) { | 286 | if (!isCycling() && !m_screen.isShuttingdown() && !s_reverting) { |
303 | 287 | m_focused_list.moveToFront(win_client); | |
304 | // make sure client is in our list, or else we could end up adding it | 288 | if (win_client.fbwindow()) |
305 | Focusables::iterator it_begin = m_focused_list.begin(), | 289 | m_focused_win_list.moveToFront(*win_client.fbwindow()); |
306 | it_end = m_focused_list.end(); | ||
307 | Focusables::iterator it = find(it_begin, it_end, &win_client); | ||
308 | if (it == it_end) | ||
309 | return; | ||
310 | |||
311 | m_focused_list.erase(it); | ||
312 | m_focused_list.push_front(&win_client); | ||
313 | |||
314 | // also check the fbwindow | ||
315 | it_begin = m_focused_win_list.begin(); | ||
316 | it_end = m_focused_win_list.end(); | ||
317 | it = find(it_begin, it_end, win_client.fbwindow()); | ||
318 | |||
319 | if (it != it_end) { | ||
320 | m_focused_win_list.erase(it); | ||
321 | m_focused_win_list.push_front(win_client.fbwindow()); | ||
322 | } | ||
323 | |||
324 | } | 290 | } |
325 | } | 291 | } |
326 | 292 | ||
@@ -435,15 +401,15 @@ void FocusControl::removeClient(WinClient &client) { | |||
435 | if (client.screen().isShuttingdown()) | 401 | if (client.screen().isShuttingdown()) |
436 | return; | 402 | return; |
437 | 403 | ||
438 | if (m_cycling_list && m_cycling_window != m_cycling_list->end() && | 404 | if (isCycling() && m_cycling_window != m_cycling_list->clientList().end() && |
439 | *m_cycling_window == &client) { | 405 | *m_cycling_window == &client) { |
440 | m_cycling_window = m_cycling_list->end(); | 406 | m_cycling_window = m_cycling_list->clientList().end(); |
441 | stopCyclingFocus(); | 407 | stopCyclingFocus(); |
442 | } else if (m_cycling_last == &client) | 408 | } else if (m_cycling_last == &client) |
443 | m_cycling_last = 0; | 409 | m_cycling_last = 0; |
444 | 410 | ||
445 | m_focused_list.remove(&client); | 411 | m_focused_list.remove(client); |
446 | m_creation_order_list.remove(&client); | 412 | m_creation_order_list.remove(client); |
447 | client.screen().clientListSig().notify(); | 413 | client.screen().clientListSig().notify(); |
448 | } | 414 | } |
449 | 415 | ||
@@ -451,21 +417,21 @@ void FocusControl::removeWindow(Focusable &win) { | |||
451 | if (win.screen().isShuttingdown()) | 417 | if (win.screen().isShuttingdown()) |
452 | return; | 418 | return; |
453 | 419 | ||
454 | if (m_cycling_list && m_cycling_window != m_cycling_list->end() && | 420 | if (isCycling() && m_cycling_window != m_cycling_list->clientList().end() && |
455 | *m_cycling_window == &win) { | 421 | *m_cycling_window == &win) { |
456 | m_cycling_window = m_cycling_list->end(); | 422 | m_cycling_window = m_cycling_list->clientList().end(); |
457 | stopCyclingFocus(); | 423 | stopCyclingFocus(); |
458 | } | 424 | } |
459 | 425 | ||
460 | m_focused_win_list.remove(&win); | 426 | m_focused_win_list.remove(win); |
461 | m_creation_order_win_list.remove(&win); | 427 | m_creation_order_win_list.remove(win); |
462 | win.screen().clientListSig().notify(); | 428 | win.screen().clientListSig().notify(); |
463 | } | 429 | } |
464 | 430 | ||
465 | void FocusControl::shutdown() { | 431 | void FocusControl::shutdown() { |
466 | // restore windows backwards so they get put back correctly on restart | 432 | // restore windows backwards so they get put back correctly on restart |
467 | Focusables::reverse_iterator it = m_focused_list.rbegin(); | 433 | Focusables::reverse_iterator it = m_focused_list.clientList().rbegin(); |
468 | for (; it != m_focused_list.rend(); ++it) { | 434 | for (; it != m_focused_list.clientList().rend(); ++it) { |
469 | WinClient *client = dynamic_cast<WinClient *>(*it); | 435 | WinClient *client = dynamic_cast<WinClient *>(*it); |
470 | if (client && client->fbwindow()) | 436 | if (client && client->fbwindow()) |
471 | client->fbwindow()->restore(client, true); | 437 | client->fbwindow()->restore(client, true); |
@@ -582,7 +548,10 @@ void FocusControl::setFocusedWindow(WinClient *client) { | |||
582 | } | 548 | } |
583 | 549 | ||
584 | // update AtomHandlers and/or other stuff... | 550 | // update AtomHandlers and/or other stuff... |
585 | Fluxbox::instance()->updateFocusedWindow(screen, old_screen); | 551 | if (screen) |
552 | screen->focusedWindowSig().notify(); | ||
553 | if (old_screen && screen != old_screen) | ||
554 | old_screen->focusedWindowSig().notify(); | ||
586 | } | 555 | } |
587 | 556 | ||
588 | ////////////////////// FocusControl RESOURCES | 557 | ////////////////////// FocusControl RESOURCES |
diff --git a/src/FocusControl.hh b/src/FocusControl.hh index 4e2ceab..84f0269 100644 --- a/src/FocusControl.hh +++ b/src/FocusControl.hh | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <list> | 27 | #include <list> |
28 | 28 | ||
29 | #include "FbTk/Resource.hh" | 29 | #include "FbTk/Resource.hh" |
30 | #include "FocusableList.hh" | ||
30 | 31 | ||
31 | class ClientPattern; | 32 | class ClientPattern; |
32 | class WinClient; | 33 | class WinClient; |
@@ -60,12 +61,6 @@ public: | |||
60 | FOCUSRIGHT ///< window is right | 61 | FOCUSRIGHT ///< window is right |
61 | }; | 62 | }; |
62 | 63 | ||
63 | /// prevFocus/nextFocus option bits | ||
64 | enum { | ||
65 | CYCLEGROUPS = 0x01, //< cycle through groups | ||
66 | CYCLELINEAR = 0x08, ///< linear cycle | ||
67 | }; | ||
68 | |||
69 | explicit FocusControl(BScreen &screen); | 64 | explicit FocusControl(BScreen &screen); |
70 | /// cycle previous focuable | 65 | /// cycle previous focuable |
71 | void prevFocus() { cycleFocus(m_focused_list, 0, true); } | 66 | void prevFocus() { cycleFocus(m_focused_list, 0, true); } |
@@ -77,10 +72,10 @@ public: | |||
77 | * @param pat pattern for matching focusables | 72 | * @param pat pattern for matching focusables |
78 | * @param reverse reverse the cycle order | 73 | * @param reverse reverse the cycle order |
79 | */ | 74 | */ |
80 | void cycleFocus(const Focusables &winlist, const ClientPattern *pat = 0, | 75 | void cycleFocus(const FocusableList &winlist, const ClientPattern *pat = 0, |
81 | bool reverse = false); | 76 | bool reverse = false); |
82 | 77 | ||
83 | void goToWindowNumber(const Focusables &winlist, int num, | 78 | void goToWindowNumber(const FocusableList &winlist, int num, |
84 | const ClientPattern *pat = 0); | 79 | const ClientPattern *pat = 0); |
85 | /// sets the focused window on a screen | 80 | /// sets the focused window on a screen |
86 | void setScreenFocusedWindow(WinClient &win_client); | 81 | void setScreenFocusedWindow(WinClient &win_client); |
@@ -108,7 +103,7 @@ public: | |||
108 | void addFocusFront(WinClient &client); | 103 | void addFocusFront(WinClient &client); |
109 | void addFocusWinBack(Focusable &win); | 104 | void addFocusWinBack(Focusable &win); |
110 | void addFocusWinFront(Focusable &win); | 105 | void addFocusWinFront(Focusable &win); |
111 | void setFocusBack(FluxboxWindow *fbwin); | 106 | void setFocusBack(FluxboxWindow &fbwin); |
112 | /// @return main focus model | 107 | /// @return main focus model |
113 | FocusModel focusModel() const { return *m_focus_model; } | 108 | FocusModel focusModel() const { return *m_focus_model; } |
114 | /// @return tab focus model | 109 | /// @return tab focus model |
@@ -122,11 +117,11 @@ public: | |||
122 | WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0); | 117 | WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0); |
123 | 118 | ||
124 | /// @return focus list in creation order | 119 | /// @return focus list in creation order |
125 | const Focusables &creationOrderList() const { return m_creation_order_list; } | 120 | const FocusableList &creationOrderList() const { return m_creation_order_list; } |
126 | /// @return the focus list in focused order | 121 | /// @return the focus list in focused order |
127 | const Focusables &focusedOrderList() const { return m_focused_list; } | 122 | const FocusableList &focusedOrderList() const { return m_focused_list; } |
128 | const Focusables &creationOrderWinList() const { return m_creation_order_win_list; } | 123 | const FocusableList &creationOrderWinList() const { return m_creation_order_win_list; } |
129 | const Focusables &focusedOrderWinList() const { return m_focused_win_list; } | 124 | const FocusableList &focusedOrderWinList() const { return m_focused_win_list; } |
130 | 125 | ||
131 | /// remove client from focus list | 126 | /// remove client from focus list |
132 | void removeClient(WinClient &client); | 127 | void removeClient(WinClient &client); |
@@ -153,13 +148,13 @@ private: | |||
153 | 148 | ||
154 | // This list keeps the order of window focusing for this screen | 149 | // This list keeps the order of window focusing for this screen |
155 | // Screen global so it works for sticky windows too. | 150 | // Screen global so it works for sticky windows too. |
156 | Focusables m_focused_list; | 151 | FocusableList m_focused_list; |
157 | Focusables m_creation_order_list; | 152 | FocusableList m_creation_order_list; |
158 | Focusables m_focused_win_list; | 153 | FocusableList m_focused_win_list; |
159 | Focusables m_creation_order_win_list; | 154 | FocusableList m_creation_order_win_list; |
160 | 155 | ||
161 | Focusables::const_iterator m_cycling_window; | 156 | Focusables::const_iterator m_cycling_window; |
162 | const Focusables *m_cycling_list; | 157 | const FocusableList *m_cycling_list; |
163 | Focusable *m_was_iconic; | 158 | Focusable *m_was_iconic; |
164 | WinClient *m_cycling_last; | 159 | WinClient *m_cycling_last; |
165 | 160 | ||
diff --git a/src/Focusable.hh b/src/Focusable.hh index 3903e25..5a2f40c 100644 --- a/src/Focusable.hh +++ b/src/Focusable.hh | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id$ | 22 | // $Id: $ |
23 | 23 | ||
24 | #ifndef FOCUSABLE_HH | 24 | #ifndef FOCUSABLE_HH |
25 | #define FOCUSABLE_HH | 25 | #define FOCUSABLE_HH |
diff --git a/src/FocusableList.cc b/src/FocusableList.cc new file mode 100644 index 0000000..8a5c8f7 --- /dev/null +++ b/src/FocusableList.cc | |||
@@ -0,0 +1,293 @@ | |||
1 | // FocusableList.cc | ||
2 | // Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id: $ | ||
23 | |||
24 | #include "FocusableList.hh" | ||
25 | |||
26 | #include "Focusable.hh" | ||
27 | #include "FocusControl.hh" | ||
28 | #include "Screen.hh" | ||
29 | #include "WinClient.hh" | ||
30 | #include "Window.hh" | ||
31 | |||
32 | #include "FbTk/StringUtil.hh" | ||
33 | |||
34 | #include <vector> | ||
35 | |||
36 | using std::string; | ||
37 | using std::vector; | ||
38 | |||
39 | void FocusableList::parseArgs(const string &in, int &opts, string &pat) { | ||
40 | string options; | ||
41 | int err = FbTk::StringUtil::getStringBetween(options, in.c_str(), '{', '}'); | ||
42 | |||
43 | // the rest of the string is a ClientPattern | ||
44 | pat = in.c_str() + err; | ||
45 | |||
46 | // now parse the options | ||
47 | vector<string> args; | ||
48 | FbTk::StringUtil::stringtok(args, options); | ||
49 | vector<string>::iterator it = args.begin(), it_end = args.end(); | ||
50 | opts = 0; | ||
51 | for (; it != it_end; ++it) { | ||
52 | if (strcasecmp((*it).c_str(), "static") == 0) | ||
53 | opts |= STATIC_ORDER; | ||
54 | else if (strcasecmp((*it).c_str(), "groups") == 0) | ||
55 | opts |= LIST_GROUPS; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | const FocusableList *FocusableList::getListFromOptions(BScreen &scr, int opts) { | ||
60 | if (opts & LIST_GROUPS) | ||
61 | return (opts & STATIC_ORDER) ? | ||
62 | &scr.focusControl().creationOrderWinList() : | ||
63 | &scr.focusControl().focusedOrderWinList(); | ||
64 | return (opts & STATIC_ORDER) ? | ||
65 | &scr.focusControl().creationOrderList() : | ||
66 | &scr.focusControl().focusedOrderList(); | ||
67 | } | ||
68 | |||
69 | FocusableList::FocusableList(BScreen &scr, const string pat): | ||
70 | m_pat(0), m_parent(0), m_screen(scr) { | ||
71 | |||
72 | int options = 0; | ||
73 | string pattern; | ||
74 | parseArgs(pat, options, pattern); | ||
75 | m_parent = getListFromOptions(scr, options); | ||
76 | m_pat.reset(new ClientPattern(pattern.c_str())); | ||
77 | |||
78 | init(); | ||
79 | } | ||
80 | |||
81 | FocusableList::FocusableList(BScreen &scr, const FocusableList &parent, | ||
82 | const string pat): | ||
83 | m_pat(new ClientPattern(pat.c_str())), m_parent(&parent), m_screen(scr) { | ||
84 | |||
85 | init(); | ||
86 | } | ||
87 | |||
88 | void FocusableList::init() { | ||
89 | addMatching(); | ||
90 | m_parent->attachChild(*this); | ||
91 | |||
92 | // TODO: can't handle (head=[mouse]) yet | ||
93 | if (m_pat->dependsOnCurrentWorkspace()) | ||
94 | m_screen.currentWorkspaceSig().attach(this); | ||
95 | if (m_pat->dependsOnFocusedWindow()) | ||
96 | m_screen.focusedWindowSig().attach(this); | ||
97 | } | ||
98 | |||
99 | void FocusableList::update(FbTk::Subject *subj) { | ||
100 | if (subj == 0 || m_screen.isShuttingdown()) | ||
101 | return; | ||
102 | |||
103 | if (typeid(*subj) == typeid(Focusable::FocusSubject)) { | ||
104 | Focusable::FocusSubject *fsubj = | ||
105 | static_cast<Focusable::FocusSubject *>(subj); | ||
106 | if (fsubj == &fsubj->win().dieSig()) | ||
107 | remove(fsubj->win()); | ||
108 | else if (fsubj == &fsubj->win().titleSig()) | ||
109 | checkUpdate(fsubj->win()); | ||
110 | } | ||
111 | if (typeid(*subj) == typeid(FluxboxWindow::WinSubject)) { | ||
112 | FluxboxWindow::WinSubject *fsubj = | ||
113 | static_cast<FluxboxWindow::WinSubject *>(subj); | ||
114 | // we only bind these for matching patterns, so skip finding out signal | ||
115 | FluxboxWindow &fbwin = fsubj->win(); | ||
116 | if (m_parent->contains(fbwin)) | ||
117 | checkUpdate(fbwin); | ||
118 | std::list<WinClient *> list = fbwin.clientList(); | ||
119 | std::list<WinClient *>::iterator it = list.begin(), it_end = list.end(); | ||
120 | for (; it != it_end; ++it) { | ||
121 | if (m_parent->contains(**it)) | ||
122 | checkUpdate(**it); | ||
123 | } | ||
124 | } | ||
125 | if (typeid(*subj) == typeid(FocusableListSubject)) { | ||
126 | FocusableListSubject *fsubj = | ||
127 | static_cast<FocusableListSubject *>(subj); | ||
128 | if (subj == &m_parent->addSig()) { | ||
129 | if (m_pat->match(*fsubj->win())) { | ||
130 | insertFromParent(*fsubj->win()); | ||
131 | m_addsig.notify(fsubj->win()); | ||
132 | } else // we still want to watch it, in case it changes to match | ||
133 | attachSignals(*fsubj->win()); | ||
134 | } else if (subj == &m_parent->removeSig()) | ||
135 | remove(*fsubj->win()); | ||
136 | else if (subj == &m_parent->resetSig()) | ||
137 | reset(); | ||
138 | else if (subj == &m_parent->orderSig()) { | ||
139 | Focusable *win = fsubj->win(); | ||
140 | if (!win || !contains(*win)) | ||
141 | return; | ||
142 | if (insertFromParent(*win)) | ||
143 | m_ordersig.notify(win); | ||
144 | } | ||
145 | } else if (subj == &m_screen.currentWorkspaceSig() || | ||
146 | subj == &m_screen.focusedWindowSig()) | ||
147 | reset(); | ||
148 | } | ||
149 | |||
150 | void FocusableList::checkUpdate(Focusable &win) { | ||
151 | if (contains(win)) { | ||
152 | if (!m_pat->match(win)) { | ||
153 | m_list.remove(&win); | ||
154 | m_removesig.notify(&win); | ||
155 | } | ||
156 | } else if (m_pat->match(win)) { | ||
157 | insertFromParent(win); | ||
158 | m_addsig.notify(&win); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | // returns whether or not the window was moved | ||
163 | bool FocusableList::insertFromParent(Focusable &win) { | ||
164 | const Focusables list = m_parent->clientList(); | ||
165 | Focusables::const_iterator p_it = list.begin(), p_it_end = list.end(); | ||
166 | Focusables::iterator our_it = m_list.begin(), our_it_end = m_list.end(); | ||
167 | // walk through our list looking for corresponding entries in | ||
168 | // parent's list, until we find the window that moved | ||
169 | for (; our_it != our_it_end && p_it != p_it_end; p_it++) { | ||
170 | if (*p_it == &win) { | ||
171 | if (*our_it == &win) // win didn't move in our list | ||
172 | return false; | ||
173 | m_list.remove(&win); | ||
174 | m_list.insert(our_it, &win); | ||
175 | return true; | ||
176 | } | ||
177 | if (*p_it == *our_it) | ||
178 | ++our_it; | ||
179 | } | ||
180 | m_list.remove(&win); | ||
181 | m_list.push_back(&win); | ||
182 | return true; | ||
183 | } | ||
184 | |||
185 | void FocusableList::addMatching() { | ||
186 | if (!m_parent) | ||
187 | return; | ||
188 | |||
189 | const Focusables list = m_parent->clientList(); | ||
190 | Focusables::const_iterator it = list.begin(), it_end = list.end(); | ||
191 | for (; it != it_end; ++it) { | ||
192 | if (m_pat->match(**it)) | ||
193 | pushBack(**it); | ||
194 | else // we still want to watch it, in case it changes to match | ||
195 | attachSignals(**it); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | void FocusableList::pushFront(Focusable &win) { | ||
200 | m_list.push_front(&win); | ||
201 | attachSignals(win); | ||
202 | m_addsig.notify(&win); | ||
203 | } | ||
204 | |||
205 | void FocusableList::pushBack(Focusable &win) { | ||
206 | m_list.push_back(&win); | ||
207 | attachSignals(win); | ||
208 | m_addsig.notify(&win); | ||
209 | } | ||
210 | |||
211 | void FocusableList::moveToFront(Focusable &win) { | ||
212 | // if the window isn't already in this list, we could accidentally add it | ||
213 | if (!contains(win)) | ||
214 | return; | ||
215 | |||
216 | m_list.remove(&win); | ||
217 | m_list.push_front(&win); | ||
218 | m_ordersig.notify(&win); | ||
219 | } | ||
220 | |||
221 | void FocusableList::moveToBack(Focusable &win) { | ||
222 | // if the window isn't already in this list, we could accidentally add it | ||
223 | if (!contains(win)) | ||
224 | return; | ||
225 | |||
226 | m_list.remove(&win); | ||
227 | m_list.push_back(&win); | ||
228 | m_ordersig.notify(&win); | ||
229 | } | ||
230 | |||
231 | void FocusableList::remove(Focusable &win) { | ||
232 | // if the window isn't already in this list, we could send a bad signal | ||
233 | bool contained = contains(win); | ||
234 | |||
235 | detachSignals(win); | ||
236 | if (!contained) | ||
237 | return; | ||
238 | m_list.remove(&win); | ||
239 | m_removesig.notify(&win); | ||
240 | } | ||
241 | |||
242 | void FocusableList::attachSignals(Focusable &win) { | ||
243 | win.dieSig().attach(this); | ||
244 | if (m_parent) { | ||
245 | // attach various signals for matching | ||
246 | win.titleSig().attach(this); | ||
247 | FluxboxWindow *fbwin = win.fbwindow(); | ||
248 | if (!fbwin) | ||
249 | return; | ||
250 | fbwin->workspaceSig().attach(this); | ||
251 | fbwin->stateSig().attach(this); | ||
252 | fbwin->layerSig().attach(this); | ||
253 | // TODO: can't watch (head=...) yet | ||
254 | } | ||
255 | } | ||
256 | |||
257 | void FocusableList::detachSignals(Focusable &win) { | ||
258 | win.dieSig().detach(this); | ||
259 | if (m_parent) { | ||
260 | // detach various signals for matching | ||
261 | win.titleSig().detach(this); | ||
262 | FluxboxWindow *fbwin = win.fbwindow(); | ||
263 | if (!fbwin) | ||
264 | return; | ||
265 | fbwin->workspaceSig().detach(this); | ||
266 | fbwin->stateSig().detach(this); | ||
267 | fbwin->layerSig().detach(this); | ||
268 | // TODO: can't watch (head=...) yet | ||
269 | } | ||
270 | } | ||
271 | |||
272 | void FocusableList::reset() { | ||
273 | while (!m_list.empty()) { | ||
274 | detachSignals(*m_list.back()); | ||
275 | m_list.pop_back(); | ||
276 | } | ||
277 | if (m_parent) | ||
278 | addMatching(); | ||
279 | m_resetsig.notify(0); | ||
280 | } | ||
281 | |||
282 | bool FocusableList::contains(const Focusable &win) const { | ||
283 | Focusables::const_iterator it = m_list.begin(), it_end = m_list.end(); | ||
284 | it = find(it, it_end, &win); | ||
285 | return (it != it_end); | ||
286 | } | ||
287 | |||
288 | void FocusableList::attachChild(FocusableList &child) const { | ||
289 | m_addsig.attach(&child); | ||
290 | m_removesig.attach(&child); | ||
291 | m_resetsig.attach(&child); | ||
292 | m_ordersig.attach(&child); | ||
293 | } | ||
diff --git a/src/FocusableList.hh b/src/FocusableList.hh new file mode 100644 index 0000000..7cca298 --- /dev/null +++ b/src/FocusableList.hh | |||
@@ -0,0 +1,121 @@ | |||
1 | // FocusableList.hh | ||
2 | // Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id: $ | ||
23 | |||
24 | #ifndef FOCUSABLELIST_HH | ||
25 | #define FOCUSABLELIST_HH | ||
26 | |||
27 | #include "FbTk/NotCopyable.hh" | ||
28 | #include "FbTk/Observer.hh" | ||
29 | #include "FbTk/Subject.hh" | ||
30 | |||
31 | #include "ClientPattern.hh" | ||
32 | |||
33 | #include <list> | ||
34 | #include <string> | ||
35 | |||
36 | class BScreen; | ||
37 | class Focusable; | ||
38 | |||
39 | class FocusableList: public FbTk::Observer, private FbTk::NotCopyable { | ||
40 | public: | ||
41 | typedef std::list<Focusable *> Focusables; | ||
42 | |||
43 | /// list option bits | ||
44 | enum { | ||
45 | LIST_GROUPS = 0x01, //< list groups instead of clients | ||
46 | STATIC_ORDER = 0x02, ///< use creation order instead of focused order | ||
47 | }; | ||
48 | |||
49 | FocusableList(BScreen &scr): m_pat(0), m_parent(0), m_screen(scr) { } | ||
50 | FocusableList(BScreen &scr, const std::string pat); | ||
51 | FocusableList(BScreen &scr, const FocusableList &parent, | ||
52 | const std::string pat); | ||
53 | |||
54 | static void parseArgs(const std::string &in, int &opts, std::string &out); | ||
55 | static const FocusableList *getListFromOptions(BScreen &scr, int opts); | ||
56 | |||
57 | void update(FbTk::Subject *subj); | ||
58 | |||
59 | /// functions for modifying the list contents | ||
60 | void pushFront(Focusable &win); | ||
61 | void pushBack(Focusable &win); | ||
62 | void moveToFront(Focusable &win); | ||
63 | void moveToBack(Focusable &win); | ||
64 | void remove(Focusable &win); | ||
65 | |||
66 | /// accessor for list | ||
67 | Focusables &clientList() { return m_list; } | ||
68 | const Focusables &clientList() const { return m_list; } | ||
69 | |||
70 | /// does the list contain any windows? | ||
71 | bool empty() const { return m_list.empty(); } | ||
72 | /// does the list contain the given window? | ||
73 | bool contains(const Focusable &win) const; | ||
74 | |||
75 | /** | ||
76 | @name signals | ||
77 | @{ | ||
78 | */ | ||
79 | FbTk::Subject &orderSig() { return m_ordersig; } | ||
80 | const FbTk::Subject &orderSig() const { return m_ordersig; } | ||
81 | FbTk::Subject &addSig() { return m_addsig; } | ||
82 | const FbTk::Subject &addSig() const { return m_addsig; } | ||
83 | FbTk::Subject &removeSig() { return m_removesig; } | ||
84 | const FbTk::Subject &removeSig() const { return m_removesig; } | ||
85 | FbTk::Subject &resetSig() { return m_resetsig; } | ||
86 | const FbTk::Subject &resetSig() const { return m_resetsig; } | ||
87 | /** @} */ // end group signals | ||
88 | |||
89 | /** | ||
90 | * Signaling object to attatch observers to. | ||
91 | */ | ||
92 | class FocusableListSubject: public FbTk::Subject { | ||
93 | public: | ||
94 | explicit FocusableListSubject(): m_win(0) { } | ||
95 | void notify(Focusable *win) { m_win = win; FbTk::Subject::notify(); } | ||
96 | /// @return context for this signal | ||
97 | Focusable *win() { return m_win; } | ||
98 | |||
99 | private: | ||
100 | Focusable *m_win; | ||
101 | }; | ||
102 | |||
103 | private: | ||
104 | void init(); | ||
105 | void addMatching(); | ||
106 | void checkUpdate(Focusable &win); | ||
107 | bool insertFromParent(Focusable &win); | ||
108 | void attachSignals(Focusable &win); | ||
109 | void detachSignals(Focusable &win); | ||
110 | void reset(); | ||
111 | void attachChild(FocusableList &child) const; | ||
112 | |||
113 | std::auto_ptr<ClientPattern> m_pat; | ||
114 | const FocusableList *m_parent; | ||
115 | BScreen &m_screen; | ||
116 | std::list<Focusable *> m_list; | ||
117 | |||
118 | mutable FocusableListSubject m_ordersig, m_addsig, m_removesig, m_resetsig; | ||
119 | }; | ||
120 | |||
121 | #endif // FOCUSABLELIST_HH | ||
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index bbd867b..1a4e87c 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "FocusControl.hh" | 38 | #include "FocusControl.hh" |
39 | #include "FbCommands.hh" | 39 | #include "FbCommands.hh" |
40 | #include "Layer.hh" | 40 | #include "Layer.hh" |
41 | #include "STLUtil.hh" | ||
41 | 42 | ||
42 | #include "FbTk/I18n.hh" | 43 | #include "FbTk/I18n.hh" |
43 | #include "FbTk/Menu.hh" | 44 | #include "FbTk/Menu.hh" |
@@ -68,26 +69,6 @@ using std::endl; | |||
68 | namespace FbTk { | 69 | namespace FbTk { |
69 | 70 | ||
70 | template<> | 71 | template<> |
71 | void FbTk::Resource<IconbarTool::Mode>::setFromString(const char *strval) { | ||
72 | if (strcasecmp(strval, "None") == 0) | ||
73 | m_value = IconbarTool::NONE; | ||
74 | else if (strcasecmp(strval, "Icons") == 0) | ||
75 | m_value = IconbarTool::ICONS; | ||
76 | else if (strcasecmp(strval, "NoIcons") == 0) | ||
77 | m_value = IconbarTool::NOICONS; | ||
78 | else if (strcasecmp(strval, "WorkspaceIcons") == 0) | ||
79 | m_value = IconbarTool::WORKSPACEICONS; | ||
80 | else if (strcasecmp(strval, "WorkspaceNoIcons") == 0) | ||
81 | m_value = IconbarTool::WORKSPACENOICONS; | ||
82 | else if (strcasecmp(strval, "Workspace") == 0) | ||
83 | m_value = IconbarTool::WORKSPACE; | ||
84 | else if (strcasecmp(strval, "AllWindows") == 0) | ||
85 | m_value = IconbarTool::ALLWINDOWS; | ||
86 | else | ||
87 | setDefaultValue(); | ||
88 | } | ||
89 | |||
90 | template<> | ||
91 | void FbTk::Resource<Container::Alignment>::setDefaultValue() { | 72 | void FbTk::Resource<Container::Alignment>::setDefaultValue() { |
92 | m_value = Container::RELATIVE; | 73 | m_value = Container::RELATIVE; |
93 | } | 74 | } |
@@ -117,35 +98,6 @@ void FbTk::Resource<Container::Alignment>::setFromString(const char *str) { | |||
117 | setDefaultValue(); | 98 | setDefaultValue(); |
118 | } | 99 | } |
119 | 100 | ||
120 | template<> | ||
121 | string FbTk::Resource<IconbarTool::Mode>::getString() const { | ||
122 | |||
123 | switch (m_value) { | ||
124 | case IconbarTool::NONE: | ||
125 | return string("None"); | ||
126 | break; | ||
127 | case IconbarTool::ICONS: | ||
128 | return string("Icons"); | ||
129 | break; | ||
130 | case IconbarTool::NOICONS: | ||
131 | return string("NoIcons"); | ||
132 | break; | ||
133 | case IconbarTool::WORKSPACEICONS: | ||
134 | return string("WorkspaceIcons"); | ||
135 | break; | ||
136 | case IconbarTool::WORKSPACENOICONS: | ||
137 | return string("WorkspaceNoIcons"); | ||
138 | break; | ||
139 | case IconbarTool::WORKSPACE: | ||
140 | return string("Workspace"); | ||
141 | break; | ||
142 | case IconbarTool::ALLWINDOWS: | ||
143 | return string("AllWindows"); | ||
144 | break; | ||
145 | } | ||
146 | // default string | ||
147 | return string("Icons"); | ||
148 | } | ||
149 | } // end namespace FbTk | 101 | } // end namespace FbTk |
150 | 102 | ||
151 | namespace { | 103 | namespace { |
@@ -153,7 +105,7 @@ namespace { | |||
153 | class ToolbarModeMenuItem : public FbTk::MenuItem { | 105 | class ToolbarModeMenuItem : public FbTk::MenuItem { |
154 | public: | 106 | public: |
155 | ToolbarModeMenuItem(const FbTk::FbString &label, IconbarTool &handler, | 107 | ToolbarModeMenuItem(const FbTk::FbString &label, IconbarTool &handler, |
156 | IconbarTool::Mode mode, | 108 | string mode, |
157 | FbTk::RefCount<FbTk::Command> &cmd): | 109 | FbTk::RefCount<FbTk::Command> &cmd): |
158 | FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) { | 110 | FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) { |
159 | } | 111 | } |
@@ -165,7 +117,7 @@ public: | |||
165 | 117 | ||
166 | private: | 118 | private: |
167 | IconbarTool &m_handler; | 119 | IconbarTool &m_handler; |
168 | IconbarTool::Mode m_mode; | 120 | string m_mode; |
169 | }; | 121 | }; |
170 | 122 | ||
171 | class ToolbarAlignMenuItem: public FbTk::MenuItem { | 123 | class ToolbarAlignMenuItem: public FbTk::MenuItem { |
@@ -198,42 +150,42 @@ void setupModeMenu(FbTk::Menu &menu, IconbarTool &handler) { | |||
198 | menu.insert(new ToolbarModeMenuItem(_FB_XTEXT(Toolbar, IconbarModeNone, | 150 | menu.insert(new ToolbarModeMenuItem(_FB_XTEXT(Toolbar, IconbarModeNone, |
199 | "None", "No icons are shown in the iconbar"), | 151 | "None", "No icons are shown in the iconbar"), |
200 | handler, | 152 | handler, |
201 | IconbarTool::NONE, saverc_cmd)); | 153 | "none", saverc_cmd)); |
202 | 154 | ||
203 | menu.insert(new ToolbarModeMenuItem( | 155 | menu.insert(new ToolbarModeMenuItem( |
204 | _FB_XTEXT(Toolbar, IconbarModeIcons, | 156 | _FB_XTEXT(Toolbar, IconbarModeIcons, |
205 | "Icons", "Iconified windows from all workspaces are shown"), | 157 | "Icons", "Iconified windows from all workspaces are shown"), |
206 | handler, | 158 | handler, |
207 | IconbarTool::ICONS, saverc_cmd)); | 159 | "{static groups} (minimized=yes)", saverc_cmd)); |
208 | 160 | ||
209 | menu.insert(new ToolbarModeMenuItem( | 161 | menu.insert(new ToolbarModeMenuItem( |
210 | _FB_XTEXT(Toolbar, IconbarModeNoIcons, | 162 | _FB_XTEXT(Toolbar, IconbarModeNoIcons, |
211 | "NoIcons", "No iconified windows from all workspaces are shown"), | 163 | "NoIcons", "No iconified windows from all workspaces are shown"), |
212 | handler, | 164 | handler, |
213 | IconbarTool::NOICONS, saverc_cmd)); | 165 | "{static groups} (minimized=no)", saverc_cmd)); |
214 | 166 | ||
215 | menu.insert(new ToolbarModeMenuItem( | 167 | menu.insert(new ToolbarModeMenuItem( |
216 | _FB_XTEXT(Toolbar, IconbarModeWorkspaceIcons, | 168 | _FB_XTEXT(Toolbar, IconbarModeWorkspaceIcons, |
217 | "WorkspaceIcons", "Iconified windows from this workspace are shown"), | 169 | "WorkspaceIcons", "Iconified windows from this workspace are shown"), |
218 | handler, | 170 | handler, |
219 | IconbarTool::WORKSPACEICONS, saverc_cmd)); | 171 | "{static groups} (minimized=yes) (workspace)", saverc_cmd)); |
220 | 172 | ||
221 | menu.insert(new ToolbarModeMenuItem( | 173 | menu.insert(new ToolbarModeMenuItem( |
222 | _FB_XTEXT(Toolbar, IconbarModeWorkspaceNoIcons, | 174 | _FB_XTEXT(Toolbar, IconbarModeWorkspaceNoIcons, |
223 | "WorkspaceNoIcons", "No iconified windows from this workspace are shown"), | 175 | "WorkspaceNoIcons", "No iconified windows from this workspace are shown"), |
224 | handler, | 176 | handler, |
225 | IconbarTool::WORKSPACENOICONS, saverc_cmd)); | 177 | "{static groups} (minimized=no) (workspace)", saverc_cmd)); |
226 | 178 | ||
227 | menu.insert(new ToolbarModeMenuItem( | 179 | menu.insert(new ToolbarModeMenuItem( |
228 | _FB_XTEXT(Toolbar, IconbarModeWorkspace, | 180 | _FB_XTEXT(Toolbar, IconbarModeWorkspace, |
229 | "Workspace", "Normal and iconified windows from this workspace are shown"), | 181 | "Workspace", "Normal and iconified windows from this workspace are shown"), |
230 | handler, | 182 | handler, |
231 | IconbarTool::WORKSPACE, saverc_cmd)); | 183 | "{static groups} (workspace)", saverc_cmd)); |
232 | 184 | ||
233 | menu.insert(new ToolbarModeMenuItem( | 185 | menu.insert(new ToolbarModeMenuItem( |
234 | _FB_XTEXT(Toolbar, IconbarModeAllWindows, "All Windows", "All windows are shown"), | 186 | _FB_XTEXT(Toolbar, IconbarModeAllWindows, "All Windows", "All windows are shown"), |
235 | handler, | 187 | handler, |
236 | IconbarTool::ALLWINDOWS, saverc_cmd)); | 188 | "{static groups}", saverc_cmd)); |
237 | 189 | ||
238 | menu.insert(new FbTk::MenuSeparator()); | 190 | menu.insert(new FbTk::MenuSeparator()); |
239 | 191 | ||
@@ -257,26 +209,6 @@ void setupModeMenu(FbTk::Menu &menu, IconbarTool &handler) { | |||
257 | menu.updateMenu(); | 209 | menu.updateMenu(); |
258 | } | 210 | } |
259 | 211 | ||
260 | inline bool checkAddWindow(IconbarTool::Mode mode, const FluxboxWindow &win) { | ||
261 | if (win.isIconHidden() || mode == IconbarTool::NONE) | ||
262 | return false; | ||
263 | |||
264 | if ((mode == IconbarTool::ICONS || mode == IconbarTool::WORKSPACEICONS) && | ||
265 | !win.isIconic()) | ||
266 | return false; | ||
267 | |||
268 | if ((mode == IconbarTool::NOICONS || mode == IconbarTool::WORKSPACENOICONS) | ||
269 | && win.isIconic()) | ||
270 | return false; | ||
271 | |||
272 | if ((mode == IconbarTool::WORKSPACE || mode == IconbarTool::WORKSPACEICONS | ||
273 | || mode == IconbarTool::WORKSPACENOICONS) && | ||
274 | win.workspaceNumber() != win.screen().currentWorkspaceID()) | ||
275 | return false; | ||
276 | |||
277 | return true; | ||
278 | } | ||
279 | |||
280 | typedef FbTk::RefCount<FbTk::Command> RefCmd; | 212 | typedef FbTk::RefCount<FbTk::Command> RefCmd; |
281 | 213 | ||
282 | class ShowMenu: public FbTk::Command { | 214 | class ShowMenu: public FbTk::Command { |
@@ -322,14 +254,16 @@ private: | |||
322 | 254 | ||
323 | }; // end anonymous namespace | 255 | }; // end anonymous namespace |
324 | 256 | ||
325 | IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScreen &screen, | 257 | IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, |
326 | FbTk::Menu &menu): | 258 | BScreen &screen, FbTk::Menu &menu): |
327 | ToolbarItem(ToolbarItem::RELATIVE), | 259 | ToolbarItem(ToolbarItem::RELATIVE), |
328 | m_screen(screen), | 260 | m_screen(screen), |
329 | m_icon_container(parent), | 261 | m_icon_container(parent), |
330 | m_theme(theme), | 262 | m_theme(theme), |
331 | m_empty_pm( screen.imageControl() ), | 263 | m_empty_pm( screen.imageControl() ), |
332 | m_rc_mode(screen.resourceManager(), WORKSPACE, | 264 | m_winlist(new FocusableList(screen)), |
265 | m_mode("none"), | ||
266 | m_rc_mode(screen.resourceManager(), "{static groups} (workspace)", | ||
333 | screen.name() + ".iconbar.mode", screen.altName() + ".Iconbar.Mode"), | 267 | screen.name() + ".iconbar.mode", screen.altName() + ".Iconbar.Mode"), |
334 | m_rc_alignment(screen.resourceManager(), Container::LEFT, | 268 | m_rc_alignment(screen.resourceManager(), Container::LEFT, |
335 | screen.name() + ".iconbar.alignment", screen.altName() + ".Iconbar.Alignment"), | 269 | screen.name() + ".iconbar.alignment", screen.altName() + ".Iconbar.Alignment"), |
@@ -365,10 +299,7 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScr | |||
365 | 299 | ||
366 | // setup signals | 300 | // setup signals |
367 | theme.reconfigSig().attach(this); | 301 | theme.reconfigSig().attach(this); |
368 | screen.clientListSig().attach(this); | 302 | setMode(*m_rc_mode); |
369 | screen.iconListSig().attach(this); | ||
370 | screen.currentWorkspaceSig().attach(this); | ||
371 | |||
372 | } | 303 | } |
373 | 304 | ||
374 | IconbarTool::~IconbarTool() { | 305 | IconbarTool::~IconbarTool() { |
@@ -405,20 +336,33 @@ void IconbarTool::setAlignment(Container::Alignment align) { | |||
405 | m_menu.reconfigure(); | 336 | m_menu.reconfigure(); |
406 | } | 337 | } |
407 | 338 | ||
408 | void IconbarTool::setMode(Mode mode) { | 339 | void IconbarTool::setMode(string mode) { |
409 | if (mode == *m_rc_mode) | 340 | if (mode == m_mode) |
410 | return; | 341 | return; |
411 | 342 | ||
412 | *m_rc_mode = mode; | 343 | *m_rc_mode = m_mode = mode; |
413 | 344 | ||
414 | // lock graphics update | 345 | // lock graphics update |
415 | m_icon_container.setUpdateLock(true); | 346 | m_icon_container.setUpdateLock(true); |
416 | 347 | ||
417 | deleteIcons(); | 348 | if (m_winlist.get()) { |
418 | 349 | m_winlist->addSig().detach(this); | |
419 | // update mode | 350 | m_winlist->removeSig().detach(this); |
420 | if (mode != NONE) | 351 | m_winlist->orderSig().detach(this); |
421 | updateList(); | 352 | m_winlist->resetSig().detach(this); |
353 | } | ||
354 | if (mode == "none") | ||
355 | m_winlist.reset(new FocusableList(m_screen)); | ||
356 | else | ||
357 | m_winlist.reset(new FocusableList(m_screen, | ||
358 | mode + " (iconhidden=no)")); | ||
359 | if (m_winlist.get()) { | ||
360 | m_winlist->addSig().attach(this); | ||
361 | m_winlist->removeSig().attach(this); | ||
362 | m_winlist->orderSig().attach(this); | ||
363 | m_winlist->resetSig().attach(this); | ||
364 | } | ||
365 | reset(); | ||
422 | 366 | ||
423 | // unlock graphics update | 367 | // unlock graphics update |
424 | m_icon_container.setUpdateLock(false); | 368 | m_icon_container.setUpdateLock(false); |
@@ -445,10 +389,7 @@ unsigned int IconbarTool::borderWidth() const { | |||
445 | void IconbarTool::update(FbTk::Subject *subj) { | 389 | void IconbarTool::update(FbTk::Subject *subj) { |
446 | // ignore updates if we're shutting down | 390 | // ignore updates if we're shutting down |
447 | if (m_screen.isShuttingdown()) { | 391 | if (m_screen.isShuttingdown()) { |
448 | m_screen.clientListSig().detach(this); | 392 | if (!m_icons.empty()) |
449 | m_screen.iconListSig().detach(this); | ||
450 | m_screen.currentWorkspaceSig().detach(this); | ||
451 | if (!m_icon_list.empty()) | ||
452 | deleteIcons(); | 393 | deleteIcons(); |
453 | return; | 394 | return; |
454 | } | 395 | } |
@@ -462,68 +403,26 @@ void IconbarTool::update(FbTk::Subject *subj) { | |||
462 | 403 | ||
463 | m_icon_container.setMaxSizePerClient(*m_rc_client_width); | 404 | m_icon_container.setMaxSizePerClient(*m_rc_client_width); |
464 | 405 | ||
465 | 406 | if (subj == &m_theme.reconfigSig()) { | |
466 | if (mode() == NONE) { | 407 | setMode(*m_rc_mode); |
467 | if (subj != 0 && typeid(*subj) == typeid(IconbarTheme)) | ||
468 | renderTheme(); | ||
469 | return; | 408 | return; |
470 | } | 409 | } |
471 | 410 | ||
472 | // handle window signal | ||
473 | if (subj != 0 && typeid(*subj) == typeid(FluxboxWindow::WinSubject)) { | ||
474 | // we handle everything except die signal here | ||
475 | FluxboxWindow::WinSubject *winsubj = static_cast<FluxboxWindow::WinSubject *>(subj); | ||
476 | if (subj == &(winsubj->win().workspaceSig())) { | ||
477 | // we can ignore this signal if we're in ALLWINDOWS mode | ||
478 | if (mode() == ALLWINDOWS || mode() == ICONS || mode() == NOICONS) | ||
479 | return; | ||
480 | |||
481 | // workspace changed for this window, and if it's not on current workspace we remove it | ||
482 | if (m_screen.currentWorkspaceID() != winsubj->win().workspaceNumber()) { | ||
483 | removeWindow(winsubj->win()); | ||
484 | renderTheme(); | ||
485 | } | ||
486 | return; | ||
487 | } else if (subj == &(winsubj->win().stateSig())) { | ||
488 | if (!checkAddWindow(mode(), winsubj->win())) { | ||
489 | removeWindow(winsubj->win()); | ||
490 | renderTheme(); | ||
491 | } | ||
492 | return; | ||
493 | |||
494 | } else { | ||
495 | // signal not handled | ||
496 | return; | ||
497 | } | ||
498 | } else if (subj != 0 && typeid(*subj) == typeid(Focusable::FocusSubject)) { | ||
499 | Focusable::FocusSubject *winsubj = static_cast<Focusable::FocusSubject *>(subj); | ||
500 | if (subj == &(winsubj->win().dieSig())) { // die sig | ||
501 | removeWindow(winsubj->win()); | ||
502 | renderTheme(); | ||
503 | return; // we don't need to update the entire list | ||
504 | } | ||
505 | } | ||
506 | |||
507 | bool remove_all = false; // if we should readd all windows | ||
508 | |||
509 | if (subj != 0 && typeid(*subj) == typeid(BScreen::ScreenSubject) && | ||
510 | mode() != ALLWINDOWS && mode() != ICONS && mode() != NOICONS) { | ||
511 | BScreen::ScreenSubject *screen_subj = static_cast<BScreen::ScreenSubject *>(subj); | ||
512 | // current workspace sig | ||
513 | if (&m_screen.currentWorkspaceSig() == screen_subj ) { | ||
514 | remove_all = true; // remove and readd all windows | ||
515 | } | ||
516 | |||
517 | } | ||
518 | |||
519 | // lock graphic update | 411 | // lock graphic update |
520 | m_icon_container.setUpdateLock(true); | 412 | m_icon_container.setUpdateLock(true); |
521 | 413 | ||
522 | if (remove_all) | 414 | if (typeid(*subj) == typeid(FocusableList::FocusableListSubject)) { |
523 | deleteIcons(); | 415 | FocusableList::FocusableListSubject *fsubj = |
524 | 416 | static_cast<FocusableList::FocusableListSubject *>(subj); | |
525 | // ok, we got some signal that we need to update our iconbar container | 417 | if (subj == &m_winlist->addSig()) |
526 | updateList(); | 418 | insertWindow(*fsubj->win()); |
419 | else if (subj == &m_winlist->removeSig()) | ||
420 | removeWindow(*fsubj->win()); | ||
421 | else if (subj == &m_winlist->resetSig()) | ||
422 | reset(); | ||
423 | else if (subj == &m_winlist->orderSig()) | ||
424 | insertWindow(*fsubj->win()); | ||
425 | } | ||
527 | 426 | ||
528 | // unlock container and update graphics | 427 | // unlock container and update graphics |
529 | m_icon_container.setUpdateLock(false); | 428 | m_icon_container.setUpdateLock(false); |
@@ -540,25 +439,42 @@ void IconbarTool::update(FbTk::Subject *subj) { | |||
540 | renderTheme(); | 439 | renderTheme(); |
541 | } | 440 | } |
542 | 441 | ||
543 | IconButton *IconbarTool::findButton(Focusable &win) { | 442 | void IconbarTool::insertWindow(Focusable &win, int pos) { |
443 | IconButton *button = 0; | ||
444 | |||
445 | IconMap::iterator icon_it = m_icons.find(&win); | ||
446 | if (icon_it != m_icons.end()) | ||
447 | button = icon_it->second; | ||
544 | 448 | ||
545 | IconList::iterator icon_it = m_icon_list.begin(); | 449 | if (button) |
546 | IconList::iterator icon_it_end = m_icon_list.end(); | 450 | m_icon_container.removeItem(button); |
547 | for (; icon_it != icon_it_end; ++icon_it) { | 451 | else |
548 | if (&(*icon_it)->win() == &win) | 452 | button = makeButton(win); |
549 | return *icon_it; | 453 | if (!button) return; |
454 | |||
455 | if (pos == -2) { | ||
456 | pos = 0; | ||
457 | list<Focusable *>::iterator it = m_winlist->clientList().begin(), | ||
458 | it_end = m_winlist->clientList().end(); | ||
459 | for (; it != it_end && *it != &win; ++it) | ||
460 | pos++; | ||
550 | } | 461 | } |
551 | 462 | ||
552 | return 0; | 463 | m_icon_container.insertItem(button, pos); |
464 | } | ||
465 | |||
466 | void IconbarTool::reset() { | ||
467 | deleteIcons(); | ||
468 | updateList(); | ||
553 | } | 469 | } |
554 | 470 | ||
555 | void IconbarTool::updateSizing() { | 471 | void IconbarTool::updateSizing() { |
556 | m_icon_container.setBorderWidth(m_theme.border().width()); | 472 | m_icon_container.setBorderWidth(m_theme.border().width()); |
557 | 473 | ||
558 | IconList::iterator icon_it = m_icon_list.begin(); | 474 | IconMap::iterator icon_it = m_icons.begin(); |
559 | const IconList::iterator icon_it_end = m_icon_list.end(); | 475 | const IconMap::iterator icon_it_end = m_icons.end(); |
560 | for (; icon_it != icon_it_end; ++icon_it) | 476 | for (; icon_it != icon_it_end; ++icon_it) |
561 | (*icon_it)->reconfigTheme(); | 477 | icon_it->second->reconfigTheme(); |
562 | 478 | ||
563 | } | 479 | } |
564 | 480 | ||
@@ -588,10 +504,10 @@ void IconbarTool::renderTheme() { | |||
588 | m_icon_container.setAlpha(m_alpha); | 504 | m_icon_container.setAlpha(m_alpha); |
589 | 505 | ||
590 | // update buttons | 506 | // update buttons |
591 | IconList::iterator icon_it = m_icon_list.begin(); | 507 | IconMap::iterator icon_it = m_icons.begin(); |
592 | const IconList::iterator icon_it_end = m_icon_list.end(); | 508 | const IconMap::iterator icon_it_end = m_icons.end(); |
593 | for (; icon_it != icon_it_end; ++icon_it) | 509 | for (; icon_it != icon_it_end; ++icon_it) |
594 | renderButton(*(*icon_it)); | 510 | renderButton(*icon_it->second); |
595 | 511 | ||
596 | } | 512 | } |
597 | 513 | ||
@@ -606,49 +522,30 @@ void IconbarTool::renderButton(IconButton &button, bool clear) { | |||
606 | 522 | ||
607 | void IconbarTool::deleteIcons() { | 523 | void IconbarTool::deleteIcons() { |
608 | m_icon_container.removeAll(); | 524 | m_icon_container.removeAll(); |
609 | while (!m_icon_list.empty()) { | 525 | STLUtil::destroyAndClearSecond(m_icons); |
610 | delete m_icon_list.back(); | ||
611 | m_icon_list.pop_back(); | ||
612 | } | ||
613 | } | 526 | } |
614 | 527 | ||
615 | void IconbarTool::removeWindow(Focusable &win) { | 528 | void IconbarTool::removeWindow(Focusable &win) { |
616 | // got window die signal, lets find and remove the window | 529 | // got window die signal, lets find and remove the window |
617 | IconList::iterator it = m_icon_list.begin(); | 530 | IconMap::iterator it = m_icons.find(&win); |
618 | IconList::iterator it_end = m_icon_list.end(); | 531 | if (it == m_icons.end()) |
619 | for (; it != it_end; ++it) { | ||
620 | if (&(*it)->win() == &win) | ||
621 | break; | ||
622 | } | ||
623 | // did we find it? | ||
624 | if (it == m_icon_list.end()) { | ||
625 | return; | 532 | return; |
626 | } | ||
627 | #ifdef DEBUG | 533 | #ifdef DEBUG |
628 | cerr<<"IconbarTool::"<<__FUNCTION__<<"( 0x"<<&win<<" title = "<<win.title()<<") found!"<<endl; | 534 | cerr<<"IconbarTool::"<<__FUNCTION__<<"( 0x"<<&win<<" title = "<<win.title()<<") found!"<<endl; |
629 | #endif // DEBUG | 535 | #endif // DEBUG |
630 | // detach from all signals | ||
631 | win.dieSig().detach(this); | ||
632 | if (win.fbwindow()) { | ||
633 | win.fbwindow()->workspaceSig().detach(this); | ||
634 | win.fbwindow()->stateSig().detach(this); | ||
635 | } | ||
636 | 536 | ||
637 | // remove from list and render theme again | 537 | // remove from list and render theme again |
638 | IconButton *button = *it; | 538 | IconButton *button = it->second; |
639 | 539 | m_icons.erase(it); | |
640 | m_icon_container.removeItem(m_icon_container.find(*it)); | 540 | m_icon_container.removeItem(button); |
641 | m_icon_list.erase(it); | ||
642 | |||
643 | delete button; | 541 | delete button; |
644 | |||
645 | } | 542 | } |
646 | 543 | ||
647 | void IconbarTool::addWindow(Focusable &win) { | 544 | IconButton *IconbarTool::makeButton(Focusable &win) { |
648 | // we just want windows that have clients | 545 | // we just want windows that have clients |
649 | FluxboxWindow *fbwin = win.fbwindow(); | 546 | FluxboxWindow *fbwin = win.fbwindow(); |
650 | if (!fbwin || fbwin->clientList().empty() || fbwin->isIconHidden()) | 547 | if (!fbwin || fbwin->clientList().empty()) |
651 | return; | 548 | return 0; |
652 | #ifdef DEBUG | 549 | #ifdef DEBUG |
653 | cerr<<"IconbarTool::addWindow(0x"<<&win<<" title = "<<win.title()<<")"<<endl; | 550 | cerr<<"IconbarTool::addWindow(0x"<<&win<<" title = "<<win.title()<<")"<<endl; |
654 | #endif // DEBUG | 551 | #endif // DEBUG |
@@ -660,39 +557,21 @@ void IconbarTool::addWindow(Focusable &win) { | |||
660 | button->setOnClick(menu_cmd, 3); | 557 | button->setOnClick(menu_cmd, 3); |
661 | 558 | ||
662 | renderButton(*button, false); // update the attributes, but don't clear it | 559 | renderButton(*button, false); // update the attributes, but don't clear it |
663 | m_icon_container.insertItem(button); | 560 | m_icons[&win] = button; |
664 | m_icon_list.push_back(button); | 561 | return button; |
665 | |||
666 | // dont forget to detach signal in removeWindow | ||
667 | win.dieSig().attach(this); | ||
668 | fbwin->workspaceSig().attach(this); | ||
669 | fbwin->stateSig().attach(this); | ||
670 | } | 562 | } |
671 | 563 | ||
672 | void IconbarTool::updateList() { | 564 | void IconbarTool::updateList() { |
673 | list<Focusable *> ordered_list = | 565 | list<Focusable *>::iterator it = m_winlist->clientList().begin(); |
674 | m_screen.focusControl().creationOrderWinList(); | 566 | list<Focusable *>::iterator it_end = m_winlist->clientList().end(); |
675 | list<Focusable *>::iterator it = ordered_list.begin(); | ||
676 | list<Focusable *>::iterator it_end = ordered_list.end(); | ||
677 | for (; it != it_end; ++it) { | 567 | for (; it != it_end; ++it) { |
678 | if ((*it)->fbwindow() && checkAddWindow(mode(), *(*it)->fbwindow()) && | 568 | if ((*it)->fbwindow()) |
679 | !checkDuplicate(**it)) | 569 | insertWindow(**it, -1); |
680 | addWindow(**it); | ||
681 | } | 570 | } |
682 | 571 | ||
683 | renderTheme(); | 572 | renderTheme(); |
684 | } | 573 | } |
685 | 574 | ||
686 | bool IconbarTool::checkDuplicate(Focusable &win) { | ||
687 | IconList::iterator it = m_icon_list.begin(); | ||
688 | IconList::iterator it_end = m_icon_list.end(); | ||
689 | for (; it != it_end; ++it) { | ||
690 | if (&win == &(*it)->win()) | ||
691 | return true; | ||
692 | } | ||
693 | return false; | ||
694 | } | ||
695 | |||
696 | void IconbarTool::setOrientation(FbTk::Orientation orient) { | 575 | void IconbarTool::setOrientation(FbTk::Orientation orient) { |
697 | m_icon_container.setOrientation(orient); | 576 | m_icon_container.setOrientation(orient); |
698 | ToolbarItem::setOrientation(orient); | 577 | ToolbarItem::setOrientation(orient); |
diff --git a/src/IconbarTool.hh b/src/IconbarTool.hh index 323c714..e1bebe3 100644 --- a/src/IconbarTool.hh +++ b/src/IconbarTool.hh | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "ToolbarItem.hh" | 28 | #include "ToolbarItem.hh" |
29 | #include "Container.hh" | 29 | #include "Container.hh" |
30 | #include "FbMenu.hh" | 30 | #include "FbMenu.hh" |
31 | #include "FocusableList.hh" | ||
31 | 32 | ||
32 | #include "FbTk/CachedPixmap.hh" | 33 | #include "FbTk/CachedPixmap.hh" |
33 | #include "FbTk/Observer.hh" | 34 | #include "FbTk/Observer.hh" |
@@ -36,7 +37,7 @@ | |||
36 | 37 | ||
37 | #include <X11/Xlib.h> | 38 | #include <X11/Xlib.h> |
38 | 39 | ||
39 | #include <list> | 40 | #include <map> |
40 | 41 | ||
41 | class IconbarTheme; | 42 | class IconbarTheme; |
42 | class BScreen; | 43 | class BScreen; |
@@ -45,17 +46,7 @@ class Focusable; | |||
45 | 46 | ||
46 | class IconbarTool: public ToolbarItem, public FbTk::Observer { | 47 | class IconbarTool: public ToolbarItem, public FbTk::Observer { |
47 | public: | 48 | public: |
48 | typedef std::list<IconButton *> IconList; | 49 | typedef std::map<Focusable *, IconButton *> IconMap; |
49 | /// iconbar mode | ||
50 | enum Mode { | ||
51 | NONE, ///< no icons | ||
52 | ICONS, ///< all icons from all workspaces | ||
53 | NOICONS, ///< all noniconified windows from all workspaces | ||
54 | WORKSPACEICONS, ///< icons on current workspace | ||
55 | WORKSPACENOICONS, ///< non iconified workspaces on current workspaces | ||
56 | WORKSPACE, ///< all windows and all icons on current workspace | ||
57 | ALLWINDOWS ///< all windows and all icons from all workspaces | ||
58 | }; | ||
59 | 50 | ||
60 | IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, | 51 | IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, |
61 | BScreen &screen, FbTk::Menu &menu); | 52 | BScreen &screen, FbTk::Menu &menu); |
@@ -70,14 +61,14 @@ public: | |||
70 | void show(); | 61 | void show(); |
71 | void hide(); | 62 | void hide(); |
72 | void setAlignment(Container::Alignment a); | 63 | void setAlignment(Container::Alignment a); |
73 | void setMode(Mode mode); | 64 | void setMode(std::string mode); |
74 | void parentMoved() { m_icon_container.parentMoved(); } | 65 | void parentMoved() { m_icon_container.parentMoved(); } |
75 | 66 | ||
76 | unsigned int width() const; | 67 | unsigned int width() const; |
77 | unsigned int height() const; | 68 | unsigned int height() const; |
78 | unsigned int borderWidth() const; | 69 | unsigned int borderWidth() const; |
79 | 70 | ||
80 | Mode mode() const { return *m_rc_mode; } | 71 | std::string mode() const { return *m_rc_mode; } |
81 | 72 | ||
82 | void setOrientation(FbTk::Orientation orient); | 73 | void setOrientation(FbTk::Orientation orient); |
83 | Container::Alignment alignment() const { return m_icon_container.alignment(); } | 74 | Container::Alignment alignment() const { return m_icon_container.alignment(); } |
@@ -85,9 +76,6 @@ public: | |||
85 | const BScreen &screen() const { return m_screen; } | 76 | const BScreen &screen() const { return m_screen; } |
86 | private: | 77 | private: |
87 | 78 | ||
88 | /// @return button associated with window | ||
89 | IconButton *findButton(Focusable &win); | ||
90 | |||
91 | void updateSizing(); | 79 | void updateSizing(); |
92 | 80 | ||
93 | /// render single button, and probably apply changes (clear) | 81 | /// render single button, and probably apply changes (clear) |
@@ -99,14 +87,16 @@ private: | |||
99 | void renderTheme(unsigned char alpha); | 87 | void renderTheme(unsigned char alpha); |
100 | /// destroy all icons | 88 | /// destroy all icons |
101 | void deleteIcons(); | 89 | void deleteIcons(); |
90 | /// add or move a single window | ||
91 | void insertWindow(Focusable &win, int pos = -2); | ||
102 | /// remove a single window | 92 | /// remove a single window |
103 | void removeWindow(Focusable &win); | 93 | void removeWindow(Focusable &win); |
104 | /// add a single window | 94 | /// make a button for the window |
105 | void addWindow(Focusable &win); | 95 | IconButton *makeButton(Focusable &win); |
96 | /// remove all windows and add again | ||
97 | void reset(); | ||
106 | /// add icons to the list | 98 | /// add icons to the list |
107 | void updateList(); | 99 | void updateList(); |
108 | /// check if window is already in the list | ||
109 | bool checkDuplicate(Focusable &win); | ||
110 | 100 | ||
111 | BScreen &m_screen; | 101 | BScreen &m_screen; |
112 | Container m_icon_container; | 102 | Container m_icon_container; |
@@ -114,8 +104,10 @@ private: | |||
114 | FbTk::CachedPixmap m_empty_pm; ///< pixmap for empty container | 104 | FbTk::CachedPixmap m_empty_pm; ///< pixmap for empty container |
115 | 105 | ||
116 | 106 | ||
117 | IconList m_icon_list; | 107 | std::auto_ptr<FocusableList> m_winlist; |
118 | FbTk::Resource<Mode> m_rc_mode; | 108 | IconMap m_icons; |
109 | std::string m_mode; | ||
110 | FbTk::Resource<std::string> m_rc_mode; | ||
119 | FbTk::Resource<Container::Alignment> m_rc_alignment; ///< alignment of buttons | 111 | FbTk::Resource<Container::Alignment> m_rc_alignment; ///< alignment of buttons |
120 | FbTk::Resource<int> m_rc_client_width; ///< size of client button in LEFT/RIGHT mode | 112 | FbTk::Resource<int> m_rc_client_width; ///< size of client button in LEFT/RIGHT mode |
121 | FbTk::Resource<unsigned int> m_rc_client_padding; ///< padding of the text | 113 | FbTk::Resource<unsigned int> m_rc_client_padding; ///< padding of the text |
diff --git a/src/Makefile.am b/src/Makefile.am index 9245097..3ecc610 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -151,7 +151,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ | |||
151 | IconButton.hh IconButton.cc \ | 151 | IconButton.hh IconButton.cc \ |
152 | IconbarTheme.hh IconbarTheme.cc \ | 152 | IconbarTheme.hh IconbarTheme.cc \ |
153 | STLUtil.hh \ | 153 | STLUtil.hh \ |
154 | Focusable.hh \ | 154 | Focusable.hh FocusableList.hh FocusableList.cc \ |
155 | ${newwmspec_SOURCE} ${gnome_SOURCE} \ | 155 | ${newwmspec_SOURCE} ${gnome_SOURCE} \ |
156 | ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE} | 156 | ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE} |
157 | 157 | ||
diff --git a/src/MinOverlapPlacement.cc b/src/MinOverlapPlacement.cc index ce7ff3c..874aea8 100644 --- a/src/MinOverlapPlacement.cc +++ b/src/MinOverlapPlacement.cc | |||
@@ -40,7 +40,7 @@ bool MinOverlapPlacement::placeWindow(const FluxboxWindow &win, int head, | |||
40 | 40 | ||
41 | std::list<FluxboxWindow *> windowlist; | 41 | std::list<FluxboxWindow *> windowlist; |
42 | const std::list<Focusable *> focusables = | 42 | const std::list<Focusable *> focusables = |
43 | win.screen().focusControl().focusedOrderWinList(); | 43 | win.screen().focusControl().focusedOrderWinList().clientList(); |
44 | std::list<Focusable *>::const_iterator foc_it = focusables.begin(), | 44 | std::list<Focusable *>::const_iterator foc_it = focusables.begin(), |
45 | foc_it_end = focusables.end(); | 45 | foc_it_end = focusables.end(); |
46 | unsigned int workspace = win.workspaceNumber(); | 46 | unsigned int workspace = win.workspaceNumber(); |
diff --git a/src/RowSmartPlacement.cc b/src/RowSmartPlacement.cc index 6457d59..5d1786c 100644 --- a/src/RowSmartPlacement.cc +++ b/src/RowSmartPlacement.cc | |||
@@ -33,7 +33,7 @@ bool RowSmartPlacement::placeWindow(const FluxboxWindow &win, int head, | |||
33 | 33 | ||
34 | std::list<FluxboxWindow *> windowlist; | 34 | std::list<FluxboxWindow *> windowlist; |
35 | const std::list<Focusable *> focusables = | 35 | const std::list<Focusable *> focusables = |
36 | win.screen().focusControl().focusedOrderWinList(); | 36 | win.screen().focusControl().focusedOrderWinList().clientList(); |
37 | std::list<Focusable *>::const_iterator foc_it = focusables.begin(), | 37 | std::list<Focusable *>::const_iterator foc_it = focusables.begin(), |
38 | foc_it_end = focusables.end(); | 38 | foc_it_end = focusables.end(); |
39 | unsigned int workspace = win.workspaceNumber(); | 39 | unsigned int workspace = win.workspaceNumber(); |
diff --git a/src/Screen.cc b/src/Screen.cc index e618216..a53792b 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -346,6 +346,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
346 | m_workspacenames_sig(*this), // workspace names signal | 346 | m_workspacenames_sig(*this), // workspace names signal |
347 | m_workspace_area_sig(*this), // workspace area signal | 347 | m_workspace_area_sig(*this), // workspace area signal |
348 | m_currentworkspace_sig(*this), // current workspace signal | 348 | m_currentworkspace_sig(*this), // current workspace signal |
349 | m_focusedwindow_sig(*this), // focused window signal | ||
349 | m_reconfigure_sig(*this), // reconfigure signal | 350 | m_reconfigure_sig(*this), // reconfigure signal |
350 | m_resize_sig(*this), | 351 | m_resize_sig(*this), |
351 | m_bg_change_sig(*this), | 352 | m_bg_change_sig(*this), |
@@ -871,19 +872,10 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { | |||
871 | } | 872 | } |
872 | 873 | ||
873 | if (mods == 0) // can't stacked cycle unless there is a mod to grab | 874 | if (mods == 0) // can't stacked cycle unless there is a mod to grab |
874 | options |= FocusControl::CYCLELINEAR; | 875 | options |= FocusableList::STATIC_ORDER; |
875 | |||
876 | const FocusControl::Focusables *win_list = 0; | ||
877 | if (options & FocusControl::CYCLEGROUPS) { | ||
878 | win_list = (options & FocusControl::CYCLELINEAR) ? | ||
879 | &focusControl().creationOrderWinList() : | ||
880 | &focusControl().focusedOrderWinList(); | ||
881 | } else { | ||
882 | win_list = (options & FocusControl::CYCLELINEAR) ? | ||
883 | &focusControl().creationOrderList() : | ||
884 | &focusControl().focusedOrderList(); | ||
885 | } | ||
886 | 876 | ||
877 | const FocusableList *win_list = | ||
878 | FocusableList::getListFromOptions(*this, options); | ||
887 | focusControl().cycleFocus(*win_list, pat, reverse); | 879 | focusControl().cycleFocus(*win_list, pat, reverse); |
888 | 880 | ||
889 | } | 881 | } |
diff --git a/src/Screen.hh b/src/Screen.hh index f5641e2..953411c 100644 --- a/src/Screen.hh +++ b/src/Screen.hh | |||
@@ -222,6 +222,8 @@ public: | |||
222 | FbTk::Subject &workspaceAreaSig() { return m_workspace_area_sig; } | 222 | FbTk::Subject &workspaceAreaSig() { return m_workspace_area_sig; } |
223 | /// current workspace signal | 223 | /// current workspace signal |
224 | FbTk::Subject ¤tWorkspaceSig() { return m_currentworkspace_sig; } | 224 | FbTk::Subject ¤tWorkspaceSig() { return m_currentworkspace_sig; } |
225 | /// focused window signal | ||
226 | FbTk::Subject &focusedWindowSig() { return m_focusedwindow_sig; } | ||
225 | /// reconfigure signal | 227 | /// reconfigure signal |
226 | FbTk::Subject &reconfigureSig() { return m_reconfigure_sig; } | 228 | FbTk::Subject &reconfigureSig() { return m_reconfigure_sig; } |
227 | FbTk::Subject &resizeSig() { return m_resize_sig; } | 229 | FbTk::Subject &resizeSig() { return m_resize_sig; } |
@@ -488,6 +490,7 @@ private: | |||
488 | m_workspacenames_sig, ///< workspace names signal | 490 | m_workspacenames_sig, ///< workspace names signal |
489 | m_workspace_area_sig, ///< workspace area changed signal | 491 | m_workspace_area_sig, ///< workspace area changed signal |
490 | m_currentworkspace_sig, ///< current workspace signal | 492 | m_currentworkspace_sig, ///< current workspace signal |
493 | m_focusedwindow_sig, ///< focused window signal | ||
491 | m_reconfigure_sig, ///< reconfigure signal | 494 | m_reconfigure_sig, ///< reconfigure signal |
492 | m_resize_sig, ///< resize signal | 495 | m_resize_sig, ///< resize signal |
493 | m_bg_change_sig; ///< background change signal | 496 | m_bg_change_sig; ///< background change signal |
diff --git a/src/Window.cc b/src/Window.cc index 898111d..903756a 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -1405,7 +1405,7 @@ void FluxboxWindow::iconify() { | |||
1405 | 1405 | ||
1406 | hide(true); | 1406 | hide(true); |
1407 | 1407 | ||
1408 | screen().focusControl().setFocusBack(this); | 1408 | screen().focusControl().setFocusBack(*this); |
1409 | 1409 | ||
1410 | ClientList::iterator client_it = m_clientlist.begin(); | 1410 | ClientList::iterator client_it = m_clientlist.begin(); |
1411 | const ClientList::iterator client_it_end = m_clientlist.end(); | 1411 | const ClientList::iterator client_it_end = m_clientlist.end(); |
@@ -2038,10 +2038,6 @@ void FluxboxWindow::setState(unsigned long new_state, bool setting_up) { | |||
2038 | (*it)->show(); | 2038 | (*it)->show(); |
2039 | (*it)->setEventMask(PropertyChangeMask | StructureNotifyMask | FocusChangeMask | KeyPressMask); | 2039 | (*it)->setEventMask(PropertyChangeMask | StructureNotifyMask | FocusChangeMask | KeyPressMask); |
2040 | } | 2040 | } |
2041 | |||
2042 | saveBlackboxAttribs(); | ||
2043 | //notify state changed | ||
2044 | m_statesig.notify(); | ||
2045 | } | 2041 | } |
2046 | 2042 | ||
2047 | bool FluxboxWindow::getState() { | 2043 | bool FluxboxWindow::getState() { |
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index a525078..79ceb40 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc | |||
@@ -49,7 +49,7 @@ void WindowListCmd::execute() { | |||
49 | 49 | ||
50 | BScreen *screen = Fluxbox::instance()->keyScreen(); | 50 | BScreen *screen = Fluxbox::instance()->keyScreen(); |
51 | if (screen != 0) { | 51 | if (screen != 0) { |
52 | FocusControl::Focusables win_list(screen->focusControl().creationOrderWinList()); | 52 | FocusControl::Focusables win_list(screen->focusControl().creationOrderWinList().clientList()); |
53 | 53 | ||
54 | FocusControl::Focusables::iterator it = win_list.begin(), | 54 | FocusControl::Focusables::iterator it = win_list.begin(), |
55 | it_end = win_list.end(); | 55 | it_end = win_list.end(); |
@@ -63,7 +63,7 @@ void WindowListCmd::execute() { | |||
63 | void AttachCmd::execute() { | 63 | void AttachCmd::execute() { |
64 | BScreen *screen = Fluxbox::instance()->keyScreen(); | 64 | BScreen *screen = Fluxbox::instance()->keyScreen(); |
65 | if (screen != 0) { | 65 | if (screen != 0) { |
66 | FocusControl::Focusables win_list(screen->focusControl().focusedOrderWinList()); | 66 | FocusControl::Focusables win_list(screen->focusControl().focusedOrderWinList().clientList()); |
67 | 67 | ||
68 | FocusControl::Focusables::iterator it = win_list.begin(), | 68 | FocusControl::Focusables::iterator it = win_list.begin(), |
69 | it_end = win_list.end(); | 69 | it_end = win_list.end(); |
@@ -95,16 +95,8 @@ void PrevWindowCmd::execute() { | |||
95 | void GoToWindowCmd::execute() { | 95 | void GoToWindowCmd::execute() { |
96 | BScreen *screen = Fluxbox::instance()->keyScreen(); | 96 | BScreen *screen = Fluxbox::instance()->keyScreen(); |
97 | if (screen != 0) { | 97 | if (screen != 0) { |
98 | const FocusControl::Focusables *win_list = 0; | 98 | const FocusableList *win_list = |
99 | if (m_option & FocusControl::CYCLEGROUPS) { | 99 | FocusableList::getListFromOptions(*screen, m_option); |
100 | win_list = (m_option & FocusControl::CYCLELINEAR) ? | ||
101 | &screen->focusControl().creationOrderWinList() : | ||
102 | &screen->focusControl().focusedOrderWinList(); | ||
103 | } else { | ||
104 | win_list = (m_option & FocusControl::CYCLELINEAR) ? | ||
105 | &screen->focusControl().creationOrderList() : | ||
106 | &screen->focusControl().focusedOrderList(); | ||
107 | } | ||
108 | screen->focusControl().goToWindowNumber(*win_list, m_num, &m_pat); | 100 | screen->focusControl().goToWindowNumber(*win_list, m_num, &m_pat); |
109 | } | 101 | } |
110 | } | 102 | } |
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index ddb09e2..3c30c14 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc | |||
@@ -514,6 +514,7 @@ void Fluxbox::initScreen(BScreen *screen) { | |||
514 | 514 | ||
515 | // attach screen signals to this | 515 | // attach screen signals to this |
516 | screen->currentWorkspaceSig().attach(this); | 516 | screen->currentWorkspaceSig().attach(this); |
517 | screen->focusedWindowSig().attach(this); | ||
517 | screen->workspaceCountSig().attach(this); | 518 | screen->workspaceCountSig().attach(this); |
518 | screen->workspaceNamesSig().attach(this); | 519 | screen->workspaceNamesSig().attach(this); |
519 | screen->workspaceAreaSig().attach(this); | 520 | screen->workspaceAreaSig().attach(this); |
@@ -642,7 +643,7 @@ void Fluxbox::setupConfigFiles() { | |||
642 | if (create_init) | 643 | if (create_init) |
643 | FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); | 644 | FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); |
644 | 645 | ||
645 | #define CONFIG_VERSION 4 | 646 | #define CONFIG_VERSION 5 |
646 | FbTk::Resource<int> config_version(m_resourcemanager, 0, | 647 | FbTk::Resource<int> config_version(m_resourcemanager, 0, |
647 | "session.configVersion", "Session.ConfigVersion"); | 648 | "session.configVersion", "Session.ConfigVersion"); |
648 | if (*config_version < CONFIG_VERSION) { | 649 | if (*config_version < CONFIG_VERSION) { |
@@ -1191,6 +1192,14 @@ void Fluxbox::update(FbTk::Subject *changedsub) { | |||
1191 | if ((*it).first->update()) | 1192 | if ((*it).first->update()) |
1192 | (*it).first->updateCurrentWorkspace(screen); | 1193 | (*it).first->updateCurrentWorkspace(screen); |
1193 | } | 1194 | } |
1195 | } else if ((&(screen.focusedWindowSig())) == changedsub) { | ||
1196 | for (AtomHandlerContainerIt it= m_atomhandler.begin(); | ||
1197 | it != m_atomhandler.end(); it++) { | ||
1198 | (*it).first->updateFocusedWindow(screen, | ||
1199 | (FocusControl::focusedWindow() ? | ||
1200 | FocusControl::focusedWindow()->window() : | ||
1201 | 0)); | ||
1202 | } | ||
1194 | } else if ((&(screen.workspaceAreaSig())) == changedsub) { | 1203 | } else if ((&(screen.workspaceAreaSig())) == changedsub) { |
1195 | for (AtomHandlerContainerIt it= m_atomhandler.begin(); | 1204 | for (AtomHandlerContainerIt it= m_atomhandler.begin(); |
1196 | it != m_atomhandler.end(); ++it) { | 1205 | it != m_atomhandler.end(); ++it) { |
@@ -1682,23 +1691,6 @@ bool Fluxbox::validateClient(const WinClient *client) const { | |||
1682 | return it != m_window_search.end(); | 1691 | return it != m_window_search.end(); |
1683 | } | 1692 | } |
1684 | 1693 | ||
1685 | void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) { | ||
1686 | if (screen != 0) { | ||
1687 | for (AtomHandlerContainerIt it= m_atomhandler.begin(); | ||
1688 | it != m_atomhandler.end(); it++) { | ||
1689 | (*it).first->updateFocusedWindow(*screen, (FocusControl::focusedWindow() ? | ||
1690 | FocusControl::focusedWindow()->window() : | ||
1691 | 0)); | ||
1692 | } | ||
1693 | } | ||
1694 | |||
1695 | if (old_screen && old_screen != screen) { | ||
1696 | for (AtomHandlerContainerIt it= m_atomhandler.begin(); | ||
1697 | it != m_atomhandler.end(); it++) | ||
1698 | (*it).first->updateFocusedWindow(*old_screen, 0); | ||
1699 | } | ||
1700 | } | ||
1701 | |||
1702 | void Fluxbox::updateFrameExtents(FluxboxWindow &win) { | 1694 | void Fluxbox::updateFrameExtents(FluxboxWindow &win) { |
1703 | AtomHandlerContainerIt it = m_atomhandler.begin(); | 1695 | AtomHandlerContainerIt it = m_atomhandler.begin(); |
1704 | AtomHandlerContainerIt it_end = m_atomhandler.end(); | 1696 | AtomHandlerContainerIt it_end = m_atomhandler.end(); |
diff --git a/src/fluxbox.hh b/src/fluxbox.hh index 82ff76d..d5a48c6 100644 --- a/src/fluxbox.hh +++ b/src/fluxbox.hh | |||
@@ -162,12 +162,6 @@ public: | |||
162 | /// handle any system signal sent to the application | 162 | /// handle any system signal sent to the application |
163 | void handleSignal(int signum); | 163 | void handleSignal(int signum); |
164 | void update(FbTk::Subject *changed); | 164 | void update(FbTk::Subject *changed); |
165 | /** | ||
166 | * Sends update signal to atomhandlers, | ||
167 | * @param screen the new screen | ||
168 | * @param old_screen the old screen if any, can be the same as new screen | ||
169 | */ | ||
170 | void updateFocusedWindow(BScreen *screen, BScreen *old_screen); | ||
171 | /// todo, remove this. just temporary | 165 | /// todo, remove this. just temporary |
172 | void updateFrameExtents(FluxboxWindow &win); | 166 | void updateFrameExtents(FluxboxWindow &win); |
173 | 167 | ||