Xinerama support

This commit is contained in:
fluxgen 2002-03-19 14:30:43 +00:00
parent 1871169b06
commit 95aeda2627
12 changed files with 1089 additions and 232 deletions

View file

@ -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

View file

@ -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 <X11/Xlib.h>
#ifdef XINERAMA
extern "C" {
#include <X11/extensions/Xinerama.h>
}
#endif // XINERAMA
#include <list>
#include <vector>
@ -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

View file

@ -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];

View file

@ -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,
(getWidth() - geom_w) / 2,
(getHeight() - geom_h) / 2, geom_w, geom_h);
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);

View file

@ -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> tab_placement;
Resource<Tab::Alignment> tab_alignment;
#ifdef XINERAMA
Resource<int> toolbar_on_head;
#endif // XINERAMA
Resource<Toolbar::Placement> 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

View file

@ -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

View file

@ -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
};

View file

@ -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<int>(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

View file

@ -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 <X11/Xlib.h>
#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);
protected:
virtual void itemSelected(int, int);
public:
Placementmenu(Toolbarmenu *);
};
public:
Placementmenu(Toolbarmenu *);
};
Toolbar *toolbar;
Placementmenu *placementmenu;
#ifdef XINERAMA
class Headmenu : public Basemenu {
public:
Headmenu(Toolbarmenu *);
private:
Toolbarmenu *toolbarmenu;
friend class Placementmenu;
friend class Toolbar;
protected:
virtual void itemSelected(int, int);
};
#endif // XINERAMA
Toolbar *toolbar;
Placementmenu *placementmenu;
#ifdef XINERAMA
Headmenu *headmenu;
friend class Headmenu;
#endif // XINERAMA
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;
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;
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;
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;
class HideHandler : public TimeoutHandler {
public:
Toolbar *toolbar;
virtual void timeout(void);
} hide_handler;
virtual void timeout(void);
} hide_handler;
Fluxbox *fluxbox;
BScreen *screen;
BImageControl *image_ctrl;
BTimer clock_timer, *hide_timer;
Toolbarmenu *toolbarmenu;
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 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 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 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 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);
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);
#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 };
};

View file

@ -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)
int real_x = frame.x;
int real_y = frame.y;
if (decorations.tab) {
if (screen->getTabPlacement() == Tab::PTOP) {
real_y -= screen->getTabHeight();
else if (screen->getTabPlacement() == Tab::PLEFT) {
if (screen->isTabRotateVertical())
real_x -= screen->getTabHeight();
else
real_x -= screen->getTabWidth();
} 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;

View file

@ -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();
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)
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();
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)
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());
}

View file

@ -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