aboutsummaryrefslogtreecommitdiff
path: root/src/Screen.cc
diff options
context:
space:
mode:
authorrathnor <rathnor>2003-04-15 00:50:25 (GMT)
committerrathnor <rathnor>2003-04-15 00:50:25 (GMT)
commit58e19dc91eba51739d4b8ed2dfdbb49e28d96379 (patch)
tree1fbb529d593c1b1b1fabb76832a97783649cab23 /src/Screen.cc
parent1aa5ede1b70dfba6519eeaa38101948bbdfea8a2 (diff)
downloadfluxbox_pavel-58e19dc91eba51739d4b8ed2dfdbb49e28d96379.zip
fluxbox_pavel-58e19dc91eba51739d4b8ed2dfdbb49e28d96379.tar.bz2
add most recently used window cycling (Simon)
It is now the default cycling action
Diffstat (limited to 'src/Screen.cc')
-rw-r--r--src/Screen.cc189
1 files changed, 147 insertions, 42 deletions
diff --git a/src/Screen.cc b/src/Screen.cc
index af703fb..0d374ef 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Screen.cc,v 1.119 2003/04/14 14:49:47 fluxgen Exp $ 25// $Id: Screen.cc,v 1.120 2003/04/15 00:50:24 rathnor Exp $
26 26
27 27
28#include "Screen.hh" 28#include "Screen.hh"
@@ -407,6 +407,7 @@ BScreen::BScreen(ResourceManager &rm,
407 m_workspacenames_sig(*this), // workspace names signal 407 m_workspacenames_sig(*this), // workspace names signal
408 m_currentworkspace_sig(*this), // current workspace signal 408 m_currentworkspace_sig(*this), // current workspace signal
409 m_layermanager(num_layers), 409 m_layermanager(num_layers),
410 cycling_focus(false),
410 theme(0), m_windowtheme(scrn), 411 theme(0), m_windowtheme(scrn),
411 m_menutheme(new FbTk::MenuTheme(scrn)), 412 m_menutheme(new FbTk::MenuTheme(scrn)),
412 resource(rm, screenname, altscreenname), 413 resource(rm, screenname, altscreenname),
@@ -449,6 +450,7 @@ BScreen::BScreen(ResourceManager &rm,
449 (unsigned char *) &bpid, 1); 450 (unsigned char *) &bpid, 1);
450#endif // HAVE_GETPID 451#endif // HAVE_GETPID
451 452
453 cycling_window = focused_list.end();
452 454
453 XDefineCursor(disp, getRootWindow(), fluxbox->getSessionCursor()); 455 XDefineCursor(disp, getRootWindow(), fluxbox->getSessionCursor());
454 456
@@ -841,6 +843,15 @@ void BScreen::removeWindow(FluxboxWindow *win) {
841 (*it)->removeWindow(win); 843 (*it)->removeWindow(win);
842} 844}
843 845
846
847void BScreen::removeClient(WinClient &client) {
848 WinClient *cyc = *cycling_window;
849 focused_list.remove(&client);
850 if (cyc == &client) {
851 cycling_window = focused_list.end();
852 }
853}
854
844FluxboxWindow *BScreen::getIcon(unsigned int index) { 855FluxboxWindow *BScreen::getIcon(unsigned int index) {
845 if (index < iconList.size()) 856 if (index < iconList.size())
846 return iconList[index]; 857 return iconList[index];
@@ -1130,12 +1141,17 @@ FluxboxWindow *BScreen::createWindow(Window client) {
1130 delete win; 1141 delete win;
1131 return 0; 1142 return 0;
1132 } else { 1143 } else {
1144 // always put on end of focused list, if it gets focused it'll get pushed up
1145 // there is only the one win client at this stage
1146 focused_list.push_back(&win->winClient());
1147
1148 //TODO: is next line needed?
1133 Fluxbox::instance()->saveWindowSearch(client, win); 1149 Fluxbox::instance()->saveWindowSearch(client, win);
1134 Fluxbox::instance()->attachSignals(*win); 1150 Fluxbox::instance()->attachSignals(*win);
1135 setupWindowActions(*win); 1151 setupWindowActions(*win);
1136 } 1152 }
1137 if (win->getWorkspaceNumber() == getCurrentWorkspaceID() || win->isStuck()) { 1153 if (win->getWorkspaceNumber() == getCurrentWorkspaceID() || win->isStuck()) {
1138 win->show(); 1154 win->show();
1139 } 1155 }
1140 XSync(FbTk::App::instance()->display(), False); 1156 XSync(FbTk::App::instance()->display(), False);
1141 return win; 1157 return win;
@@ -1153,6 +1169,9 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) {
1153 delete win; 1169 delete win;
1154 return 0; 1170 return 0;
1155 } 1171 }
1172 // don't add to focused_list, as it should already be in there (since the
1173 // WinClient already exists).
1174
1156 Fluxbox::instance()->saveWindowSearch(client.window(), win); 1175 Fluxbox::instance()->saveWindowSearch(client.window(), win);
1157 Fluxbox::instance()->attachSignals(*win); 1176 Fluxbox::instance()->attachSignals(*win);
1158 setupWindowActions(*win); 1177 setupWindowActions(*win);
@@ -1343,27 +1362,58 @@ void BScreen::nextFocus(int opts) {
1343 } 1362 }
1344 1363
1345 if (num_windows >= 1) { 1364 if (num_windows >= 1) {
1346 Workspace *wksp = getCurrentWorkspace(); 1365 if (!(opts & CYCLELINEAR)) {
1347 Workspace::Windows &wins = wksp->getWindowList(); 1366 if (!cycling_focus) {
1348 Workspace::Windows::iterator it = wins.begin(); 1367 cycling_focus = True;
1368 cycling_window = focused_list.begin();
1369 }
1370 // if it is stacked, we want the highest window in the focused list
1371 // that is on the same workspace
1372 FocusedWindows::iterator it = cycling_window;
1373 FocusedWindows::iterator it_end = focused_list.end();
1374
1375 while (true) {
1376 ++it;
1377 if (it == it_end) {
1378 it = focused_list.begin();
1379 }
1380 // give up [do nothing] if we reach the current focused again
1381 if ((*it) == (*cycling_window)) {
1382 break;
1383 }
1349 1384
1350 if (!have_focused) { 1385 FluxboxWindow *fbwin = (*it)->m_win;
1351 focused = (*it); 1386 if (fbwin && !fbwin->isIconic() &&
1352 } else { 1387 (fbwin->isStuck()
1353 for (; (*it) != focused; ++it) //get focused window iterator 1388 || fbwin->getWorkspaceNumber() == getCurrentWorkspaceID())) {
1354 continue; 1389 // either on this workspace, or stuck
1390 if (! (doSkipWindow(fbwin, opts) || !fbwin->setInputFocus()) )
1391 break;
1392 }
1393 }
1394 cycling_window = it;
1395 } else { // not stacked cycling
1396 Workspace *wksp = getCurrentWorkspace();
1397 Workspace::Windows &wins = wksp->getWindowList();
1398 Workspace::Windows::iterator it = wins.begin();
1399
1400 if (!have_focused) {
1401 focused = (*it);
1402 } else {
1403 for (; (*it) != focused; ++it) //get focused window iterator
1404 continue;
1405 }
1406 do {
1407 ++it;
1408 if (it == wins.end())
1409 it = wins.begin();
1410 // see if the window should be skipped
1411 if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
1412 break;
1413 } while ((*it) != focused);
1414 if ((*it) != focused && it != wins.end())
1415 (*it)->raise();
1355 } 1416 }
1356 do {
1357 ++it;
1358 if (it == wins.end())
1359 it = wins.begin();
1360 // see if the window should be skipped
1361 if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
1362 break;
1363 } while ((*it) != focused);
1364
1365 if ((*it) != focused && it != wins.end())
1366 (*it)->raise();
1367 1417
1368 } 1418 }
1369 1419
@@ -1385,29 +1435,62 @@ void BScreen::prevFocus(int opts) {
1385 } 1435 }
1386 1436
1387 if (num_windows >= 1) { 1437 if (num_windows >= 1) {
1388 Workspace *wksp = getCurrentWorkspace(); 1438 if (!(opts & CYCLELINEAR)) {
1389 Workspace::Windows &wins = wksp->getWindowList(); 1439 if (!cycling_focus) {
1390 Workspace::Windows::iterator it = wins.begin(); 1440 cycling_focus = True;
1441 cycling_window = focused_list.end();
1442 }
1443 // if it is stacked, we want the highest window in the focused list
1444 // that is on the same workspace
1445 FocusedWindows::iterator it = cycling_window;
1446 FocusedWindows::iterator it_end = focused_list.end();
1447
1448 while (true) {
1449 --it;
1450 if (it == it_end) {
1451 it = focused_list.end();
1452 --it;
1453 }
1454 // give up [do nothing] if we reach the current focused again
1455 if ((*it) == (*cycling_window)) {
1456 break;
1457 }
1391 1458
1392 if (!have_focused) { 1459 FluxboxWindow *fbwin = (*it)->m_win;
1393 focused = (*it); 1460 if (fbwin && !fbwin->isIconic() &&
1394 } else { 1461 (fbwin->isStuck()
1395 for (; (*it) != focused; ++it) //get focused window iterator 1462 || fbwin->getWorkspaceNumber() == getCurrentWorkspaceID())) {
1396 continue; 1463 // either on this workspace, or stuck
1464 if (! (doSkipWindow(fbwin, opts) || !fbwin->setInputFocus()) )
1465 break;
1466 }
1467 }
1468 cycling_window = it;
1469 } else { // not stacked cycling
1470
1471 Workspace *wksp = getCurrentWorkspace();
1472 Workspace::Windows &wins = wksp->getWindowList();
1473 Workspace::Windows::iterator it = wins.begin();
1474
1475 if (!have_focused) {
1476 focused = (*it);
1477 } else {
1478 for (; (*it) != focused; ++it) //get focused window iterator
1479 continue;
1480 }
1481
1482 do {
1483 if (it == wins.begin())
1484 it = wins.end();
1485 --it;
1486 // see if the window should be skipped
1487 if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
1488 break;
1489 } while ((*it) != focused);
1490
1491 if ((*it) != focused && it != wins.end())
1492 (*it)->raise();
1397 } 1493 }
1398
1399 do {
1400 if (it == wins.begin())
1401 it = wins.end();
1402 --it;
1403 // see if the window should be skipped
1404 if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
1405 break;
1406 } while ((*it) != focused);
1407
1408 if ((*it) != focused && it != wins.end())
1409 (*it)->raise();
1410
1411 } 1494 }
1412} 1495}
1413 1496
@@ -1428,6 +1511,15 @@ void BScreen::raiseFocus() {
1428 fb->getFocusedWindow()->raise(); 1511 fb->getFocusedWindow()->raise();
1429} 1512}
1430 1513
1514void BScreen::setFocusedWindow(WinClient &winclient) {
1515 // raise newly focused window to the top of the focused list
1516 if (!cycling_focus) { // don't change the order if we're cycling
1517 focused_list.remove(&winclient);
1518 focused_list.push_front(&winclient);
1519 cycling_window = focused_list.begin();
1520 }
1521}
1522
1431void BScreen::initMenu() { 1523void BScreen::initMenu() {
1432 I18n *i18n = I18n::instance(); 1524 I18n *i18n = I18n::instance();
1433 1525
@@ -2060,6 +2152,19 @@ bool BScreen::doSkipWindow(const FluxboxWindow *w, int opts) {
2060} 2152}
2061 2153
2062/** 2154/**
2155 Called when a set of watched modifiers has been released
2156*/
2157void BScreen::notifyReleasedKeys(XKeyEvent &ke) {
2158 if (cycling_focus) {
2159 cycling_focus = false;
2160 // put currently focused window to top
2161 WinClient *client = *cycling_window;
2162 focused_list.erase(cycling_window);
2163 focused_list.push_front(client);
2164 }
2165}
2166
2167/**
2063 Access and clear the auto-group window 2168 Access and clear the auto-group window
2064*/ 2169*/
2065FluxboxWindow* BScreen::useAutoGroupWindow() { 2170FluxboxWindow* BScreen::useAutoGroupWindow() {