From 95aeda26271cce3061a46a3ca0b122bc13c8f5c8 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Tue, 19 Mar 2002 14:30:43 +0000 Subject: Xinerama support --- src/BaseDisplay.cc | 203 ++++++++++++++++++++++++++++++++++++++- src/BaseDisplay.hh | 25 ++++- src/Basemenu.cc | 82 +++++++++++++++- src/Screen.cc | 36 ++++++- src/Screen.hh | 23 ++++- src/Slit.cc | 140 +++++++++++++++++++++------ src/Slit.hh | 26 ++++- src/Toolbar.cc | 152 +++++++++++++++++++++++++----- src/Toolbar.hh | 217 +++++++++++++++++++++++------------------- src/Window.cc | 144 +++++++++++++++++++++++----- src/Workspace.cc | 271 +++++++++++++++++++++++++++++++++++++++++++---------- src/fluxbox.cc | 24 ++++- 12 files changed, 1100 insertions(+), 243 deletions(-) diff --git a/src/BaseDisplay.cc b/src/BaseDisplay.cc index 6bcbd5e..e540136 100644 --- a/src/BaseDisplay.cc +++ b/src/BaseDisplay.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: BaseDisplay.cc,v 1.8 2002/03/18 23:41:08 fluxgen Exp $ +// $Id: BaseDisplay.cc,v 1.9 2002/03/19 14:30:42 fluxgen Exp $ // use GNU extensions #ifndef _GNU_SOURCE @@ -423,4 +423,205 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, int num) { visual = DefaultVisual(basedisplay->getXDisplay(), screen_number); colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number); } + +#ifdef XINERAMA + // check if we have Xinerama extension enabled + if (XineramaIsActive(basedisplay->getXDisplay())) { + m_hasXinerama = true; + xineramaLastHead = 0; // initialize this + xineramaInfos = + XineramaQueryScreens(basedisplay->getXDisplay(), &xineramaNumHeads); + } else { + m_hasXinerama = false; + xineramaInfos = 0; // make sure we don't point anywhere we shouldn't + } +#endif // XINERAMA } + +ScreenInfo::~ScreenInfo(void) { +#ifdef XINERAMA + if (m_hasXinerama) { // only free if we first had it + XFree(xineramaInfos); + xineramaInfos = 0; + } +#endif // XINERAMA +} + +#ifdef XINERAMA + +//---------------- getHead --------------- +// Searches for the head at the coordinates +// x,y. If it fails or Xinerama isn't +// activated it'll return head nr 0 +//----------------------------------------- +unsigned int ScreenInfo::getHead(int x, int y) { + unsigned int head = 0; + + // is Xinerama extensions enabled? + if (hasXinerama()) { + // check if last head is still active + if ((xineramaInfos[xineramaLastHead].x_org <= x) && + ((xineramaInfos[xineramaLastHead].x_org + + xineramaInfos[xineramaLastHead].width) > x) && + (xineramaInfos[xineramaLastHead].y_org <= y) && + ((xineramaInfos[xineramaLastHead].y_org + + xineramaInfos[xineramaLastHead].height) > y)) { + head = xineramaLastHead; + + } else { + // go trough all the heads, and search + for (int i = 0; (signed) head < xineramaNumHeads; i++) { + if ((xineramaInfos[i].x_org <= x) && + ((xineramaInfos[i].x_org + xineramaInfos[i].width) > x) && + (xineramaInfos[i].y_org <= y) && + ((xineramaInfos[i].y_org + xineramaInfos[i].height) > y)) { + // TODO: actually set this to last head? + head = xineramaLastHead = i; + + break; // we don't wanna spend CPU searching what we + } // allready have found, do we? + } + } + } + + return head; +} + +//------------- getCurrHead -------------- +// Searches for the head that the pointer +// currently is on, if it isn't found +// the first one is returned +//---------------------------------------- +unsigned int ScreenInfo::getCurrHead(void) { + unsigned int head = 0; + + // is Xinerama extensions enabled? + if (hasXinerama()) { + int pX, pY, wX, wY; + unsigned int mask; + Window rRoot, rChild; + + // check if last head is still active + if ((xineramaInfos[xineramaLastHead].x_org <= pX) && + ((xineramaInfos[xineramaLastHead].x_org + + xineramaInfos[xineramaLastHead].width) > pX) && + (xineramaInfos[xineramaLastHead].y_org <= pY) && + ((xineramaInfos[xineramaLastHead].y_org + + xineramaInfos[xineramaLastHead].height) > pY)) { + head = xineramaLastHead; + + } else { + // get pointer cordinates , we need to know were we are! + if ( (XQueryPointer(basedisplay->getXDisplay(), root_window, + &rRoot, &rChild, &pX, &pY, &wX, &wY, &mask)) != 0 ) { + + // go trough all the heads, and search + for (int i = 0; i < xineramaNumHeads; i++) { + if ((xineramaInfos[i].x_org <= pX) && + ((xineramaInfos[i].x_org + xineramaInfos[i].width) > pX) && + (xineramaInfos[i].y_org <= pY) && + ((xineramaInfos[i].y_org + xineramaInfos[i].height) > pY)) { + + head = xineramaLastHead = i; + break; // we don't wanna spend CPU searching what we + } // allready have found, do we? + } + } + } + } + + return head; +} + +//----------- getHeadWidth ------------ +// Returns the width of head nr head +//------------------------------------- +unsigned int ScreenInfo::getHeadWidth(unsigned int head) { + unsigned int width; + + if (hasXinerama()) { + if ((signed) head >= xineramaNumHeads) { + #ifdef DEBUG + cerr << __FILE__ << ":" <<__LINE__ << ": " << + "Head: " << head << " doesn't exist!" << endl; + #endif // DEBUG + + head = xineramaNumHeads - 1; + } + + width = xineramaInfos[head].width; + } else { + width = getWidth(); + } + + return width; +} + +//----------- getHeadHeight ------------ +// Returns the heigt of head nr head +//-------------------------------------- +unsigned int ScreenInfo::getHeadHeight(unsigned int head) { + unsigned int height; + + if (hasXinerama()) { + if ((signed) head >= xineramaNumHeads) { + #ifdef DEBUG + cerr << __FILE__ << ":" <<__LINE__ << ": " << + "Head: " << head << " doesn't exist!" << endl; + #endif // DEBUG + + head = xineramaNumHeads - 1; + } + + height = xineramaInfos[head].height; + } else { + height = getHeight(); + } + + return height; +} + + +//----------- getHeadX ----------------- +// Returns the X start of head nr head +//-------------------------------------- +int ScreenInfo::getHeadX(unsigned int head) { + int x = 0; + + if (hasXinerama()) { + if ((signed) head >= xineramaNumHeads) { + #ifdef DEBUG + cerr << __FILE__ << ":" <<__LINE__ << ": " << + "Head: " << head << " doesn't exist!" << endl; + #endif // DEBUG + + head = xineramaNumHeads - 1; + } + x = xineramaInfos[head].x_org; + } + + return x; +} + +//----------- getHeadY ----------------- +// Returns the Y start of head nr head +//-------------------------------------- +int ScreenInfo::getHeadY(unsigned int head) { + int y = 0; + + if (hasXinerama()) { + if ((signed) head >= xineramaNumHeads) { + #ifdef DEBUG + cerr << __FILE__ << ":" <<__LINE__ << ": " << + "Head: " << head << " doesn't exist!" << endl; + #endif // DEBUG + + head = xineramaNumHeads - 1; + } + y = xineramaInfos[head].y_org; + } + + return y; +} + +#endif // XINERAMA diff --git a/src/BaseDisplay.hh b/src/BaseDisplay.hh index ffc2b8d..3cf8d40 100644 --- a/src/BaseDisplay.hh +++ b/src/BaseDisplay.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: BaseDisplay.hh,v 1.15 2002/03/18 23:39:53 fluxgen Exp $ +// $Id: BaseDisplay.hh,v 1.16 2002/03/19 14:30:42 fluxgen Exp $ #ifndef BASEDISPLAY_HH #define BASEDISPLAY_HH @@ -31,6 +31,12 @@ #include "FbAtoms.hh" #include +#ifdef XINERAMA + extern "C" { + #include + } +#endif // XINERAMA + #include #include @@ -145,6 +151,7 @@ protected: class ScreenInfo { public: ScreenInfo(BaseDisplay *, int); + ~ScreenInfo(void); inline BaseDisplay *getBaseDisplay(void) { return basedisplay; } @@ -158,6 +165,17 @@ public: inline const unsigned int getWidth(void) const { return width; } inline const unsigned int getHeight(void) const { return height; } +#ifdef XINERAMA + inline bool hasXinerama(void) { return m_hasXinerama; } + inline int getNumHeads(void) { return xineramaNumHeads; } + unsigned int getHead(int x, int y); + unsigned int getCurrHead(void); + unsigned int getHeadWidth(unsigned int head); + unsigned int getHeadHeight(unsigned int head); + int getHeadX(unsigned int head); + int getHeadY(unsigned int head); +#endif // XINERAMA + private: BaseDisplay *basedisplay; Visual *visual; @@ -169,5 +187,10 @@ private: }; +#ifdef XINERAMA + bool m_hasXinerama; + int xineramaMajor, xineramaMinor, xineramaNumHeads, xineramaLastHead; + XineramaScreenInfo *xineramaInfos; +#endif // XINERAMA #endif // BASEDISPLAY_HH diff --git a/src/Basemenu.cc b/src/Basemenu.cc index 5328a2b..713b2f7 100644 --- a/src/Basemenu.cc +++ b/src/Basemenu.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Basemenu.cc,v 1.11 2002/03/18 15:42:34 fluxgen Exp $ +// $Id: Basemenu.cc,v 1.12 2002/03/19 14:30:42 fluxgen Exp $ // stupid macros needed to access some functions in version 2 of the GNU C // library @@ -580,21 +580,59 @@ void Basemenu::drawSubmenu(int index) { y = (((shifted) ? menu.y_shift : menu.y) + menu.height - item->submenu()->menu.height); } + + #ifdef XINERAMA + int head_x = 0, + head_y = 0, + head_w, + head_h; + + unsigned int head = 0; + if (screen->hasXinerama()) { + head = screen->getHead(menu.x, menu.y); + head_x = screen->getHeadX(head); + head_y = screen->getHeadY(head); + head_w = screen->getHeadWidth(head); + head_h = screen->getHeadHeight(head); + } else { + head_w = screen->getWidth(); + head_h = screen->getHeight(); + } + + if ((x + item->submenu()->getWidth()) > (head_x + head_w)) { + x = ((shifted) ? menu.x_shift : menu.x) - + item->submenu()->getWidth() - screen->getBorderWidth(); + } + if (x < head_x) + x = head_x; + + if ((y + item->submenu()->getHeight()) > (head_y + head_h)) { + y = head_y + head_h - + item->submenu()->getHeight() - screen->getBorderWidth2x(); + } + + if (y < head_y) + y = head_y; + #else // !XINERAMA + if ((x + item->submenu()->getWidth()) > screen->getWidth()) { x = ((shifted) ? menu.x_shift : menu.x) - item->submenu()->getWidth() - screen->getBorderWidth(); } - if (x < 0) x = 0; + if (x < 0) + x = 0; if ((y + item->submenu()->getHeight()) > screen->getHeight()) { y = screen->getHeight() - item->submenu()->getHeight() - screen->getBorderWidth2x(); } - if (y < 0) y = 0; - + if (y < 0) + y = 0; + #endif // XINERAMA + item->submenu()->move(x, y); if (! moving) drawItem(index, True); @@ -1007,6 +1045,33 @@ void Basemenu::exposeEvent(XExposeEvent *ee) { void Basemenu::enterNotifyEvent(XCrossingEvent *ce) { +#ifdef XINERAMA + int head = screen->hasXinerama() ? screen->getCurrHead() : 0; + + if (ce->window == menu.frame) { + menu.x_shift = menu.x, menu.y_shift = menu.y; + if (menu.x + menu.width > + (screen->getHeadX(head) + screen->getHeadWidth(head))) { + menu.x_shift = screen->getHeadX(head) + screen->getHeadWidth(head) - + menu.width - screen->getBorderWidth2x(); + shifted = True; + } else if (menu.x < screen->getHeadX(head)) { + menu.x_shift = screen->getHeadX(head); + shifted = True; + } + + if (menu.y + menu.height > + (screen->getHeadY(head) + screen->getHeadHeight(head))) { + menu.y_shift = screen->getHeadY(head) + screen->getHeadHeight(head) - + menu.height - screen->getBorderWidth2x(); + shifted = True; + } else if (menu.y + (signed) menu.title_h < screen->getHeadY(head)) { + menu.y_shift = screen->getHeadY(head); + shifted = True; + } + +#else // !XINERAMA + if (ce->window == menu.frame) { menu.x_shift = menu.x, menu.y_shift = menu.y; if (menu.x + menu.width > screen->getWidth()) { @@ -1027,8 +1092,15 @@ void Basemenu::enterNotifyEvent(XCrossingEvent *ce) { shifted = True; } - if (shifted) +#endif // XINERAMA + + if (shifted) { + #ifdef XINERAMA + menu.x = menu.x_shift; // need to do this to avoid jumping beetween heads + menu.y = menu.y_shift; + #endif // XINERAMA XMoveWindow(display, menu.window, menu.x_shift, menu.y_shift); + } if (which_sub >= 0) { BasemenuItem *tmp = menuitems[which_sub]; diff --git a/src/Screen.cc b/src/Screen.cc index 7209cdc..3c7f4a9 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.36 2002/03/19 00:05:49 fluxgen Exp $ +// $Id: Screen.cc,v 1.37 2002/03/19 14:30:42 fluxgen Exp $ //use GNU extensions #ifndef _GNU_SOURCE @@ -215,6 +215,9 @@ tab_width(rm, 64, scrname+".tab.width", altscrname+".Tab.Width"), tab_height(rm, 16, scrname+".tab.height", altscrname+".Tab.Height"), tab_placement(rm, Tab::PTOP, scrname+".tab.placement", altscrname+".Tab.Placement"), tab_alignment(rm, Tab::ALEFT, scrname+".tab.alignment", altscrname+".Tab.Alignment"), +#ifdef XINERAMA +toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"), +#endif // XINERAMA toolbar_placement(rm, Toolbar::BOTTOMCENTER, scrname+".toolbar.placement", altscrname+".Toolbar.Placement") { @@ -1025,11 +1028,21 @@ void BScreen::raiseWindows(Window *workspace_stack, int num) { #ifdef SLIT session_stack[i++] = slit->getMenu().getDirectionmenu()->getWindowID(); session_stack[i++] = slit->getMenu().getPlacementmenu()->getWindowID(); + #ifdef XINERAMA + if (hasXinerama()) { + session_stack[i++] = slit->getMenu().getHeadmenu()->getWindowID(); + } + #endif // XINERAMA session_stack[i++] = slit->getMenu().getWindowID(); #endif // SLIT session_stack[i++] = toolbar->getMenu()->getPlacementmenu()->getWindowID(); + #ifdef XINERAMA + if (hasXinerama()) { + session_stack[i++] = toolbar->getMenu()->getHeadmenu()->getWindowID(); + } + #endif // XINERAMA session_stack[i++] = toolbar->getMenu()->getWindowID(); Rootmenus::iterator rit = rootmenuList.begin(); @@ -1667,9 +1680,18 @@ void BScreen::shutdown(void) { void BScreen::showPosition(int x, int y) { if (! geom_visible) { +#ifdef XINERAMA + unsigned int head = hasXinerama() ? getCurrHead() : 0; + + XMoveResizeWindow(getBaseDisplay()->getXDisplay(), geom_window, + getHeadX(head) + (getHeadWidth(head) - geom_w) / 2, + getHeadY(head) + (getHeadHeight(head) - geom_h) / 2, geom_w, geom_h); +#else // !XINERMA XMoveResizeWindow(getBaseDisplay()->getXDisplay(), geom_window, (getWidth() - geom_w) / 2, (getHeight() - geom_h) / 2, geom_w, geom_h); +#endif // XINERAMA + XMapWindow(getBaseDisplay()->getXDisplay(), geom_window); XRaiseWindow(getBaseDisplay()->getXDisplay(), geom_window); @@ -1707,9 +1729,17 @@ void BScreen::showPosition(int x, int y) { void BScreen::showGeometry(unsigned int gx, unsigned int gy) { if (! geom_visible) { +#ifdef XINERAMA + unsigned int head = hasXinerama() ? getCurrHead() : 0; + + XMoveResizeWindow(getBaseDisplay()->getXDisplay(), geom_window, + getHeadX(head) + (getHeadWidth(head) - geom_w) / 2, + getHeadY(head) + (getHeadHeight(head) - geom_h) / 2, geom_w, geom_h); +#else // !XINERMA XMoveResizeWindow(getBaseDisplay()->getXDisplay(), geom_window, - (getWidth() - geom_w) / 2, - (getHeight() - geom_h) / 2, geom_w, geom_h); + (getWidth() - geom_w) / 2, + (getHeight() - geom_h) / 2, geom_w, geom_h); +#endif // XINERAMA XMapWindow(getBaseDisplay()->getXDisplay(), geom_window); XRaiseWindow(getBaseDisplay()->getXDisplay(), geom_window); diff --git a/src/Screen.hh b/src/Screen.hh index ffb5df4..5201eb7 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.23 2002/03/18 20:20:09 fluxgen Exp $ +// $Id: Screen.hh,v 1.24 2002/03/19 14:30:42 fluxgen Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -102,6 +102,11 @@ public: inline void saveSlitDirection(int d) { resource.slit_direction = d; } inline void saveSlitOnTop(Bool t) { resource.slit_on_top = t; } inline void saveSlitAutoHide(Bool t) { resource.slit_auto_hide = t; } +#ifdef XINERAMA + inline const unsigned int getSlitOnHead(void) const { return resource.slit_on_head; } + inline void saveSlitOnHead(unsigned int h) { resource.slit_on_head = h; } +#endif // XINERAMA + #endif // SLIT inline Toolbar *getToolbar(void) { return toolbar; } @@ -125,6 +130,9 @@ public: inline const int getNumberOfWorkspaces(void) { return *resource.workspaces; } inline const Toolbar::Placement getToolbarPlacement(void) { return *resource.toolbar_placement; } +#ifdef XINERAMA + inline const int getToolbarOnHead(void) { return *resource.toolbar_on_head; } +#endif // XINERAMA inline const int getToolbarWidthPercent(void) { return *resource.toolbar_width_percent; } inline const int getPlacementPolicy(void) const { return resource.placement_policy; } inline const int getEdgeSnapThreshold(void) { return *resource.edge_snap_threshold; } @@ -145,6 +153,10 @@ public: inline void saveToolbarAutoHide(bool r) { *resource.toolbar_auto_hide = r; } inline void saveToolbarWidthPercent(int w) { *resource.toolbar_width_percent = w; } inline void saveToolbarPlacement(Toolbar::Placement p) { *resource.toolbar_placement = p; } +#ifdef XINERAMA + inline void saveToolbarOnHead(int head) { *resource.toolbar_on_head = head; } +#endif // XINERAMA + inline void savePlacementPolicy(int p) { resource.placement_policy = p; } inline void saveRowPlacementDirection(int d) { resource.row_direction = d; } inline void saveColPlacementDirection(int d) { resource.col_direction = d; } @@ -294,12 +306,21 @@ private: Resource tab_placement; Resource tab_alignment; + #ifdef XINERAMA + Resource toolbar_on_head; + #endif // XINERAMA + Resource toolbar_placement; #ifdef SLIT Bool slit_on_top, slit_auto_hide; int slit_placement, slit_direction; + + #ifdef XINERAMA + unsigned int slit_on_head; + #endif // XINERAMA + #endif // SLIT diff --git a/src/Slit.cc b/src/Slit.cc index ef16c2f..c33d2e0 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -404,93 +404,114 @@ void Slit::reconfigure(void) { void Slit::reposition(void) { + int head_x = 0, + head_y = 0, + head_w, + head_h; +#ifdef XINERMA + if (screen->hasXinerama()) { + unsigned int head = screen->getSlitOnHead(); + + head_x = screen->getHeadX(head); + head_y = screen->getHeadY(head); + head_w = screen->getHeadWidth(head); + head_h = screen->getHeadHeight(head); + } else { + head_w = screen->getWidth(); + head_h = screen->getHeight(); + } +#else // !XINERAMA + head_w = screen->getWidth(); + head_h = screen->getHeight(); +#endif // XINERAMA + // place the slit in the appropriate place switch (screen->getSlitPlacement()) { case TOPLEFT: - frame.x = 0; - frame.y = 0; + frame.x = head_x; + frame.y = head_y; if (screen->getSlitDirection() == VERTICAL) { frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth() - frame.width; - frame.y_hidden = 0; + frame.y_hidden = head_y; } else { - frame.x_hidden = 0; + frame.x_hidden = head_x; frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth() - frame.height; } break; case CENTERLEFT: - frame.x = 0; - frame.y = (screen->getHeight() - frame.height) / 2; - frame.x_hidden = screen->getBevelWidth() - + frame.x = head_x; + frame.y = head_y + (head_h - frame.height) / 2; + frame.x_hidden = head_x + screen->getBevelWidth() - screen->getBorderWidth() - frame.width; frame.y_hidden = frame.y; break; case BOTTOMLEFT: - frame.x = 0; - frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x(); + frame.x = head_x; + frame.y = head_h - frame.height - screen->getBorderWidth2x(); if (screen->getSlitDirection() == VERTICAL) { - frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth() - - frame.width; + frame.x_hidden = head_x + screen->getBevelWidth() - + screen->getBorderWidth() - frame.width; frame.y_hidden = frame.y; } else { - frame.x_hidden = 0; - frame.y_hidden = screen->getHeight() - + frame.x_hidden = head_x; + frame.y_hidden = head_y + head_h - screen->getBevelWidth() - screen->getBorderWidth(); } break; case TOPCENTER: - frame.x = (screen->getWidth() - frame.width) / 2; - frame.y = 0; + frame.x = head_x + ((head_w - frame.width) / 2); + frame.y = head_y; frame.x_hidden = frame.x; - frame.y_hidden = screen->getBevelWidth() - + frame.y_hidden = head_y + screen->getBevelWidth() - screen->getBorderWidth() - frame.height; break; case BOTTOMCENTER: - frame.x = (screen->getWidth() - frame.width) / 2; - frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x(); + frame.x = head_x + ((head_w - frame.width) / 2); + frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x(); frame.x_hidden = frame.x; - frame.y_hidden = screen->getHeight() - + frame.y_hidden = head_y + head_h - screen->getBevelWidth() - screen->getBorderWidth(); break; case TOPRIGHT: - frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x(); - frame.y = 0; + frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x(); + frame.y = head_y; if (screen->getSlitDirection() == VERTICAL) { - frame.x_hidden = screen->getWidth() - + frame.x_hidden = head_x + head_w - screen->getBevelWidth() - screen->getBorderWidth(); - frame.y_hidden = 0; + frame.y_hidden = head_y; } else { frame.x_hidden = frame.x; - frame.y_hidden = screen->getBevelWidth() - + frame.y_hidden = head_y + screen->getBevelWidth() - screen->getBorderWidth() - frame.height; } break; case CENTERRIGHT: default: - frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x(); - frame.y = (screen->getHeight() - frame.height) / 2; - frame.x_hidden = screen->getWidth() - + frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x(); + frame.y = head_y + ((head_h - frame.height) / 2); + frame.x_hidden = head_x + head_w - screen->getBevelWidth() - screen->getBorderWidth(); frame.y_hidden = frame.y; break; case BOTTOMRIGHT: - frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x(); - frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x(); + frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x(); + frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x(); if (screen->getSlitDirection() == VERTICAL) { - frame.x_hidden = screen->getWidth() - + frame.x_hidden = head_x + head_w - screen->getBevelWidth() - screen->getBorderWidth(); frame.y_hidden = frame.y; } else { frame.x_hidden = frame.x; - frame.y_hidden = screen->getHeight() - + frame.y_hidden = head_y + head_h - screen->getBevelWidth() - screen->getBorderWidth(); } break; @@ -654,6 +675,11 @@ Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) { directionmenu = new Directionmenu(this); placementmenu = new Placementmenu(this); +#ifdef XINERAMA + if (slit->screen->hasXinerama()) { // only create if we need + headmenu = new Headmenu(this); + } +#endif // XINERAMA insert(i18n->getMessage( #ifdef NLS @@ -671,6 +697,14 @@ Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) { #endif // NLS "Placement"), placementmenu); + +#ifdef XINERAMA + //TODO: NLS + if (slit->screen->hasXinerama()) { + insert(i18n->getMessage(0, 0, "Place on Head"), headmenu); + } +#endif // XINERAMA + insert(i18n->getMessage( #ifdef NLS CommonSet, CommonAlwaysOnTop, @@ -696,6 +730,11 @@ Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) { Slitmenu::~Slitmenu(void) { delete directionmenu; delete placementmenu; +#ifdef XINERAMA + if (slit->screen->hasXinerama()) { + delete headmenu; + } +#endif // XINERAMA } @@ -738,6 +777,11 @@ void Slitmenu::internal_hide(void) { void Slitmenu::reconfigure(void) { directionmenu->reconfigure(); placementmenu->reconfigure(); +#ifdef XINERAMA + if (slit->screen->hasXinerama()) { + headmenu->reconfigure(); + } +#endif // XINERAMA Basemenu::reconfigure(); } @@ -900,5 +944,39 @@ void Slitmenu::Placementmenu::itemSelected(int button, int index) { } } +#ifdef XINERAMA + +Slitmenu::Headmenu::Headmenu(Slitmenu *sm) + : Basemenu(sm->slit->screen) { + slitmenu = sm; + I18n *i18n = I18n::instance(); + + setLabel(i18n->getMessage(0, 0, "Place on Head")); //TODO: NLS + setInternalMenu(); + + int numHeads = slitmenu->slit->screen->getNumHeads(); + // fill menu with head entries + for (int i = 0; i < numHeads; i++) { + char headName[32]; + sprintf(headName, "Head %i", i+1); //TODO: NLS + insert(i18n->getMessage(0, 0, headName), i); + } + + update(); +} + +void Slitmenu::Headmenu::itemSelected(int button, int index) { + if (button == 1) { + BasemenuItem *item = find(index); + if (! item) + return; + + slitmenu->slit->screen->saveSlitOnHead(item->function()); + hide(); + slitmenu->slit->reconfigure(); + } +} + +#endif // XINERAMA #endif // SLIT diff --git a/src/Slit.hh b/src/Slit.hh index d07cfe0..d3ee5b7 100644 --- a/src/Slit.hh +++ b/src/Slit.hh @@ -60,13 +60,31 @@ private: Placementmenu(Slitmenu *); }; +#ifdef XINERAMA + class Headmenu : public Basemenu { + public: + Headmenu(Slitmenu *); + private: + Slitmenu *slitmenu; + + protected: + virtual void itemSelected(int, int); + + }; +#endif // XINERAMA + Directionmenu *directionmenu; Placementmenu *placementmenu; - +#ifdef XINERAMA + Headmenu *headmenu; +#endif // XINERAMA Slit *slit; friend class Directionmenu; friend class Placementmenu; +#ifdef XINERAMA + friend class Headmenu; +#endif // XINERAMA friend class Slit; @@ -81,6 +99,9 @@ public: inline Basemenu *getDirectionmenu(void) { return directionmenu; } inline Basemenu *getPlacementmenu(void) { return placementmenu; } +#ifdef XINERAMA + inline Basemenu *getHeadmenu(void) { return headmenu; } +#endif // XINERAMA void reconfigure(void); }; @@ -158,6 +179,9 @@ private: friend class Slitmenu; friend class Slitmenu::Directionmenu; friend class Slitmenu::Placementmenu; + #ifdef XINERAMA + friend class Slitmenu::Headmenu; + #endif // XINERAMA }; diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 9cf2752..3b9b652 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -1,3 +1,6 @@ +// Toolbar.cc for Fluxbox +// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org) +// // Toolbar.cc for Blackbox - an X11 Window manager // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) // @@ -13,13 +16,13 @@ // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Toolbar.cc,v 1.13 2002/03/19 00:12:36 fluxgen Exp $ +// $Id: Toolbar.cc,v 1.14 2002/03/19 14:30:42 fluxgen Exp $ // stupid macros needed to access some functions in version 2 of the GNU C // library @@ -215,9 +218,38 @@ void Toolbar::delIcon(FluxboxWindow *w) { } void Toolbar::reconfigure(void) { + int head_x = 0, + head_y = 0, + head_w, + head_h; + frame.bevel_w = screen->getBevelWidth(); +#ifdef XINERAMA + int head = (screen->hasXinerama()) + ? screen->getToolbarOnHead() + : -1; + + if (head >= 0) { // toolbar on head nr, if -1 then over ALL heads + head_x = screen->getHeadX(head); + head_y = screen->getHeadY(head); + head_w = screen->getHeadWidth(head); + head_h = screen->getHeadHeight(head); + + frame.width = + (screen->getHeadWidth(head) * screen->getToolbarWidthPercent() / 100); + } else { + head_w = screen->getHeadWidth(head); + head_h = screen->getHeadHeight(head); + + frame.width = screen->getWidth() * screen->getToolbarWidthPercent() / 100; + } +#else // !XINERAMA + head_w = screen->getWidth(); + head_h = screen->getHeight(); + frame.width = screen->getWidth() * screen->getToolbarWidthPercent() / 100; - +#endif // XINERAMA + I18n *i18n = I18n::instance(); if (i18n->multibyte()) @@ -233,50 +265,51 @@ void Toolbar::reconfigure(void) { switch (screen->getToolbarPlacement()) { case TOPLEFT: - frame.x = 0; - frame.y = 0; - frame.x_hidden = 0; - frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth() - frame.height; + frame.x = head_x; + frame.y = head_y; + frame.x_hidden = head_x; + frame.y_hidden = head_y + + screen->getBevelWidth() - screen->getBorderWidth() - frame.height; break; case BOTTOMLEFT: - frame.x = 0; - frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x(); - frame.x_hidden = 0; - frame.y_hidden = screen->getHeight() - screen->getBevelWidth() - + frame.x = head_x; + frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x(); + frame.x_hidden = head_x; + frame.y_hidden = head_y + head_h - screen->getBevelWidth() - screen->getBorderWidth(); break; case TOPCENTER: - frame.x = (screen->getWidth() - frame.width) / 2; - frame.y = 0; + frame.x = head_x + ((head_w - frame.width) / 2); + frame.y = head_y; frame.x_hidden = frame.x; - frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth() - - frame.height; + frame.y_hidden = head_y + + screen->getBevelWidth() - screen->getBorderWidth() - frame.height; break; case BOTTOMCENTER: default: - frame.x = (screen->getWidth() - frame.width) / 2; - frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x(); + frame.x = head_x + ((head_w - frame.width) / 2); + frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x(); frame.x_hidden = frame.x; - frame.y_hidden = screen->getHeight() - screen->getBevelWidth() - + frame.y_hidden = head_y + head_h - screen->getBevelWidth() - screen->getBorderWidth(); break; case TOPRIGHT: - frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x(); - frame.y = 0; + frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x(); + frame.y = head_y; frame.x_hidden = frame.x; - frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth() - - frame.height; + frame.y_hidden = head_y + + screen->getBevelWidth() - screen->getBorderWidth() - frame.height; break; case BOTTOMRIGHT: - frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x(); - frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x(); + frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x(); + frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x(); frame.x_hidden = frame.x; - frame.y_hidden = screen->getHeight() - screen->getBevelWidth() - + frame.y_hidden = head_y + head_h - screen->getBevelWidth() - screen->getBorderWidth(); break; } @@ -1226,6 +1259,11 @@ Toolbarmenu::Toolbarmenu(Toolbar *tb) : Basemenu(tb->screen) { setInternalMenu(); placementmenu = new Placementmenu(this); +#ifdef XINERAMA + if (toolbar->screen->hasXinerama()) { // only create if we need it + headmenu = new Headmenu(this); + } +#endif // XINERAMA insert(i18n->getMessage( #ifdef NLS @@ -1235,6 +1273,13 @@ Toolbarmenu::Toolbarmenu(Toolbar *tb) : Basemenu(tb->screen) { #endif // NLS "Placement"), placementmenu); + +#ifdef XINERAMA + if (toolbar->screen->hasXinerama()) { //TODO: NLS + insert(i18n->getMessage(0, 0, "Place on Head"), headmenu); + } +#endif // XINERAMA + insert(i18n->getMessage( #ifdef NLS CommonSet, CommonAlwaysOnTop, @@ -1271,6 +1316,12 @@ Toolbarmenu::Toolbarmenu(Toolbar *tb) : Basemenu(tb->screen) { Toolbarmenu::~Toolbarmenu(void) { delete placementmenu; +#ifdef XINERAMA + if (toolbar->screen->hasXinerama()) { + delete headmenu; + } +#endif // XINERAMA + } @@ -1321,6 +1372,11 @@ void Toolbarmenu::internal_hide(void) { void Toolbarmenu::reconfigure(void) { placementmenu->reconfigure(); +#ifdef XINERAMA + if (toolbar->screen->hasXinerama()) { + headmenu->reconfigure(); + } +#endif // XINERAMA Basemenu::reconfigure(); } @@ -1413,3 +1469,49 @@ void Toolbarmenu::Placementmenu::itemSelected(int button, int index) { } } + +#ifdef XINERAMA + +Toolbarmenu::Headmenu::Headmenu(Toolbarmenu *tm) + : Basemenu(tm->toolbar->screen) { + toolbarmenu = tm; + I18n *i18n = I18n::instance(); + + setLabel(i18n->getMessage(0, 0, "Place on Head")); //TODO: NLS + setInternalMenu(); + + int numHeads = toolbarmenu->toolbar->screen->getNumHeads(); + // fill menu with head entries + for (int i = 0; i < numHeads; i++) { + char headName[32]; + sprintf(headName, "Head %i", i+1); //TODO: NLS + insert(i18n->getMessage(0, 0, headName), i); + } + + insert(i18n->getMessage(0, 0, "All Heads"), -1); //TODO: NLS + + update(); +} + + +void Toolbarmenu::Headmenu::itemSelected(int button, int index) { + if (button == 1) { + BasemenuItem *item = find(index); + if (! item) + return; + + toolbarmenu->toolbar->screen->saveToolbarOnHead( + static_cast(item->function())); + hide(); + toolbarmenu->toolbar->reconfigure(); + +#ifdef SLIT + // reposition the slit as well to make sure it doesn't intersect the + // toolbar + toolbarmenu->toolbar->screen->getSlit()->reposition(); +#endif // SLIT + + } +} + +#endif // XINERAMA diff --git a/src/Toolbar.hh b/src/Toolbar.hh index d2d4016..1a70a48 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -1,3 +1,6 @@ +// Toolbar.hh for Fluxbox +// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org) +// // Toolbar.hh for Blackbox - an X11 Window manager // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) // @@ -19,148 +22,164 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Toolbar.hh,v 1.8 2002/03/19 00:12:36 fluxgen Exp $ +// $Id: Toolbar.hh,v 1.9 2002/03/19 14:30:42 fluxgen Exp $ -#ifndef TOOLBAR_HH -#define TOOLBAR_HH +#ifndef TOOLBAR_HH +#define TOOLBAR_HH #include -#ifndef _BASEMENU_HH_ #include "Basemenu.hh" -#endif -#ifndef _TIMER_HH_ #include "Timer.hh" -#endif -#ifndef _ICONBAR_HH_ #include "IconBar.hh" -#endif - // forward declaration class Toolbar; class Toolbarmenu : public Basemenu { private: - class Placementmenu : public Basemenu { - private: - Toolbarmenu *toolbarmenu; + class Placementmenu : public Basemenu { + private: + Toolbarmenu *toolbarmenu; + + protected: + virtual void itemSelected(int, int); + + public: + Placementmenu(Toolbarmenu *); + }; - protected: - virtual void itemSelected(int, int); + #ifdef XINERAMA + class Headmenu : public Basemenu { + public: + Headmenu(Toolbarmenu *); + private: + Toolbarmenu *toolbarmenu; - public: - Placementmenu(Toolbarmenu *); - }; + protected: + virtual void itemSelected(int, int); + }; + #endif // XINERAMA + - Toolbar *toolbar; - Placementmenu *placementmenu; + Toolbar *toolbar; + Placementmenu *placementmenu; + #ifdef XINERAMA + Headmenu *headmenu; + friend class Headmenu; + #endif // XINERAMA - friend class Placementmenu; - friend class Toolbar; + friend class Placementmenu; + friend class Toolbar; protected: - virtual void itemSelected(int, int); - virtual void internal_hide(void); + virtual void itemSelected(int, int); + virtual void internal_hide(void); public: - Toolbarmenu(Toolbar *); - ~Toolbarmenu(void); + Toolbarmenu(Toolbar *); + ~Toolbarmenu(void); + #ifdef XINERAMA + inline Basemenu *getHeadmenu(void) { return headmenu; } + #endif // XINERAMA - inline Basemenu *getPlacementmenu(void) { return placementmenu; } + inline Basemenu *getPlacementmenu(void) { return placementmenu; } - void reconfigure(void); + void reconfigure(void); }; class Toolbar : public TimeoutHandler { private: - Bool on_top, editing, hidden, do_auto_hide; - Display *display; - - struct frame { - unsigned long button_pixel, pbutton_pixel; - Pixmap base, label, wlabel, clk, button, pbutton; - Window window, workspace_label, window_label, clock, psbutton, nsbutton, - pwbutton, nwbutton; - - int x, y, x_hidden, y_hidden, hour, minute, grab_x, grab_y; - unsigned int width, height, window_label_w, workspace_label_w, clock_w, - button_w, bevel_w, label_h; - } frame; - - class HideHandler : public TimeoutHandler { - public: - Toolbar *toolbar; - - virtual void timeout(void); - } hide_handler; - - Fluxbox *fluxbox; - BScreen *screen; - BImageControl *image_ctrl; - BTimer clock_timer, *hide_timer; - Toolbarmenu *toolbarmenu; + Bool on_top, editing, hidden, do_auto_hide; + Display *display; + + struct frame { + unsigned long button_pixel, pbutton_pixel; + Pixmap base, label, wlabel, clk, button, pbutton; + Window window, workspace_label, window_label, clock, psbutton, nsbutton, + pwbutton, nwbutton; + + int x, y, x_hidden, y_hidden, hour, minute, grab_x, grab_y; + unsigned int width, height, window_label_w, workspace_label_w, clock_w, + button_w, bevel_w, label_h; + } frame; + + class HideHandler : public TimeoutHandler { + public: + Toolbar *toolbar; + + virtual void timeout(void); + } hide_handler; + + Fluxbox *fluxbox; + BScreen *screen; + BImageControl *image_ctrl; + BTimer clock_timer, *hide_timer; + Toolbarmenu *toolbarmenu; class IconBar *iconbar; - std::string new_workspace_name; + std::string new_workspace_name; - friend class HideHandler; - friend class Toolbarmenu; - friend class Toolbarmenu::Placementmenu; + friend class HideHandler; + friend class Toolbarmenu; + friend class Toolbarmenu::Placementmenu; + #ifdef XINERAMA + friend class Toolbarmenu::Headmenu; + #endif // XINERAMA public: - Toolbar(BScreen *); - virtual ~Toolbar(void); + Toolbar(BScreen *); + virtual ~Toolbar(void); void addIcon(FluxboxWindow *w); void delIcon(FluxboxWindow *w); - inline Toolbarmenu *getMenu(void) { return toolbarmenu; } + inline Toolbarmenu *getMenu(void) { return toolbarmenu; } //inline Window getWindowLabel(void) { return frame.window_label; } - inline const Bool &isEditing(void) const { return editing; } - inline const Bool &isOnTop(void) const { return on_top; } - inline const Bool &isHidden(void) const { return hidden; } - inline const Bool &doAutoHide(void) const { return do_auto_hide; } - - inline const Window &getWindowID(void) const { return frame.window; } - - inline const unsigned int &getWidth(void) const { return frame.width; } - inline const unsigned int &getHeight(void) const { return frame.height; } - inline const unsigned int &getExposedHeight(void) const - { return ((do_auto_hide) ? frame.bevel_w : frame.height); } - inline const int &getX(void) const - { return ((hidden) ? frame.x_hidden : frame.x); } - inline const int &getY(void) const - { return ((hidden) ? frame.y_hidden : frame.y); } + inline const Bool &isEditing(void) const { return editing; } + inline const Bool &isOnTop(void) const { return on_top; } + inline const Bool &isHidden(void) const { return hidden; } + inline const Bool &doAutoHide(void) const { return do_auto_hide; } + + inline const Window &getWindowID(void) const { return frame.window; } + + inline const unsigned int &getWidth(void) const { return frame.width; } + inline const unsigned int &getHeight(void) const { return frame.height; } + inline const unsigned int &getExposedHeight(void) const + { return ((do_auto_hide) ? frame.bevel_w : frame.height); } + inline const int &getX(void) const + { return ((hidden) ? frame.x_hidden : frame.x); } + inline const int &getY(void) const + { return ((hidden) ? frame.y_hidden : frame.y); } inline IconBar *getIconBar(void) { return iconbar; } - void buttonPressEvent(XButtonEvent *); - void buttonReleaseEvent(XButtonEvent *); - void enterNotifyEvent(XCrossingEvent *); - void leaveNotifyEvent(XCrossingEvent *); - void exposeEvent(XExposeEvent *); - void keyPressEvent(XKeyEvent *); - - void redrawWindowLabel(Bool = False); - void redrawWorkspaceLabel(Bool = False); - void redrawPrevWorkspaceButton(Bool = False, Bool = False); - void redrawNextWorkspaceButton(Bool = False, Bool = False); - void redrawPrevWindowButton(Bool = False, Bool = False); - void redrawNextWindowButton(Bool = False, Bool = False); - void edit(void); - void reconfigure(void); - -#ifdef HAVE_STRFTIME - void checkClock(Bool = False); -#else // HAVE_STRFTIME - void checkClock(Bool = False, Bool = False); + void buttonPressEvent(XButtonEvent *); + void buttonReleaseEvent(XButtonEvent *); + void enterNotifyEvent(XCrossingEvent *); + void leaveNotifyEvent(XCrossingEvent *); + void exposeEvent(XExposeEvent *); + void keyPressEvent(XKeyEvent *); + + void redrawWindowLabel(Bool = False); + void redrawWorkspaceLabel(Bool = False); + void redrawPrevWorkspaceButton(Bool = False, Bool = False); + void redrawNextWorkspaceButton(Bool = False, Bool = False); + void redrawPrevWindowButton(Bool = False, Bool = False); + void redrawNextWindowButton(Bool = False, Bool = False); + void edit(void); + void reconfigure(void); + +#ifdef HAVE_STRFTIME + void checkClock(Bool = False); +#else // HAVE_STRFTIME + void checkClock(Bool = False, Bool = False); #endif // HAVE_STRFTIME - virtual void timeout(void); + virtual void timeout(void); - enum Placement{ TOPLEFT = 1, BOTTOMLEFT, TOPCENTER, - BOTTOMCENTER, TOPRIGHT, BOTTOMRIGHT }; + enum Placement{ TOPLEFT = 1, BOTTOMLEFT, TOPCENTER, + BOTTOMCENTER, TOPRIGHT, BOTTOMRIGHT }; }; diff --git a/src/Window.cc b/src/Window.cc index d41b77e..c74f101 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.33 2002/03/19 00:15:58 fluxgen Exp $ +// $Id: Window.cc,v 1.34 2002/03/19 14:30:42 fluxgen Exp $ //use GNU extensions #ifndef _GNU_SOURCE @@ -265,32 +265,44 @@ tab(0) client.normal_hint_flags & (PPosition|USPosition)) { setGravityOffsets(); - if (! fluxbox->isStartup()) { // is going to be used when position - if (decorations.tab) { // window is cleanly fixed - int real_x = frame.x; - int real_y = frame.y; + if (! fluxbox->isStartup()) { + #ifdef XINERAMA + unsigned int head = 0; + if (screen->hasXinerama()) { + head = screen->getHead(frame.x, frame.y); + } + #endif // XINERAMA - if (screen->getTabPlacement() == Tab::PTOP) - real_y -= screen->getTabHeight(); + int real_x = frame.x; + int real_y = frame.y; - else if (screen->getTabPlacement() == Tab::PLEFT) { - if (screen->isTabRotateVertical()) - real_x -= screen->getTabHeight(); - else - real_x -= screen->getTabWidth(); + if (decorations.tab) { + if (screen->getTabPlacement() == Tab::PTOP) { + real_y -= screen->getTabHeight(); + } else if (screen->getTabPlacement() == Tab::PLEFT) { + real_x -= (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); } + } - if (real_x >= 0 && - real_y + frame.y_border >= 0 && - real_x <= (signed) screen->getWidth() && - real_y <= (signed) screen->getHeight()) - place_window = false; - - } else if (frame.x >= 0 && // non tab - (signed) (frame.y + frame.y_border) >= 0 && - frame.x <= (signed) screen->getWidth() && - frame.y <= (signed) screen->getHeight()) + #ifdef XINERAMA + // check is within the current head, so it won't overlap heads + if (real_x >= screen->getHeadX(head) && + real_y + frame.y_border >= screen->getHeadY(head) && + (real_x + frame.width) <= + (screen->getHeadX(head) + screen->getHeadWidth(head)) && + (real_y + frame.height) <= + (screen->getHeadY(head) + screen->getHeadHeight(head)) ) + place_window = false; + #else // !XINERAMA + if (real_x >= 0 && + real_y + frame.y_border >= 0 && + real_x <= (signed) screen->getWidth() && + real_y <= (signed) screen->getHeight()) place_window = false; + #endif // XIENRAMA + } else place_window = false; @@ -2083,7 +2095,25 @@ void FluxboxWindow::maximize(unsigned int button) { if (! maximized) { int dx, dy; unsigned int dw, dh, slitModL = 0, slitModR = 0, slitModT = 0, slitModB = 0; + +#ifdef XINERAMA + // get the head the window is on, taking the middle of the window to + // make it feel right, maybe someone will like client.x, client.y better + // tough? + unsigned int head = (screen->hasXinerama()) ? + screen->getHead(client.x + (client.width / 2), client.y + (client.height / 2)) + : 0; +#endif // XINERAMA + + #ifdef SLIT + +#ifdef XINERAMA +// take the slit in account if it's on the same head +// (always true if we don't have xinerama +if (!screen->hasXinerama() || screen->getSlitOnHead() == head) { +#endif // XINERAMA + Slit* mSlt = screen->getSlit(); if(!screen->doMaxOverSlit() && !screen->doFullMax() && (mSlt->getWidth() > 1)) @@ -2138,6 +2168,10 @@ void FluxboxWindow::maximize(unsigned int button) { break; } } +#ifdef XINERAMA +} +#endif // XINERAMA + #endif // SLIT blackbox_attrib.premax_x = frame.x; @@ -2145,21 +2179,44 @@ void FluxboxWindow::maximize(unsigned int button) { blackbox_attrib.premax_w = frame.width; blackbox_attrib.premax_h = frame.height; +#ifdef XINERAMA + dw = screen->getHeadWidth(head) - slitModL - slitModR; +#else // !XINERAMA dw = screen->getWidth() - slitModL - slitModR; +#endif // XINERAMA dw -= screen->getBorderWidth2x(); dw -= frame.mwm_border_w * 2; dw -= client.base_width; +#ifdef XINERAMA + dh = screen->getHeadHeight(head) - slitModT - slitModB; +#else // !XINERAMA dh = screen->getHeight() - slitModT - slitModB; +#endif // XINERAMA dh -= screen->getBorderWidth2x(); dh -= frame.mwm_border_w * 2; dh -= ((frame.handle_h + screen->getBorderWidth()) * decorations.handle); dh -= client.base_height; dh -= frame.y_border; - if (! screen->doFullMax()) + if (! screen->doFullMax()) { +#ifdef XINERAMA + if (screen->hasXinerama()) { + // is the toolbar on this head? + if ((screen->getToolbarOnHead() == (signed) head) || + (screen->getToolbarOnHead() < 0)) { + dh -= screen->getToolbar()->getExposedHeight() + + screen->getBorderWidth2x(); + } + } else { + dh -= screen->getToolbar()->getExposedHeight() + + screen->getBorderWidth2x(); + } +#else // !XINERAMA dh -= screen->getToolbar()->getExposedHeight() + screen->getBorderWidth2x(); +#endif // XINERAMA + } if (dw < client.min_width) dw = client.min_width; if (dh < client.min_height) dh = client.min_height; @@ -2177,20 +2234,61 @@ void FluxboxWindow::maximize(unsigned int button) { dh += (frame.handle_h + screen->getBorderWidth()); dh += frame.mwm_border_w * 2; +#ifdef XINERAMA + dx = screen->getHeadX(head) + + ((screen->getHeadWidth(head) + slitModL - slitModR - dw) / 2) + - screen->getBorderWidth(); +#else // !XINERAMA dx = ((screen->getWidth()+ slitModL - slitModR - dw) / 2) - screen->getBorderWidth(); +#endif // XINERAMA if (screen->doFullMax()) { +#ifdef XINERAMA + dy = screen->getHeadY(head) + + ((screen->getHeadHeight(head) - dh) / 2) - screen->getBorderWidth(); +#else // !XINERAMA dy = ((screen->getHeight() - dh) / 2) - screen->getBorderWidth(); +#endif // XINERAMA } else { +#ifdef XINERAMA + if (screen->hasXinerama()) { // xinerama + dy = screen->getHeadY(head); + // is the toolbar on this head? + if ((screen->getToolbarOnHead() == (signed) head) || + (screen->getToolbarOnHead() < 0)) { + dy += (((screen->getHeadHeight(head) + slitModT - slitModB + - (screen->getToolbar()->getExposedHeight())) - dh) / 2) + - screen->getBorderWidth2x(); + } else { + dy += ((screen->getHeadHeight(head) + slitModT - slitModB - dh) / 2) - + screen->getBorderWidth(); + } + } else { // no xinerama + dy = (((screen->getHeight() + slitModT - slitModB - + (screen->getToolbar()->getExposedHeight())) - dh) / 2) - + screen->getBorderWidth2x(); + } +#else // !XINERAMA dy = (((screen->getHeight() + slitModT - slitModB - (screen->getToolbar()->getExposedHeight())) - dh) / 2) - screen->getBorderWidth2x(); +#endif // XINERAMA switch (screen->getToolbarPlacement()) { case Toolbar::TOPLEFT: case Toolbar::TOPCENTER: case Toolbar::TOPRIGHT: +#ifdef XINERAMA + // if < 0 than it's over ALL heads, with no xinerama it's there too + if (!screen->hasXinerama() || + (screen->getToolbarOnHead() == (signed) head) || + (screen->getToolbarOnHead() < 0)) { + dy += screen->getToolbar()->getExposedHeight() + + screen->getBorderWidth2x(); + } +#else // !XINERAMA dy += screen->getToolbar()->getExposedHeight() + screen->getBorderWidth2x(); +#endif // XINERAMA break; default: break; diff --git a/src/Workspace.cc b/src/Workspace.cc index e136c32..85bd2aa 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Workspace.cc,v 1.12 2002/02/26 22:34:49 fluxgen Exp $ +// $Id: Workspace.cc,v 1.13 2002/03/19 14:30:43 fluxgen Exp $ // use GNU extensions #ifndef _GNU_SOURCE @@ -343,8 +343,8 @@ void Workspace::setName(char *new_name) { } //------------ shutdown --------- -// Calles restore on all windows -// in the workspace and then +// Calls restore on all windows +// on the workspace and then // clears the windowList //------------------------------- void Workspace::shutdown(void) { @@ -358,22 +358,17 @@ void Workspace::shutdown(void) { void Workspace::placeWindow(FluxboxWindow *win) { Bool placed = False; - int win_w = win->getWidth() + (screen->getBorderWidth2x() * 2), - win_h = win->getHeight() + (screen->getBorderWidth2x() * 2), + int borderWidth4x = screen->getBorderWidth2x() * 2, #ifdef SLIT slit_x = screen->getSlit()->getX() - screen->getBorderWidth(), slit_y = screen->getSlit()->getY() - screen->getBorderWidth(), - slit_w = screen->getSlit()->getWidth() + - (screen->getBorderWidth2x() * 2), - slit_h = screen->getSlit()->getHeight() + - (screen->getBorderWidth2x() * 2), + slit_w = screen->getSlit()->getWidth() + borderWidth4x, + slit_h = screen->getSlit()->getHeight() + borderWidth4x, #endif // SLIT toolbar_x = screen->getToolbar()->getX() - screen->getBorderWidth(), toolbar_y = screen->getToolbar()->getY() - screen->getBorderWidth(), - toolbar_w = screen->getToolbar()->getWidth() + - (screen->getBorderWidth2x() * 2), - toolbar_h = screen->getToolbar()->getHeight() + - (screen->getBorderWidth2x() * 2), + toolbar_w = screen->getToolbar()->getWidth() + borderWidth4x, + toolbar_h = screen->getToolbar()->getHeight() + borderWidth4x, place_x = 0, place_y = 0, change_x = 1, change_y = 1; if (screen->getColPlacementDirection() == BScreen::BOTTOMTOP) @@ -381,43 +376,135 @@ void Workspace::placeWindow(FluxboxWindow *win) { if (screen->getRowPlacementDirection() == BScreen::RIGHTLEFT) change_x = -1; - register int test_x, test_y, curr_w, curr_h; +#ifdef XINERAMA + int head = 0, + head_x = 0, + head_y = 0; + int head_w, head_h; + if (screen->hasXinerama()) { + head = screen->getCurrHead(); + head_x = screen->getHeadX(head); + head_y = screen->getHeadY(head); + head_w = screen->getHeadWidth(head); + head_h = screen->getHeadHeight(head); + + } else { // no xinerama + head_w = screen->getWidth(); + head_h = screen->getHeight(); + } + +#endif // XINERAMA + + int win_w = win->getWidth() + screen->getBorderWidth2x(), + win_h = win->getHeight() + screen->getBorderWidth2x(); + + if (win->hasTab()) { + if ((! win->isShaded()) && + screen->getTabPlacement() == Tab::PLEFT || + screen->getTabPlacement() == Tab::PRIGHT) + win_w += (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); + else // tab placement top or bottom or win is shaded + win_h += screen->getTabHeight(); + } + + register int test_x, test_y, curr_x, curr_y, curr_w, curr_h; switch (screen->getPlacementPolicy()) { case BScreen::ROWSMARTPLACEMENT: { - test_y = screen->getBorderWidth() + screen->getEdgeSnapThreshold(); + #ifdef XINERAMA + test_y = head_y; + #else // !XINERAMA + test_y = 0; + #endif // XINERAMA if (screen->getColPlacementDirection() == BScreen::BOTTOMTOP) + #ifdef XINERAMA + test_y = (head_y + head_h) - win_h - test_y; + #else // !XINERAMA test_y = screen->getHeight() - win_h - test_y; + #endif // XINERAMA while (((screen->getColPlacementDirection() == BScreen::BOTTOMTOP) ? - test_y > 0 : test_y + win_h < (signed) screen->getHeight()) && - ! placed) { - test_x = screen->getBorderWidth() + screen->getEdgeSnapThreshold(); + #ifdef XINERAMA + test_y >= head_y : test_y + win_h <= (head_y + head_h)) && + #else // !XINERAMA + test_y > 0 : test_y + win_h < (signed) screen->getHeight()) && + #endif // XINERAMA + ! placed) { + + #ifdef XINERAMA + test_x = head_x; + #else // !XINERAMA + test_x = 0; + #endif // XINERAMA if (screen->getRowPlacementDirection() == BScreen::RIGHTLEFT) + #ifdef XINERAMA + test_x = (head_x + head_w) - win_w - test_x; + #else // !XINERAMA test_x = screen->getWidth() - win_w - test_x; + #endif // XINERAMA while (((screen->getRowPlacementDirection() == BScreen::RIGHTLEFT) ? - test_x > 0 : test_x + win_w < (signed) screen->getWidth()) && - ! placed) { + #ifdef XINERAMA + test_x >= head_x : test_x + win_w <= (head_x + head_w)) && + #else // !XINERAMA + test_x > 0 : test_x + win_w < (signed) screen->getWidth()) && + #endif // XINERAMA + ! placed) { + placed = True; - Windows::iterator it = windowList.begin(); - Windows::iterator it_end = windowList.end(); - for (; it != it_end && placed; ++it) { - curr_w = (*it)->getWidth() + screen->getBorderWidth2x() + - screen->getBorderWidth2x(); + Windows::iterator it = windowList.begin(); + Windows::iterator it_end = windowList.end(); + + for (; it != it_end && placed; ++it) { + curr_x = (*it)->getXFrame(); + curr_y = (*it)->getYFrame(); + curr_w = (*it)->getWidth() + screen->getBorderWidth2x(); curr_h = (((*it)->isShaded()) ? (*it)->getTitleHeight() : (*it)->getHeight()) + - screen->getBorderWidth2x() + - screen->getBorderWidth2x(); - - if ((*it)->getXFrame() < test_x + win_w && - (*it)->getXFrame() + curr_w > test_x && - (*it)->getYFrame() < test_y + win_h && - (*it)->getYFrame() + curr_h > test_y) + screen->getBorderWidth2x(); + + if ((*it)->hasTab()) { + if (! (*it)->isShaded()) { // not shaded window + switch(screen->getTabPlacement()) { + case Tab::PTOP: + curr_y -= screen->getTabHeight(); + case Tab::PBOTTOM: + curr_h += screen->getTabHeight(); + break; + case Tab::PLEFT: + curr_x -= (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); + case Tab::PRIGHT: + curr_w += (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); + break; + default: + #ifdef DEBUG + cerr << __FILE__ << ":" <<__LINE__ << ": " << + "Unsupported Placement" << endl; + #endif // DEBUG + break; + } + } else { // shaded window + if (screen->getTabPlacement() == Tab::PTOP) + curr_y -= screen->getTabHeight(); + curr_h += screen->getTabHeight(); + } + } // tab cheking done + + if (curr_x < test_x + win_w && + curr_x + curr_w > test_x && + curr_y < test_y + win_h && + curr_y + curr_h > test_y) { placed = False; + } } if ((toolbar_x < test_x + win_w && @@ -450,39 +537,96 @@ void Workspace::placeWindow(FluxboxWindow *win) { break; } case BScreen::COLSMARTPLACEMENT: { - test_x = screen->getBorderWidth() + screen->getEdgeSnapThreshold(); + #ifdef XINERAMA + test_x = head_x; + #else // !XINERAMA + test_x = 0; + #endif // XINERAMA if (screen->getRowPlacementDirection() == BScreen::RIGHTLEFT) + #ifdef XINERAMA + test_x = (head_x + head_w) - win_w - test_x; + #else // !XINERAMA test_x = screen->getWidth() - win_w - test_x; + #endif // XINERAMA while (((screen->getRowPlacementDirection() == BScreen::RIGHTLEFT) ? - test_x > 0 : test_x + win_w < (signed) screen->getWidth()) && - ! placed) { - test_y = screen->getBorderWidth() + screen->getEdgeSnapThreshold(); + #ifdef XINERAMA + test_x >= 0 : test_x + win_w <= (head_x + head_w)) && + #else // !XINERAMA + test_x > 0 : test_x + win_w < (signed) screen->getWidth()) && + #endif // XINERAMA + ! placed) { + + #ifdef XINERAMA + test_y = head_y; + #else // !XINERAMA + test_y = 0; + #endif // XINERAMA if (screen->getColPlacementDirection() == BScreen::BOTTOMTOP) + #ifdef XINERAMA + test_y = (head_y + head_h) - win_h - test_y; + #else // !XINERAMA test_y = screen->getHeight() - win_h - test_y; + #endif // XINERAMA while (((screen->getColPlacementDirection() == BScreen::BOTTOMTOP) ? - test_y > 0 : test_y + win_h < (signed) screen->getHeight()) && - ! placed) { + #ifdef XINERAMA + test_y >= head_y : test_y + win_h <= (head_y + head_h)) && + #else // !XINERAMA + test_y > 0 : test_y + win_h < (signed) screen->getHeight()) && + #endif // XINERAMA + ! placed) { placed = True; Windows::iterator it = windowList.begin(); Windows::iterator it_end = windowList.end(); for (; it != it_end && placed; ++it) { - curr_w = (*it)->getWidth() + screen->getBorderWidth2x() + - screen->getBorderWidth2x(); + curr_x = (*it)->getXFrame(); + curr_y = (*it)->getYFrame(); + curr_w = (*it)->getWidth() + screen->getBorderWidth2x(); curr_h = (((*it)->isShaded()) ? (*it)->getTitleHeight() : (*it)->getHeight()) + - screen->getBorderWidth2x() + - screen->getBorderWidth2x(); - - if ((*it)->getXFrame() < test_x + win_w && - (*it)->getXFrame() + curr_w > test_x && - (*it)->getYFrame() < test_y + win_h && - (*it)->getYFrame() + curr_h > test_y) + screen->getBorderWidth2x();; + + if ((*it)->hasTab()) { + if (! (*it)->isShaded()) { // not shaded window + switch(screen->getTabPlacement()) { + case Tab::PTOP: + curr_y -= screen->getTabHeight(); + case Tab::PBOTTOM: + curr_h += screen->getTabHeight(); + break; + case Tab::PLEFT: + curr_x -= (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); + case Tab::PRIGHT: + curr_w += (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); + break; + default: + #ifdef DEBUG + cerr << __FILE__ << ":" <<__LINE__ << ": " << + "Unsupported Placement" << endl; + #endif // DEBUG + break; + } + } else { // shaded window + if (screen->getTabPlacement() == Tab::PTOP) + curr_y -= screen->getTabHeight(); + curr_h += screen->getTabHeight(); + } + } // tab cheking done + + if (curr_x < test_x + win_w && + curr_x + curr_w > test_x && + curr_y < test_y + win_h && + curr_y + curr_h > test_y) { placed = False; + } } if ((toolbar_x < test_x + win_w && @@ -502,8 +646,6 @@ void Workspace::placeWindow(FluxboxWindow *win) { if (placed) { place_x = test_x; place_y = test_y; - - break; } test_y += change_y; @@ -515,22 +657,49 @@ void Workspace::placeWindow(FluxboxWindow *win) { break; } } + // cascade placement or smart placement failed if (! placed) { + #ifdef XINERAMA + if ((cascade_x > (head_w / 2)) || + (cascade_y > (head_h / 2))) + #else // !XINERAMA if (((unsigned) cascade_x > (screen->getWidth() / 2)) || ((unsigned) cascade_y > (screen->getHeight() / 2))) - cascade_x = cascade_y = 32; + #endif // XINERAMA + cascade_x = cascade_y = 32; +#ifdef XINERAMA + place_x = head_x + cascade_x; + place_y = head_y + cascade_y; +#else // !XINERAMA place_x = cascade_x; place_y = cascade_y; - +#endif // XINERAMA cascade_x += win->getTitleHeight(); cascade_y += win->getTitleHeight(); } +#ifdef XINERAMA + if (place_x + win_w > (head_x + head_w)) + place_x = head_x + ((head_w - win_w) / 2); + if (place_y + win_h > (head_y + head_h)) + place_y = head_y + ((head_h - win_h) / 2); +#else // !XINERAMA if (place_x + win_w > (signed) screen->getWidth()) place_x = (((signed) screen->getWidth()) - win_w) / 2; if (place_y + win_h > (signed) screen->getHeight()) place_y = (((signed) screen->getHeight()) - win_h) / 2; +#endif // XINERAMA + + // fix window placement, think of tabs + if (win->hasTab()) { + if (screen->getTabPlacement() == Tab::PTOP) + place_y += screen->getTabHeight(); + else if (screen->getTabPlacement() == Tab::PLEFT) + place_x += (screen->isTabRotateVertical()) + ? screen->getTabHeight() + : screen->getTabWidth(); + } win->configure(place_x, place_y, win->getWidth(), win->getHeight()); } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 2ff4b03..5ba27b4 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.41 2002/03/19 00:16:44 fluxgen Exp $ +// $Id: fluxbox.cc,v 1.42 2002/03/19 14:30:43 fluxgen Exp $ //Use some GNU extensions #ifndef _GNU_SOURCE @@ -1881,7 +1881,13 @@ void Fluxbox::save_rc(void) { sprintf(rc_string, "session.screen%d.slit.autoHide: %s", screen_number, ((screen->getSlit()->doAutoHide()) ? "True" : "False")); XrmPutLineResource(&new_blackboxrc, rc_string); - + + #ifdef XINERAMA + sprintf(rc_string, "session.screen%d.slit.onHead: %d", screen_number, + screen->getSlitOnHead()); + XrmPutLineResource(&new_blackboxrc, rc_string); + #endif // XINERAMA + #endif // SLIT sprintf(rc_string, "session.screen%d.rowPlacementDirection: %s", screen_number, @@ -2243,6 +2249,20 @@ void Fluxbox::load_rc(BScreen *screen) { screen->saveSlitAutoHide(False); else screen->saveSlitAutoHide(False); + + #ifdef XINERAMA + int tmp_head; + sprintf(name_lookup, "session.screen%d.slit.onHead", screen_number); + sprintf(class_lookup, "Session.Screen%d.Slit.OnHead", screen_number); + if (XrmGetResource(*database, name_lookup, class_lookup, &value_type, + &value)) { + if (sscanf(value.addr, "%d", &tmp_head) != 1) + tmp_head = 0; + } else + tmp_head = 0; + screen->saveSlitOnHead(tmp_head); + #endif // XINERAMA + #endif // SLIT #ifdef HAVE_STRFTIME -- cgit v0.11.2