// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+#ifdef HAVE_CONFIG_H
#include "../config.h"
+#endif // HAVE_CONFIG_H
extern "C" {
#include <X11/Xatom.h>
#include <X11/keysym.h>
+#ifdef XINERAMA
+# include <X11/Xlib.h>
+# include <X11/extensions/Xinerama.h>
+#endif // XINERAMA
+
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
#include "Window.hh"
#include "Workspace.hh"
#include "Workspacemenu.hh"
+#include "Util.hh"
#include "XAtom.hh"
#ifndef FONT_ELEMENT_SIZE
XDefineCursor(blackbox->getXDisplay(), getRootWindow(),
blackbox->getSessionCursor());
- // start off full screen, top left.
- usableArea.setSize(getWidth(), getHeight());
+ updateAvailableArea();
image_control =
new BImageControl(blackbox, this, True, blackbox->getColorsPerChannel(),
iconmenu = new Iconmenu(this);
configmenu = new Configmenu(this);
- if (resource.workspaces != 0) {
+ if (resource.workspaces > 0) {
for (unsigned int i = 0; i < resource.workspaces; ++i) {
Workspace *wkspc = new Workspace(this, workspacesList.size());
workspacesList.push_back(wkspc);
std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin());
- while (! desktopWindowList.empty())
- removeDesktopWindow(desktopWindowList[0]);
-
while (! systrayWindowList.empty())
removeSystrayWindow(systrayWindowList[0]);
}
+void BScreen::saveAllowScrollLock(bool a) {
+ resource.allow_scroll_lock = a;
+ config->setValue(screenstr + "disableBindingsWithScrollLock",
+ resource.allow_scroll_lock);
+}
+
+
+void BScreen::saveWorkspaceWarping(bool w) {
+ resource.workspace_warping = w;
+ config->setValue(screenstr + "workspaceWarping",
+ resource.workspace_warping);
+}
+
+
void BScreen::save_rc(void) {
saveSloppyFocus(resource.sloppy_focus);
saveAutoRaise(resource.auto_raise);
#endif // HAVE_STRFTIME
savePlaceIgnoreShaded(resource.ignore_shaded);
savePlaceIgnoreMaximized(resource.ignore_maximized);
+ saveAllowScrollLock(resource.allow_scroll_lock);
+ saveWorkspaceWarping(resource.workspace_warping);
toolbar->save_rc();
slit->save_rc();
else
resource.col_direction = TopBottom;
- XAtom::StringVect workspaceNames;
if (config->getValue(screenstr + "workspaceNames", s)) {
+ XAtom::StringVect workspaceNames;
+
string::const_iterator it = s.begin(), end = s.end();
while(1) {
string::const_iterator tmp = it; // current string.begin()
break;
++it;
}
+
+ xatom->setValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8,
+ workspaceNames);
}
- xatom->setValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8,
- workspaceNames);
resource.sloppy_focus = true;
resource.auto_raise = false;
else if (s == "UnderMousePlacement")
resource.placement_policy = UnderMousePlacement;
else if (s == "ClickMousePlacement")
- resource.placement_policy = UnderMousePlacement;
+ resource.placement_policy = ClickMousePlacement;
else if (s == "ColSmartPlacement")
resource.placement_policy = ColSmartPlacement;
else //if (s == "RowSmartPlacement")
if (! config->getValue(screenstr + "placementIgnoreMaximized",
resource.ignore_maximized))
resource.ignore_maximized = true;
+
+if (! config->getValue(screenstr + "disableBindingsWithScrollLock",
+ resource.allow_scroll_lock))
+ resource.allow_scroll_lock = false;
+
+ if (! config->getValue(screenstr + "workspaceWarping",
+ resource.workspace_warping))
+ resource.workspace_warping = false;
+}
+
+
+void BScreen::changeWorkspaceCount(unsigned int new_count) {
+ assert(new_count > 0);
+
+ if (new_count < workspacesList.size()) {
+ // shrink
+ for (unsigned int i = workspacesList.size(); i > new_count; --i)
+ removeLastWorkspace();
+ // removeLast already sets the current workspace to the
+ // last available one.
+ } else if (new_count > workspacesList.size()) {
+ // grow
+ for(unsigned int i = workspacesList.size(); i < new_count; ++i)
+ addWorkspace();
+ }
}
void BScreen::reconfigure(void) {
+ // don't reconfigure while saving the initial rc file, it's a waste and it
+ // breaks somethings (workspace names)
+ if (blackbox->isStartup()) return;
+
load_rc();
toolbar->load_rc();
slit->load_rc();
LoadStyle();
+ // we need to do this explicitly, because just loading this value from the rc
+ // does nothing
+ changeWorkspaceCount(resource.workspaces);
+
XGCValues gcv;
gcv.foreground = WhitePixel(blackbox->getXDisplay(),
getScreenNumber());
}
-void BScreen::addDesktopWindow(Window window) {
- desktopWindowList.push_back(window);
- XLowerWindow(blackbox->getXDisplay(), window);
- XSelectInput(blackbox->getXDisplay(), window, StructureNotifyMask);
- blackbox->saveDesktopWindowSearch(window, this);
-}
-
-
-void BScreen::removeDesktopWindow(Window window) {
- WindowList::iterator it = desktopWindowList.begin();
- const WindowList::iterator end = desktopWindowList.end();
- for (; it != end; ++it)
- if (*it == window) {
- desktopWindowList.erase(it);
- XSelectInput(blackbox->getXDisplay(), window, None);
- blackbox->removeDesktopWindowSearch(window);
- break;
- }
-}
-
-
void BScreen::manageWindow(Window w) {
+ // is the window a KDE systray window?
+ Window systray;
+ if (xatom->getValue(w, XAtom::kde_net_wm_system_tray_window_for,
+ XAtom::window, systray) && systray) {
+ addSystrayWindow(w);
+ return;
+ }
+
new BlackboxWindow(blackbox, w, this);
BlackboxWindow *win = blackbox->searchWindow(w);
if (! win)
return;
- if (win->windowType() == BlackboxWindow::Type_Desktop) {
- // desktop windows cant do anything, so we remove all the normal window
- // stuff from them, they are only kept around so that we can keep them on
- // the bottom of the z-order
- win->restore(True);
- addDesktopWindow(win->getClientWindow());
- delete win;
- return;
- }
- windowList.push_back(win);
- updateClientList();
+
+ if (win->isNormal()) {
+ // don't list non-normal windows as managed windows
+ windowList.push_back(win);
+ updateClientList();
+ } else if (win->isDesktop()) {
+ desktopWindowList.push_back(win->getFrameWindow());
+ }
XMapRequestEvent mre;
mre.window = w;
- if (blackbox->isStartup()) win->restoreAttributes();
+ if (blackbox->isStartup() && win->isNormal()) win->restoreAttributes();
win->mapRequestEvent(&mre);
}
void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) {
w->restore(remap);
+ // Remove the modality so that its parent won't try to re-focus the window
+ if (w->isModal()) w->setModal(False);
+
if (w->getWorkspaceNumber() != BSENTINEL &&
w->getWindowNumber() != BSENTINEL)
getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
else if (w->isIconic())
removeIcon(w);
- windowList.remove(w);
- updateClientList();
+ if (w->isNormal()) {
+ // we don't list non-normal windows as managed windows
+ windowList.remove(w);
+ updateClientList();
+ } else if (w->isDesktop()) {
+ WindowList::iterator it = desktopWindowList.begin();
+ const WindowList::iterator end = desktopWindowList.end();
+ for (; it != end; ++it)
+ if (*it == w->getFrameWindow()) {
+ desktopWindowList.erase(it);
+ break;
+ }
+ assert(it != end); // the window wasnt a desktop window?
+ }
if (blackbox->getFocusedWindow() == w)
blackbox->setFocusedWindow((BlackboxWindow *) 0);
void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
// the 13 represents the number of blackbox windows such as menus
+ int bbwins = 13;
+#ifdef XINERAMA
+ ++bbwins;
+#endif // XINERAMA
+
Window *session_stack = new
- Window[(num + workspacesList.size() + rootmenuList.size() + 13)];
+ Window[(num + workspacesList.size() + rootmenuList.size() + bbwins)];
unsigned int i = 0, k = num;
XRaiseWindow(blackbox->getXDisplay(), iconmenu->getWindowID());
*(session_stack + i++) = configmenu->getFocusmenu()->getWindowID();
*(session_stack + i++) = configmenu->getPlacementmenu()->getWindowID();
+#ifdef XINERAMA
+ *(session_stack + i++) = configmenu->getXineramamenu()->getWindowID();
+#endif // XINERAMA
*(session_stack + i++) = configmenu->getWindowID();
*(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID();
}
+#ifdef XINERAMA
+const RectList& BScreen::allAvailableAreas(void) const {
+ assert(isXineramaActive());
+ assert(xineramaUsableArea.size() > 0);
+ fprintf(stderr, "1found x %d y %d w %d h %d\n",
+ xineramaUsableArea[0].x(), xineramaUsableArea[0].y(),
+ xineramaUsableArea[0].width(), xineramaUsableArea[0].height());
+ return xineramaUsableArea;
+}
+#endif // XINERAMA
+
+
void BScreen::updateAvailableArea(void) {
Rect old_area = usableArea;
usableArea = getRect(); // reset to full screen
+#ifdef XINERAMA
+ // reset to the full areas
+ if (isXineramaActive())
+ xineramaUsableArea = getXineramaAreas();
+#endif // XINERAMA
+
/* these values represent offsets from the screen edge
* we look for the biggest offset on each edge and then apply them
* all at once
usableArea.setSize(usableArea.width() - (current_left + current_right),
usableArea.height() - (current_top + current_bottom));
+#ifdef XINERAMA
+ if (isXineramaActive()) {
+ // keep each of the ximerama-defined areas inside the strut
+ RectList::iterator xit, xend = xineramaUsableArea.end();
+ for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) {
+ if (xit->x() < usableArea.x()) {
+ xit->setX(usableArea.x());
+ xit->setWidth(xit->width() - usableArea.x());
+ }
+ if (xit->y() < usableArea.y()) {
+ xit->setY(usableArea.y());
+ xit->setHeight(xit->height() - usableArea.y());
+ }
+ if (xit->x() + xit->width() > usableArea.width())
+ xit->setWidth(usableArea.width() - xit->x());
+ if (xit->y() + xit->height() > usableArea.height())
+ xit->setHeight(usableArea.height() - xit->y());
+ }
+ }
+#endif // XINERAMA
+
if (old_area != usableArea) {
BlackboxWindowList::iterator it = windowList.begin(),
end = windowList.end();
void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) {
if (pe->atom == xatom->getAtom(XAtom::net_desktop_names)) {
// _NET_WM_DESKTOP_NAMES
- fprintf(stderr, "UPDATING WORKSPACE NAMES\n");
WorkspaceList::iterator it = workspacesList.begin();
const WorkspaceList::iterator end = workspacesList.end();
for (; it != end; ++it) {