diff options
Diffstat (limited to 'src/Screen.cc')
-rw-r--r-- | src/Screen.cc | 189 |
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 | |||
847 | void 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 | |||
844 | FluxboxWindow *BScreen::getIcon(unsigned int index) { | 855 | FluxboxWindow *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 | ||
1514 | void 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 | |||
1431 | void BScreen::initMenu() { | 1523 | void 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 | */ | ||
2157 | void 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 | */ |
2065 | FluxboxWindow* BScreen::useAutoGroupWindow() { | 2170 | FluxboxWindow* BScreen::useAutoGroupWindow() { |