X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FSlit.cc;h=c15f66c4b361ce336e51bfafb3689ffa210e383e;hb=fa3fb793e7e8a4d7dfdc1d4997983ea59a8b6924;hp=97d881c73db8fde3bea7ad1b0a18451a7ac342cb;hpb=44e3582d5e08556c7b1136cfd9a49546cf5fcae0;p=chaz%2Fopenbox diff --git a/src/Slit.cc b/src/Slit.cc index 97d881c7..c15f66c4 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -1,5 +1,6 @@ -// Slit.cc for Openbox -// Copyright (c) 2001 Sean 'Shaleh' Perry +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- +// Slit.cc for Blackbox - an X11 Window manager +// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) // // Permission is hereby granted, free of charge, to any person obtaining a @@ -20,166 +21,169 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// stupid macros needed to access some functions in version 2 of the GNU C -// library -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif // _GNU_SOURCE - #ifdef HAVE_CONFIG_H # include "../config.h" #endif // HAVE_CONFIG_H -#ifdef SLIT - +extern "C" { #include +} -#include "i18n.h" -#include "openbox.h" -#include "Image.h" -#include "Screen.h" -#include "Slit.h" -#include "Toolbar.h" +#include "i18n.hh" +#include "blackbox.hh" +#include "Image.hh" +#include "Screen.hh" +#include "Slit.hh" +#include "Toolbar.hh" -Slit::Slit(BScreen &scr) : screen(scr), openbox(scr.getOpenbox()) { - on_top = screen.isSlitOnTop(); - hidden = do_auto_hide = screen.doSlitAutoHide(); +Slit::Slit(BScreen *scr) { + screen = scr; + blackbox = screen->getBlackbox(); + slitstr = "session.screen" + itostring(screen->getScreenNumber()) + ".slit."; + config = blackbox->getConfig(); - display = screen.getBaseDisplay().getXDisplay(); - frame.window = frame.pixmap = None; + load_rc(); - timer = new BTimer(openbox, *this); - timer->setTimeout(openbox.getAutoRaiseDelay()); - timer->fireOnce(True); + display = screen->getBaseDisplay()->getXDisplay(); + frame.window = frame.pixmap = None; - clientList = new LinkedList; + timer = new BTimer(blackbox, this); + timer->setTimeout(blackbox->getAutoRaiseDelay()); - slitmenu = new Slitmenu(*this); + slitmenu = new Slitmenu(this); XSetWindowAttributes attrib; unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; attrib.background_pixmap = None; attrib.background_pixel = attrib.border_pixel = - screen.getBorderColor()->getPixel(); - attrib.colormap = screen.getColormap(); + screen->getBorderColor()->pixel(); + attrib.colormap = screen->getColormap(); attrib.override_redirect = True; attrib.event_mask = SubstructureRedirectMask | ButtonPressMask | EnterWindowMask | LeaveWindowMask; - frame.x = frame.y = 0; - frame.width = frame.height = 1; + frame.rect.setSize(1, 1); frame.window = - XCreateWindow(display, screen.getRootWindow(), frame.x, frame.y, - frame.width, frame.height, screen.getBorderWidth(), - screen.getDepth(), InputOutput, screen.getVisual(), - create_mask, &attrib); - openbox.saveSlitSearch(frame.window, this); + XCreateWindow(display, screen->getRootWindow(), + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height(), + screen->getBorderWidth(), screen->getDepth(), InputOutput, + screen->getVisual(), create_mask, &attrib); + blackbox->saveSlitSearch(frame.window, this); + + screen->addStrut(&strut); reconfigure(); } -Slit::~Slit() { - openbox.grab(); - - if (timer->isTiming()) timer->stop(); +Slit::~Slit(void) { delete timer; - delete clientList; delete slitmenu; - screen.getImageControl()->removeImage(frame.pixmap); + screen->removeStrut(&strut); + screen->updateAvailableArea(); - openbox.removeSlitSearch(frame.window); + screen->getImageControl()->removeImage(frame.pixmap); - XDestroyWindow(display, frame.window); + blackbox->removeSlitSearch(frame.window); - openbox.ungrab(); + XDestroyWindow(display, frame.window); } void Slit::addClient(Window w) { - openbox.grab(); - - if (openbox.validateWindow(w)) { - SlitClient *client = new SlitClient; - client->client_window = w; - - XWMHints *wmhints = XGetWMHints(display, w); - - if (wmhints) { - if ((wmhints->flags & IconWindowHint) && - (wmhints->icon_window != None)) { - XMoveWindow(display, client->client_window, screen.size().w() + 10, - screen.size().h() + 10); - XMapWindow(display, client->client_window); - - client->icon_window = wmhints->icon_window; - client->window = client->icon_window; - } else { - client->icon_window = None; - client->window = client->client_window; - } + if (! blackbox->validateWindow(w)) + return; + + SlitClient *client = new SlitClient; + client->client_window = w; + + XWMHints *wmhints = XGetWMHints(display, w); + + if (wmhints) { + if ((wmhints->flags & IconWindowHint) && + (wmhints->icon_window != None)) { + // some dock apps use separate windows, we need to hide these + XMoveWindow(display, client->client_window, screen->getWidth() + 10, + screen->getHeight() + 10); + XMapWindow(display, client->client_window); - XFree(wmhints); + client->icon_window = wmhints->icon_window; + client->window = client->icon_window; } else { client->icon_window = None; client->window = client->client_window; } - XWindowAttributes attrib; - if (XGetWindowAttributes(display, client->window, &attrib)) { - client->width = attrib.width; - client->height = attrib.height; - } else { - client->width = client->height = 64; - } + XFree(wmhints); + } else { + client->icon_window = None; + client->window = client->client_window; + } - XSetWindowBorderWidth(display, client->window, 0); + XWindowAttributes attrib; + if (XGetWindowAttributes(display, client->window, &attrib)) { + client->rect.setSize(attrib.width, attrib.height); + } else { + client->rect.setSize(64, 64); + } - XSelectInput(display, frame.window, NoEventMask); - XSelectInput(display, client->window, NoEventMask); + Atom *proto; + int num_return = 0; + if (XGetWMProtocols(display, client->window, &proto, &num_return)) { + for (int i = 0; i < num_return; ++i) { + if (proto[i] == + blackbox->getXAtom()->getAtom(XAtom::blackbox_structure_messages)) { + screen->addNetizen(new Netizen(screen, client->window)); + } + } + } - XReparentWindow(display, client->window, frame.window, 0, 0); - XMapRaised(display, client->window); - XChangeSaveSet(display, client->window, SetModeInsert); + XSetWindowBorderWidth(display, client->window, 0); - XSelectInput(display, frame.window, SubstructureRedirectMask | - ButtonPressMask | EnterWindowMask | LeaveWindowMask); - XSelectInput(display, client->window, StructureNotifyMask | - SubstructureNotifyMask | EnterWindowMask); - XFlush(display); + XGrabServer(display); + XSelectInput(display, frame.window, NoEventMask); + XSelectInput(display, client->window, NoEventMask); + XReparentWindow(display, client->window, frame.window, 0, 0); + XMapRaised(display, client->window); + XChangeSaveSet(display, client->window, SetModeInsert); + XSelectInput(display, frame.window, SubstructureRedirectMask | + ButtonPressMask | EnterWindowMask | LeaveWindowMask); + XSelectInput(display, client->window, StructureNotifyMask | + SubstructureNotifyMask | EnterWindowMask); - clientList->insert(client); + XUngrabServer(display); - openbox.saveSlitSearch(client->client_window, this); - openbox.saveSlitSearch(client->icon_window, this); - reconfigure(); - } + clientList.push_back(client); - openbox.ungrab(); + blackbox->saveSlitSearch(client->client_window, this); + blackbox->saveSlitSearch(client->icon_window, this); + reconfigure(); } -void Slit::removeClient(SlitClient *client, Bool remap) { - openbox.removeSlitSearch(client->client_window); - openbox.removeSlitSearch(client->icon_window); - clientList->remove(client); +void Slit::removeClient(SlitClient *client, bool remap) { + blackbox->removeSlitSearch(client->client_window); + blackbox->removeSlitSearch(client->icon_window); + clientList.remove(client); - screen.removeNetizen(client->window); + screen->removeNetizen(client->window); - if (remap && openbox.validateWindow(client->window)) { + if (remap && blackbox->validateWindow(client->window)) { + XGrabServer(display); XSelectInput(display, frame.window, NoEventMask); XSelectInput(display, client->window, NoEventMask); - XReparentWindow(display, client->window, screen.getRootWindow(), - client->x, client->y); + XReparentWindow(display, client->window, screen->getRootWindow(), + client->rect.x(), client->rect.y()); XChangeSaveSet(display, client->window, SetModeDelete); XSelectInput(display, frame.window, SubstructureRedirectMask | - ButtonPressMask | EnterWindowMask | LeaveWindowMask); - XFlush(display); + ButtonPressMask | EnterWindowMask | LeaveWindowMask); + XUngrabServer(display); } delete client; @@ -187,119 +191,195 @@ void Slit::removeClient(SlitClient *client, Bool remap) { } -void Slit::removeClient(Window w, Bool remap) { - openbox.grab(); +struct SlitClientMatch { + Window window; + SlitClientMatch(Window w): window(w) {} + inline bool operator()(const Slit::SlitClient* client) const { + return (client->window == window); + } +}; - Bool reconf = False; - LinkedListIterator it(clientList); - for (SlitClient *tmp = it.current(); tmp; it++, tmp = it.current()) { - if (tmp->window == w) { - removeClient(tmp, remap); - reconf = True; +void Slit::removeClient(Window w, bool remap) { + SlitClientList::iterator it = clientList.begin(); + const SlitClientList::iterator end = clientList.end(); - break; - } + it = std::find_if(it, end, SlitClientMatch(w)); + if (it != end) { + removeClient(*it, remap); + reconfigure(); + } +} + + +void Slit::saveOnTop(bool b) { + on_top = b; + config->setValue(slitstr + "onTop", on_top); +} + +void Slit::saveAutoHide(bool b) { + do_auto_hide = b; + config->setValue(slitstr + "autoHide", do_auto_hide); +} + +void Slit::savePlacement(int p) { + placement = p; + const char *pname; + switch (placement) { + case TopLeft: pname = "TopLeft"; break; + case CenterLeft: pname = "CenterLeft"; break; + case BottomLeft: pname = "BottomLeft"; break; + case TopCenter: pname = "TopCenter"; break; + case BottomCenter: pname = "BottomCenter"; break; + case TopRight: pname = "TopRight"; break; + case BottomRight: pname = "BottomRight"; break; + case CenterRight: default: pname = "CenterRight"; break; } + config->setValue(slitstr + "placement", pname); +} + +void Slit::saveDirection(int d) { + direction = d; + config->setValue(slitstr + "direction", (direction == Horizontal ? + "Horizontal" : "Vertical")); +} - if (reconf) reconfigure(); +void Slit::save_rc(void) { + saveOnTop(on_top); + saveAutoHide(do_auto_hide); + savePlacement(placement); + saveDirection(direction); +} + +void Slit::load_rc(void) { + std::string s; + + if (! config->getValue(slitstr + "onTop", on_top)) + on_top = false; - openbox.ungrab(); + if (! config->getValue(slitstr + "autoHide", do_auto_hide)) + do_auto_hide = false; + hidden = do_auto_hide; + + if (config->getValue(slitstr + "direction", s) && s == "Horizontal") + direction = Horizontal; + else + direction = Vertical; + + if (config->getValue(slitstr + "placement", s)) { + if (s == "TopLeft") + placement = TopLeft; + else if (s == "CenterLeft") + placement = CenterLeft; + else if (s == "BottomLeft") + placement = BottomLeft; + else if (s == "TopCenter") + placement = TopCenter; + else if (s == "BottomCenter") + placement = BottomCenter; + else if (s == "TopRight") + placement = TopRight; + else if (s == "BottomRight") + placement = BottomRight; + else //if (s == "CenterRight") + placement = CenterRight; + } else + placement = CenterRight; } void Slit::reconfigure(void) { - frame.width = 0; - frame.height = 0; - LinkedListIterator it(clientList); + SlitClientList::iterator it = clientList.begin(); + const SlitClientList::iterator end = clientList.end(); SlitClient *client; - switch (screen.getSlitDirection()) { + unsigned int width = 0, height = 0; + + switch (direction) { case Vertical: - for (client = it.current(); client; it++, client = it.current()) { - frame.height += client->height + screen.getBevelWidth(); + for (; it != end; ++it) { + client = *it; + height += client->rect.height() + screen->getBevelWidth(); - if (frame.width < client->width) - frame.width = client->width; + if (width < client->rect.width()) + width = client->rect.width(); } - if (frame.width < 1) - frame.width = 1; + if (width < 1) + width = 1; else - frame.width += (screen.getBevelWidth() * 2); + width += (screen->getBevelWidth() * 2); - if (frame.height < 1) - frame.height = 1; + if (height < 1) + height = 1; else - frame.height += screen.getBevelWidth(); + height += screen->getBevelWidth(); break; case Horizontal: - for (client = it.current(); client; it++, client = it.current()) { - frame.width += client->width + screen.getBevelWidth(); + for (; it != end; ++it) { + client = *it; + width += client->rect.width() + screen->getBevelWidth(); - if (frame.height < client->height) - frame.height = client->height; + if (height < client->rect.height()) + height = client->rect.height(); } - if (frame.width < 1) - frame.width = 1; + if (width < 1) + width = 1; else - frame.width += screen.getBevelWidth(); + width += screen->getBevelWidth(); - if (frame.height < 1) - frame.height = 1; + if (height < 1) + height = 1; else - frame.height += (screen.getBevelWidth() * 2); + height += (screen->getBevelWidth() * 2); break; } + frame.rect.setSize(width, height); reposition(); - XSetWindowBorderWidth(display ,frame.window, screen.getBorderWidth()); + XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth()); XSetWindowBorder(display, frame.window, - screen.getBorderColor()->getPixel()); + screen->getBorderColor()->pixel()); - if (! clientList->count()) + if (clientList.empty()) XUnmapWindow(display, frame.window); else XMapWindow(display, frame.window); - Pixmap tmp = frame.pixmap; - BImageControl *image_ctrl = screen.getImageControl(); - BTexture *texture = &(screen.getToolbarStyle()->toolbar); - if (texture->getTexture() == (BImage_Flat | BImage_Solid)) { - frame.pixmap = None; - XSetWindowBackground(display, frame.window, - texture->getColor()->getPixel()); - } else { - frame.pixmap = image_ctrl->renderImage(frame.width, frame.height, - texture); + BTexture *texture = &(screen->getToolbarStyle()->toolbar); + frame.pixmap = texture->render(frame.rect.width(), frame.rect.height(), + frame.pixmap); + if (! frame.pixmap) + XSetWindowBackground(display, frame.window, texture->color().pixel()); + else XSetWindowBackgroundPixmap(display, frame.window, frame.pixmap); - } - if (tmp) image_ctrl->removeImage(tmp); + XClearWindow(display, frame.window); + it = clientList.begin(); + int x, y; - it.reset(); - switch (screen.getSlitDirection()) { + switch (direction) { case Vertical: x = 0; - y = screen.getBevelWidth(); + y = screen->getBevelWidth(); - for (client = it.current(); client; it++, client = it.current()) { - x = (frame.width - client->width) / 2; + for (; it != end; ++it) { + client = *it; + x = (frame.rect.width() - client->rect.width()) / 2; XMoveResizeWindow(display, client->window, x, y, - client->width, client->height); + client->rect.width(), client->rect.height()); XMapWindow(display, client->window); // for ICCCM compliance - client->x = x; - client->y = y; + client->rect.setPos(x, y); XEvent event; event.type = ConfigureNotify; @@ -309,33 +389,33 @@ void Slit::reconfigure(void) { event.xconfigure.window = client->window; event.xconfigure.x = x; event.xconfigure.y = y; - event.xconfigure.width = client->width; - event.xconfigure.height = client->height; + event.xconfigure.width = client->rect.width(); + event.xconfigure.height = client->rect.height(); event.xconfigure.border_width = 0; event.xconfigure.above = frame.window; event.xconfigure.override_redirect = False; XSendEvent(display, client->window, False, StructureNotifyMask, &event); - y += client->height + screen.getBevelWidth(); + y += client->rect.height() + screen->getBevelWidth(); } break; case Horizontal: - x = screen.getBevelWidth(); + x = screen->getBevelWidth(); y = 0; - for (client = it.current(); client; it++, client = it.current()) { - y = (frame.height - client->height) / 2; + for (; it != end; ++it) { + client = *it; + y = (frame.rect.height() - client->rect.height()) / 2; XMoveResizeWindow(display, client->window, x, y, - client->width, client->height); + client->rect.width(), client->rect.height()); XMapWindow(display, client->window); // for ICCCM compliance - client->x = x; - client->y = y; + client->rect.setPos(x, y); XEvent event; event.type = ConfigureNotify; @@ -345,17 +425,16 @@ void Slit::reconfigure(void) { event.xconfigure.window = client->window; event.xconfigure.x = x; event.xconfigure.y = y; - event.xconfigure.width = client->width; - event.xconfigure.height = client->height; + event.xconfigure.width = client->rect.width(); + event.xconfigure.height = client->rect.height(); event.xconfigure.border_width = 0; event.xconfigure.above = frame.window; event.xconfigure.override_redirect = False; XSendEvent(display, client->window, False, StructureNotifyMask, &event); - x += client->width + screen.getBevelWidth(); + x += client->rect.width() + screen->getBevelWidth(); } - break; } @@ -363,149 +442,174 @@ void Slit::reconfigure(void) { } -void Slit::reposition(void) { - // place the slit in the appropriate place - switch (screen.getSlitPlacement()) { - case TopLeft: - frame.x = 0; - frame.y = 0; - if (screen.getSlitDirection() == Vertical) { - frame.x_hidden = screen.getBevelWidth() - screen.getBorderWidth() - - frame.width; - frame.y_hidden = 0; - } else { - frame.x_hidden = 0; - frame.y_hidden = screen.getBevelWidth() - screen.getBorderWidth() - - frame.height; +void Slit::updateStrut(void) { + strut.top = strut.bottom = strut.left = strut.right = 0; + + if (! clientList.empty()) { + // when not hidden both borders are in use, when hidden only one is + unsigned int border_width = screen->getBorderWidth(); + if (! do_auto_hide) + border_width *= 2; + + switch (direction) { + case Vertical: + switch (placement) { + case TopCenter: + strut.top = getExposedHeight() + border_width; + break; + case BottomCenter: + strut.bottom = getExposedHeight() + border_width; + break; + case TopLeft: + case CenterLeft: + case BottomLeft: + strut.left = getExposedWidth() + border_width; + break; + case TopRight: + case CenterRight: + case BottomRight: + strut.right = getExposedWidth() + border_width; + break; + } + break; + case Horizontal: + switch (placement) { + case TopCenter: + case TopLeft: + case TopRight: + strut.top = frame.rect.top() + getExposedHeight() + border_width; + break; + case BottomCenter: + case BottomLeft: + case BottomRight: + int pos; + if (do_auto_hide) + pos = frame.y_hidden; + else + pos = frame.rect.y(); + strut.bottom = (screen->getRect().bottom() - pos); + break; + case CenterLeft: + strut.left = getExposedWidth() + border_width; + break; + case CenterRight: + strut.right = getExposedWidth() + border_width; + break; + } + break; } - break; + } - case CenterLeft: - frame.x = 0; - frame.y = (screen.size().h() - frame.height) / 2; - frame.x_hidden = screen.getBevelWidth() - screen.getBorderWidth() - - frame.width; - frame.y_hidden = frame.y; - break; + // update area with new Strut info + screen->updateAvailableArea(); +} + +void Slit::reposition(void) { + int x = 0, y = 0; + + switch (placement) { + case TopLeft: + case CenterLeft: case BottomLeft: - frame.x = 0; - frame.y = screen.size().h() - frame.height - - (screen.getBorderWidth() * 2); - if (screen.getSlitDirection() == Vertical) { - frame.x_hidden = screen.getBevelWidth() - screen.getBorderWidth() - - frame.width; - frame.y_hidden = frame.y; - } else { - frame.x_hidden = 0; - frame.y_hidden = screen.size().h() - screen.getBevelWidth() - - screen.getBorderWidth(); - } - break; + x = 0; + frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth() + - frame.rect.width(); + + if (placement == TopLeft) + y = 0; + else if (placement == CenterLeft) + y = (screen->getHeight() - frame.rect.height()) / 2; + else + y = screen->getHeight() - frame.rect.height() + - (screen->getBorderWidth() * 2); - case TopCenter: - frame.x = (screen.size().w() - frame.width) / 2; - frame.y = 0; - frame.x_hidden = frame.x; - frame.y_hidden = screen.getBevelWidth() - screen.getBorderWidth() - - frame.height; break; + case TopCenter: case BottomCenter: - frame.x = (screen.size().h() - frame.width) / 2; - frame.y = screen.size().h() - frame.height - - (screen.getBorderWidth() * 2); - frame.x_hidden = frame.x; - frame.y_hidden = screen.size().h() - screen.getBevelWidth() - - screen.getBorderWidth(); - break; + x = (screen->getWidth() - frame.rect.width()) / 2; + frame.x_hidden = x; - case TopRight: - frame.x = screen.size().w() - frame.width - - (screen.getBorderWidth() * 2); - frame.y = 0; - if (screen.getSlitDirection() == Vertical) { - frame.x_hidden = screen.size().w() - screen.getBevelWidth() - - screen.getBorderWidth(); - frame.y_hidden = 0; - } else { - frame.x_hidden = frame.x; - frame.y_hidden = screen.getBevelWidth() - screen.getBorderWidth() - - frame.height; - } - break; + if (placement == TopCenter) + y = 0; + else + y = screen->getHeight() - frame.rect.height() + - (screen->getBorderWidth() * 2); - case CenterRight: - default: - frame.x = screen.size().w() - frame.width - - (screen.getBorderWidth() * 2); - frame.y = (screen.size().h() - frame.height) / 2; - frame.x_hidden = screen.size().w() - screen.getBevelWidth() - - screen.getBorderWidth(); - frame.y_hidden = frame.y; break; + case TopRight: + case CenterRight: case BottomRight: - frame.x = screen.size().w() - frame.width - - (screen.getBorderWidth() * 2); - frame.y = screen.size().h() - frame.height - - (screen.getBorderWidth() * 2); - if (screen.getSlitDirection() == Vertical) { - frame.x_hidden = screen.size().w() - screen.getBevelWidth() - - screen.getBorderWidth(); - frame.y_hidden = frame.y; - } else { - frame.x_hidden = frame.x; - frame.y_hidden = screen.size().h() - screen.getBevelWidth() - - screen.getBorderWidth(); - } + x = screen->getWidth() - frame.rect.width() + - (screen->getBorderWidth() * 2); + frame.x_hidden = screen->getWidth() - screen->getBevelWidth() + - screen->getBorderWidth(); + + if (placement == TopRight) + y = 0; + else if (placement == CenterRight) + y = (screen->getHeight() - frame.rect.height()) / 2; + else + y = screen->getHeight() - frame.rect.height() + - (screen->getBorderWidth() * 2); break; } - Toolbar *tbar = screen.getToolbar(); - int sw = frame.width + (screen.getBorderWidth() * 2), - sh = frame.height + (screen.getBorderWidth() * 2), - tw = tbar->getWidth() + screen.getBorderWidth(), - th = tbar->getHeight() + screen.getBorderWidth(); - - if (tbar->getX() < frame.x + sw && tbar->getX() + tw > frame.x && - tbar->getY() < frame.y + sh && tbar->getY() + th > frame.y) { - if (frame.y < th) { - frame.y += tbar->getExposedHeight(); - if (screen.getSlitDirection() == Vertical) - frame.y_hidden += tbar->getExposedHeight(); - else - frame.y_hidden = frame.y; - } else { - frame.y -= tbar->getExposedHeight(); - if (screen.getSlitDirection() == Vertical) - frame.y_hidden -= tbar->getExposedHeight(); - else - frame.y_hidden = frame.y; - } + frame.rect.setPos(x, y); + + // we have to add the border to the rect as it is not accounted for + Rect tbar_rect = screen->getToolbar()->getRect(); + tbar_rect.setSize(tbar_rect.width() + (screen->getBorderWidth() * 2), + tbar_rect.height() + (screen->getBorderWidth() * 2)); + Rect slit_rect = frame.rect; + slit_rect.setSize(slit_rect.width() + (screen->getBorderWidth() * 2), + slit_rect.height() + (screen->getBorderWidth() * 2)); + + if (! screen->doHideToolbar() && slit_rect.intersects(tbar_rect)) { + int delta = screen->getToolbar()->getExposedHeight() + + screen->getBorderWidth(); + if (frame.rect.bottom() <= tbar_rect.bottom()) + delta = -delta; + + frame.rect.setY(frame.rect.y() + delta); } + if (placement == TopCenter) + frame.y_hidden = 0 - frame.rect.height() + screen->getBorderWidth() + + screen->getBevelWidth(); + else if (placement == BottomCenter) + frame.y_hidden = screen->getHeight() - screen->getBorderWidth() + - screen->getBevelWidth(); + else + frame.y_hidden = frame.rect.y(); + + updateStrut(); + if (hidden) - XMoveResizeWindow(display, frame.window, frame.x_hidden, - frame.y_hidden, frame.width, frame.height); + XMoveResizeWindow(display, frame.window, + frame.x_hidden, frame.y_hidden, + frame.rect.width(), frame.rect.height()); else - XMoveResizeWindow(display, frame.window, frame.x, - frame.y, frame.width, frame.height); + XMoveResizeWindow(display, frame.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); } void Slit::shutdown(void) { - while (clientList->count()) - removeClient(clientList->first()); + while (! clientList.empty()) + removeClient(clientList.front()); } -void Slit::buttonPressEvent(XButtonEvent *e) { +void Slit::buttonPressEvent(const XButtonEvent *e) { if (e->window != frame.window) return; if (e->button == Button1 && (! on_top)) { Window w[1] = { frame.window }; - screen.raiseWindows(w, 1); + screen->raiseWindows(w, 1); } else if (e->button == Button2 && (! on_top)) { XLowerWindow(display, frame.window); } else if (e->button == Button3) { @@ -517,13 +621,13 @@ void Slit::buttonPressEvent(XButtonEvent *e) { if (x < 0) x = 0; - else if (x + slitmenu->getWidth() > screen.size().w()) - x = screen.size().w() - slitmenu->getWidth(); + else if (x + slitmenu->getWidth() > screen->getWidth()) + x = screen->getWidth() - slitmenu->getWidth(); if (y < 0) y = 0; - else if (y + slitmenu->getHeight() > screen.size().h()) - y = screen.size().h() - slitmenu->getHeight(); + else if (y + slitmenu->getHeight() > screen->getHeight()) + y = screen->getHeight() - slitmenu->getHeight(); slitmenu->move(x, y); slitmenu->show(); @@ -534,7 +638,7 @@ void Slit::buttonPressEvent(XButtonEvent *e) { } -void Slit::enterNotifyEvent(XCrossingEvent *) { +void Slit::enterNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return; @@ -546,7 +650,7 @@ void Slit::enterNotifyEvent(XCrossingEvent *) { } -void Slit::leaveNotifyEvent(XCrossingEvent *) { +void Slit::leaveNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return; @@ -558,72 +662,85 @@ void Slit::leaveNotifyEvent(XCrossingEvent *) { } -void Slit::configureRequestEvent(XConfigureRequestEvent *e) { - openbox.grab(); - - if (openbox.validateWindow(e->window)) { - Bool reconf = False; - XWindowChanges xwc; +void Slit::configureRequestEvent(const XConfigureRequestEvent *e) { + if (! blackbox->validateWindow(e->window)) + return; - xwc.x = e->x; - xwc.y = e->y; - xwc.width = e->width; - xwc.height = e->height; - xwc.border_width = 0; - xwc.sibling = e->above; - xwc.stack_mode = e->detail; + XWindowChanges xwc; + + xwc.x = e->x; + xwc.y = e->y; + xwc.width = e->width; + xwc.height = e->height; + xwc.border_width = 0; + xwc.sibling = e->above; + xwc.stack_mode = e->detail; + + XConfigureWindow(display, e->window, e->value_mask, &xwc); + + SlitClientList::iterator it = clientList.begin(); + const SlitClientList::iterator end = clientList.end(); + for (; it != end; ++it) { + SlitClient *client = *it; + if (client->window == e->window && + (static_cast(client->rect.width()) != e->width || + static_cast(client->rect.height()) != e->height)) { + client->rect.setSize(e->width, e->height); + + reconfigure(); + return; + } + } +} - XConfigureWindow(display, e->window, e->value_mask, &xwc); - LinkedListIterator it(clientList); - SlitClient *client = it.current(); - for (; client; it++, client = it.current()) - if (client->window == e->window) - if (client->width != ((unsigned) e->width) || - client->height != ((unsigned) e->height)) { - client->width = (unsigned) e->width; - client->height = (unsigned) e->height; +void Slit::timeout(void) { + hidden = ! hidden; + if (hidden) + XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden); + else + XMoveWindow(display, frame.window, frame.rect.x(), frame.rect.y()); +} - reconf = True; - break; - } +void Slit::toggleAutoHide(void) { + saveAutoHide(do_auto_hide ? False : True); - if (reconf) reconfigure(); + updateStrut(); + if (do_auto_hide == False && hidden) { + // force the slit to be visible + if (timer->isTiming()) timer->stop(); + timeout(); } - - openbox.ungrab(); } -void Slit::timeout(void) { - hidden = ! hidden; - if (hidden) - XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden); - else - XMoveWindow(display, frame.window, frame.x, frame.y); +void Slit::unmapNotifyEvent(const XUnmapEvent *e) { + removeClient(e->window); } -Slitmenu::Slitmenu(Slit &sl) : Basemenu(sl.screen), slit(sl) { - setLabel(i18n->getMessage(SlitSet, SlitSlitTitle, "Slit")); +Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) { + slit = sl; + + setLabel(i18n(SlitSet, SlitSlitTitle, "Slit")); setInternalMenu(); - directionmenu = new Directionmenu(*this); - placementmenu = new Placementmenu(*this); + directionmenu = new Directionmenu(this); + placementmenu = new Placementmenu(this); - insert(i18n->getMessage(CommonSet, CommonDirectionTitle, "Direction"), - directionmenu); - insert(i18n->getMessage(CommonSet, CommonPlacementTitle, "Placement"), - placementmenu); - insert(i18n->getMessage(CommonSet, CommonAlwaysOnTop, "Always on top"), 1); - insert(i18n->getMessage(CommonSet, CommonAutoHide, "Auto hide"), 2); + insert(i18n(CommonSet, CommonDirectionTitle, "Direction"), + directionmenu); + insert(i18n(CommonSet, CommonPlacementTitle, "Placement"), + placementmenu); + insert(i18n(CommonSet, CommonAlwaysOnTop, "Always on top"), 1); + insert(i18n(CommonSet, CommonAutoHide, "Auto hide"), 2); update(); - if (slit.isOnTop()) setItemSelected(2, True); - if (slit.doAutoHide()) setItemSelected(3, True); + if (slit->isOnTop()) setItemSelected(2, True); + if (slit->doAutoHide()) setItemSelected(3, True); } @@ -633,7 +750,7 @@ Slitmenu::~Slitmenu(void) { } -void Slitmenu::itemSelected(int button, int index) { +void Slitmenu::itemSelected(int button, unsigned int index) { if (button != 1) return; @@ -642,18 +759,16 @@ void Slitmenu::itemSelected(int button, int index) { switch (item->function()) { case 1: { // always on top - Bool change = ((slit.isOnTop()) ? False : True); - slit.on_top = change; - setItemSelected(2, change); + slit->saveOnTop(! slit->isOnTop()); + setItemSelected(2, slit->isOnTop()); - if (slit.isOnTop()) slit.screen.raiseWindows((Window *) 0, 0); + if (slit->isOnTop()) slit->screen->raiseWindows((Window *) 0, 0); break; } case 2: { // auto hide - Bool change = ((slit.doAutoHide()) ? False : True); - slit.do_auto_hide = change; - setItemSelected(3, change); + slit->toggleAutoHide(); + setItemSelected(3, slit->doAutoHide()); break; } @@ -663,8 +778,8 @@ void Slitmenu::itemSelected(int button, int index) { void Slitmenu::internal_hide(void) { Basemenu::internal_hide(); - if (slit.doAutoHide()) - slit.timeout(); + if (slit->doAutoHide()) + slit->timeout(); } @@ -676,90 +791,125 @@ void Slitmenu::reconfigure(void) { } -Slitmenu::Directionmenu::Directionmenu(Slitmenu &sm) - : Basemenu(sm.slit.screen), slitmenu(sm) { - setLabel(i18n->getMessage(SlitSet, SlitSlitDirection, "Slit Direction")); +Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm) + : Basemenu(sm->slit->screen), slit(sm->slit) { + + setLabel(i18n(SlitSet, SlitSlitDirection, "Slit Direction")); setInternalMenu(); - insert(i18n->getMessage(CommonSet, CommonDirectionHoriz, "Horizontal"), - Slit::Horizontal); - insert(i18n->getMessage(CommonSet, CommonDirectionVert, "Vertical"), - Slit::Vertical); + insert(i18n(CommonSet, CommonDirectionHoriz, "Horizontal"), + Slit::Horizontal); + insert(i18n(CommonSet, CommonDirectionVert, "Vertical"), + Slit::Vertical); update(); + setValues(); +} - if (sm.slit.screen.getSlitDirection() == Slit::Horizontal) - setItemSelected(0, True); - else - setItemSelected(1, True); + +void Slitmenu::Directionmenu::reconfigure(void) { + setValues(); + Basemenu::reconfigure(); +} + + +void Slitmenu::Directionmenu::setValues(void) { + const bool horiz = slit->getDirection() == Slit::Horizontal; + setItemSelected(0, horiz); + setItemSelected(1, ! horiz); } -void Slitmenu::Directionmenu::itemSelected(int button, int index) { +void Slitmenu::Directionmenu::itemSelected(int button, unsigned int index) { if (button != 1) return; BasemenuItem *item = find(index); if (! item) return; - slitmenu.slit.screen.saveSlitDirection(item->function()); - - if (item->function() == Slit::Horizontal) { - setItemSelected(0, True); - setItemSelected(1, False); - } else { - setItemSelected(0, False); - setItemSelected(1, True); - } - + slit->saveDirection(item->function()); hide(); - slitmenu.slit.reconfigure(); + slit->reconfigure(); } -Slitmenu::Placementmenu::Placementmenu(Slitmenu &sm) - : Basemenu(sm.slit.screen), slitmenu(sm) { +Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm) + : Basemenu(sm->slit->screen), slit(sm->slit) { - setLabel(i18n->getMessage(SlitSet, SlitSlitPlacement, "Slit Placement")); + setLabel(i18n(SlitSet, SlitSlitPlacement, "Slit Placement")); setMinimumSublevels(3); setInternalMenu(); - insert(i18n->getMessage(CommonSet, CommonPlacementTopLeft, "Top Left"), - Slit::TopLeft); - insert(i18n->getMessage(CommonSet, CommonPlacementCenterLeft, "Center Left"), - Slit::CenterLeft); - insert(i18n->getMessage(CommonSet, CommonPlacementBottomLeft, "Bottom Left"), - Slit::BottomLeft); - insert(i18n->getMessage(CommonSet, CommonPlacementTopCenter, "Top Center"), - Slit::TopCenter); + insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"), + Slit::TopLeft); + insert(i18n(CommonSet, CommonPlacementCenterLeft, "Center Left"), + Slit::CenterLeft); + insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"), + Slit::BottomLeft); + insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"), + Slit::TopCenter); insert(""); - insert(i18n->getMessage(CommonSet, CommonPlacementBottomCenter, - "Bottom Center"), - Slit::BottomCenter); - insert(i18n->getMessage(CommonSet, CommonPlacementTopRight, "Top Right"), - Slit::TopRight); - insert(i18n->getMessage(CommonSet, CommonPlacementCenterRight, - "Center Right"), - Slit::CenterRight); - insert(i18n->getMessage(CommonSet, CommonPlacementBottomRight, - "Bottom Right"), - Slit::BottomRight); + insert(i18n(CommonSet, CommonPlacementBottomCenter, "Bottom Center"), + Slit::BottomCenter); + insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"), + Slit::TopRight); + insert(i18n(CommonSet, CommonPlacementCenterRight, "Center Right"), + Slit::CenterRight); + insert(i18n(CommonSet, CommonPlacementBottomRight, "Bottom Right"), + Slit::BottomRight); update(); + + setValues(); +} + + +void Slitmenu::Placementmenu::reconfigure(void) { + setValues(); + Basemenu::reconfigure(); +} + + +void Slitmenu::Placementmenu::setValues(void) { + int place = 0; + switch (slit->getPlacement()) { + case Slit::BottomRight: + place++; + case Slit::CenterRight: + place++; + case Slit::TopRight: + place++; + case Slit::BottomCenter: + place++; + case Slit::TopCenter: + place++; + case Slit::BottomLeft: + place++; + case Slit::CenterLeft: + place++; + case Slit::TopLeft: + break; + } + setItemSelected(0, 0 == place); + setItemSelected(1, 1 == place); + setItemSelected(2, 2 == place); + setItemSelected(3, 3 == place); + setItemSelected(5, 4 == place); + setItemSelected(6, 5 == place); + setItemSelected(7, 6 == place); + setItemSelected(8, 7 == place); } -void Slitmenu::Placementmenu::itemSelected(int button, int index) { +void Slitmenu::Placementmenu::itemSelected(int button, unsigned int index) { if (button != 1) return; BasemenuItem *item = find(index); if (! (item && item->function())) return; - slitmenu.slit.screen.saveSlitPlacement(item->function()); + slit->savePlacement(item->function()); hide(); - slitmenu.slit.reconfigure(); + slit->reconfigure(); } - -#endif // SLIT