aboutsummaryrefslogtreecommitdiff
path: root/src/Screen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Screen.cc')
-rw-r--r--src/Screen.cc77
1 files changed, 69 insertions, 8 deletions
diff --git a/src/Screen.cc b/src/Screen.cc
index e3b08c6..36b1918 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -360,6 +360,12 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
360 Display *disp = m_root_window.display(); 360 Display *disp = m_root_window.display();
361 Fluxbox *fluxbox = Fluxbox::instance(); 361 Fluxbox *fluxbox = Fluxbox::instance();
362 362
363 // TODO fluxgen: check if this is the right place (it was not -lis)
364 //
365 // Create the first one, initXinerama will expand this if needed.
366 m_head_areas.resize(1);
367 m_head_areas[0] = new HeadArea();
368
363 initXinerama(); 369 initXinerama();
364 370
365 // setup error handler to catch "screen already managed by other wm" 371 // setup error handler to catch "screen already managed by other wm"
@@ -402,9 +408,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
402 XFree(ret_prop); 408 XFree(ret_prop);
403 } 409 }
404 410
405 // TODO fluxgen: check if this is the right place
406 m_head_areas = new HeadArea[numHeads() ? numHeads() : 1];
407
408#ifdef HAVE_RANDR 411#ifdef HAVE_RANDR
409 // setup RANDR for this screens root window 412 // setup RANDR for this screens root window
410 // we need to determine if we should use old randr select input function or not 413 // we need to determine if we should use old randr select input function or not
@@ -600,7 +603,8 @@ BScreen::~BScreen() {
600 m_slit.reset(0); 603 m_slit.reset(0);
601 604
602 // TODO fluxgen: check if this is the right place 605 // TODO fluxgen: check if this is the right place
603 delete [] m_head_areas; 606 for (int i = 0; i < m_head_areas.size(); i++)
607 delete m_head_areas[i];
604 608
605 delete m_focus_control; 609 delete m_focus_control;
606 delete m_placement_strategy; 610 delete m_placement_strategy;
@@ -722,7 +726,12 @@ unsigned int BScreen::currentWorkspaceID() const {
722} 726}
723 727
724const Strut* BScreen::availableWorkspaceArea(int head) const { 728const Strut* BScreen::availableWorkspaceArea(int head) const {
725 return m_head_areas[head ? head-1 : 0].availableWorkspaceArea(); 729 if (head > numHeads()) {
730 /* May this ever happen? */
731 static Strut whole(-1 /* should never be used */, 0, width(), 0, height());
732 return &whole;
733 }
734 return m_head_areas[head ? head-1 : 0]->availableWorkspaceArea();
726} 735}
727 736
728unsigned int BScreen::maxLeft(int head) const { 737unsigned int BScreen::maxLeft(int head) const {
@@ -1412,7 +1421,7 @@ Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom)
1412 1421
1413 Strut* next = 0; 1422 Strut* next = 0;
1414 for (int i = begin; i != end; i++) { 1423 for (int i = begin; i != end; i++) {
1415 next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next); 1424 next = m_head_areas[i]->requestStrut(i+1, left, right, top, bottom, next);
1416 } 1425 }
1417 1426
1418 return next; 1427 return next;
@@ -1422,7 +1431,9 @@ void BScreen::clearStrut(Strut *str) {
1422 if (str->next()) 1431 if (str->next())
1423 clearStrut(str->next()); 1432 clearStrut(str->next());
1424 int head = str->head() ? str->head() - 1 : 0; 1433 int head = str->head() ? str->head() - 1 : 0;
1425 m_head_areas[head].clearStrut(str); 1434 /* The number of heads may have changed, be careful. */
1435 if (head < numHeads())
1436 m_head_areas[head]->clearStrut(str);
1426 // str is invalid now 1437 // str is invalid now
1427} 1438}
1428 1439
@@ -1431,7 +1442,7 @@ void BScreen::updateAvailableWorkspaceArea() {
1431 bool updated = false; 1442 bool updated = false;
1432 1443
1433 for (size_t i = 0; i < n; i++) { 1444 for (size_t i = 0; i < n; i++) {
1434 updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated; 1445 updated = m_head_areas[i]->updateAvailableWorkspaceArea() || updated;
1435 } 1446 }
1436 1447
1437 if (updated) 1448 if (updated)
@@ -1886,6 +1897,9 @@ void BScreen::renderPosWindow() {
1886} 1897}
1887 1898
1888void BScreen::updateSize() { 1899void BScreen::updateSize() {
1900 // update xinerama layout
1901 initXinerama();
1902
1889 // force update geometry 1903 // force update geometry
1890 rootWindow().updateGeometry(); 1904 rootWindow().updateGeometry();
1891 1905
@@ -1895,6 +1909,9 @@ void BScreen::updateSize() {
1895 // send resize notify 1909 // send resize notify
1896 m_resize_sig.notify(); 1910 m_resize_sig.notify();
1897 m_workspace_area_sig.notify(); 1911 m_workspace_area_sig.notify();
1912
1913 // move windows out of inactive heads
1914 clearHeads();
1898} 1915}
1899 1916
1900 1917
@@ -1941,10 +1958,13 @@ void BScreen::initXinerama() {
1941 Display *display = FbTk::App::instance()->display(); 1958 Display *display = FbTk::App::instance()->display();
1942 1959
1943 if (!XineramaIsActive(display)) { 1960 if (!XineramaIsActive(display)) {
1961notactive:
1944#ifdef DEBUG 1962#ifdef DEBUG
1945 cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl; 1963 cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
1946#endif // DEBUG 1964#endif // DEBUG
1947 m_xinerama_avail = false; 1965 m_xinerama_avail = false;
1966 if (m_xinerama_headinfo)
1967 delete [] m_xinerama_headinfo;
1948 m_xinerama_headinfo = 0; 1968 m_xinerama_headinfo = 0;
1949 m_xinerama_num_heads = 0; 1969 m_xinerama_num_heads = 0;
1950 return; 1970 return;
@@ -1957,6 +1977,19 @@ void BScreen::initXinerama() {
1957 XineramaScreenInfo *screen_info; 1977 XineramaScreenInfo *screen_info;
1958 int number; 1978 int number;
1959 screen_info = XineramaQueryScreens(display, &number); 1979 screen_info = XineramaQueryScreens(display, &number);
1980
1981 /* The call may have actually failed. If this is the first time we init
1982 * Xinerama, fall back to turning it off. If not, pretend nothing
1983 * happened -- another event will tell us and it will work then. */
1984 if (!screen_info) {
1985 if (m_xinerama_headinfo)
1986 return;
1987 else
1988 goto notactive;
1989 }
1990
1991 if (m_xinerama_headinfo)
1992 delete [] m_xinerama_headinfo;
1960 m_xinerama_headinfo = new XineramaHeadInfo[number]; 1993 m_xinerama_headinfo = new XineramaHeadInfo[number];
1961 m_xinerama_num_heads = number; 1994 m_xinerama_num_heads = number;
1962 for (int i=0; i < number; i++) { 1995 for (int i=0; i < number; i++) {
@@ -1970,6 +2003,18 @@ void BScreen::initXinerama() {
1970 cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl; 2003 cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
1971#endif // DEBUG 2004#endif // DEBUG
1972 2005
2006 /* Reallocate to the new number of heads. */
2007 int ha_num = numHeads() ? numHeads() : 1, ha_oldnum = m_head_areas.size();
2008 if (ha_num > ha_oldnum) {
2009 m_head_areas.resize(ha_num);
2010 for (int i = ha_oldnum; i < ha_num; i++)
2011 m_head_areas[i] = new HeadArea();
2012 } else if (ha_num < ha_oldnum) {
2013 for (int i = ha_num; i < ha_oldnum; i++)
2014 delete m_head_areas[i];
2015 m_head_areas.resize(ha_num);
2016 }
2017
1973#else // XINERAMA 2018#else // XINERAMA
1974 // no xinerama 2019 // no xinerama
1975 m_xinerama_avail = false; 2020 m_xinerama_avail = false;
@@ -1978,6 +2023,22 @@ void BScreen::initXinerama() {
1978 2023
1979} 2024}
1980 2025
2026/* Move windows out of inactive heads */
2027void BScreen::clearHeads() {
2028 if (!hasXinerama()) return;
2029
2030 for (Workspaces::iterator i = m_workspaces_list.begin();
2031 i != m_workspaces_list.end(); i++) {
2032 for (Workspace::Windows::iterator win = (*i)->windowList().begin();
2033 win != (*i)->windowList().end(); win++) {
2034 if (getHead((*win)->fbWindow()) == 0) {
2035 // first head is a safe bet here
2036 (*win)->placeWindow(1);
2037 }
2038 }
2039 }
2040}
2041
1981int BScreen::getHead(int x, int y) const { 2042int BScreen::getHead(int x, int y) const {
1982 if (!hasXinerama()) return 0; 2043 if (!hasXinerama()) return 0;
1983#ifdef XINERAMA 2044#ifdef XINERAMA