// 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 "Window.hh"
#include "Workspace.hh"
#include "Workspacemenu.hh"
+#include "Util.hh"
#include "XAtom.hh"
#ifndef FONT_ELEMENT_SIZE
iconmenu = new Iconmenu(this);
configmenu = new Configmenu(this);
- Workspace *wkspc = (Workspace *) 0;
if (resource.workspaces != 0) {
for (unsigned int i = 0; i < resource.workspaces; ++i) {
- wkspc = new Workspace(this, workspacesList.size());
+ Workspace *wkspc = new Workspace(this, workspacesList.size());
workspacesList.push_back(wkspc);
- workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
+ workspacemenu->insertWorkspace(wkspc);
+ workspacemenu->update();
+
}
} else {
- wkspc = new Workspace(this, workspacesList.size());
+ Workspace *wkspc = new Workspace(this, workspacesList.size());
workspacesList.push_back(wkspc);
- workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
+ workspacemenu->insertWorkspace(wkspc);
+ workspacemenu->update();
}
saveWorkspaceNames();
raiseWindows(0, 0); // this also initializes the empty stacking list
rootmenu->update();
- updateClientList(); // initialize the client list, which will be empty
+ updateClientList(); // initialize the client lists, which will be empty
updateAvailableArea();
changeWorkspaceID(0);
std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin());
+ while (! systrayWindowList.empty())
+ removeSystrayWindow(systrayWindowList[0]);
+
delete rootmenu;
delete workspacemenu;
delete iconmenu;
}
+void BScreen::saveAAFonts(bool f) {
+ resource.aa_fonts = f;
+ reconfigure();
+ config->setValue(screenstr + "antialiasFonts", resource.aa_fonts);
+}
+
+
void BScreen::saveHideToolbar(bool h) {
resource.hide_toolbar = h;
if (resource.hide_toolbar)
}
+void BScreen::saveResizeZones(unsigned int z) {
+ resource.resize_zones = z;
+ config->setValue(screenstr + "resizeZones", resource.resize_zones);
+}
+
+
void BScreen::saveWindowCornerSnap(bool s) {
resource.window_corner_snap = s;
config->setValue(screenstr + "windowCornerSnap",
const char *placement;
switch (resource.placement_policy) {
case CascadePlacement: placement = "CascadePlacement"; break;
+ case UnderMousePlacement: placement = "UnderMousePlacement"; break;
+ case ClickMousePlacement: placement = "ClickMousePlacement"; break;
case ColSmartPlacement: placement = "ColSmartPlacement"; break;
case RowSmartPlacement: default: placement = "RowSmartPlacement"; break;
}
}
-void BScreen::saveClock24Hour(Bool c) {
+void BScreen::saveClock24Hour(bool c) {
resource.clock24hour = c;
config->setValue(screenstr + "clockFormat", resource.clock24hour ? 24 : 12);
}
void BScreen::saveWorkspaceNames() {
- XAtom::StringVect nameList;
- unsigned long numnames = (unsigned) -1;
string names;
- if (numnames > 0 &&
- xatom->getValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8,
- numnames, nameList)) {
- for (unsigned int i = 0; i < nameList.size(); ++i) {
- if (i > 0) names += ",";
- names += nameList[i];
- }
+ for (unsigned int i = 0; i < workspacesList.size(); ++i) {
+ names += workspacesList[i]->getName();
+ if (i < workspacesList.size() - 1)
+ names += ',';
}
+
config->setValue(screenstr + "workspaceNames", names);
}
+void BScreen::savePlaceIgnoreShaded(bool i) {
+ resource.ignore_shaded = i;
+ config->setValue(screenstr + "placementIgnoreShaded",
+ resource.ignore_shaded);
+}
+
+
+void BScreen::savePlaceIgnoreMaximized(bool i) {
+ resource.ignore_maximized = i;
+ config->setValue(screenstr + "placementIgnoreMaximized",
+ resource.ignore_maximized);
+}
+
+
+void BScreen::saveAllowScrollLock(bool a) {
+ resource.allow_scroll_lock = a;
+ config->setValue(screenstr + "disableBindingsWithScrollLock",
+ resource.allow_scroll_lock);
+}
+
+
void BScreen::save_rc(void) {
saveSloppyFocus(resource.sloppy_focus);
saveAutoRaise(resource.auto_raise);
saveImageDither(doImageDither());
+ saveAAFonts(resource.aa_fonts);
+ saveResizeZones(resource.resize_zones);
saveOpaqueMove(resource.opaque_move);
saveFullMax(resource.full_max);
saveFocusNew(resource.focus_new);
saveDateFormat(resource.date_format);
savwClock24Hour(resource.clock24hour);
#endif // HAVE_STRFTIME
+ savePlaceIgnoreShaded(resource.ignore_shaded);
+ savePlaceIgnoreMaximized(resource.ignore_maximized);
+ saveAllowScrollLock(resource.allow_scroll_lock);
toolbar->save_rc();
slit->save_rc();
if (! config->getValue(screenstr + "opaqueMove", resource.opaque_move))
resource.opaque_move = false;
+ if (! config->getValue(screenstr + "antialiasFonts", resource.aa_fonts))
+ resource.aa_fonts = true;
+
+ if (! config->getValue(screenstr + "resizeZones", resource.resize_zones) ||
+ (resource.resize_zones != 1 && resource.resize_zones != 2 &&
+ resource.resize_zones != 4))
+ resource.resize_zones = 4;
+
if (! config->getValue(screenstr + "hideToolbar", resource.hide_toolbar))
resource.hide_toolbar = false;
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;
if (config->getValue(screenstr + "windowPlacement", s)) {
if (s == "CascadePlacement")
resource.placement_policy = CascadePlacement;
+ else if (s == "UnderMousePlacement")
+ resource.placement_policy = UnderMousePlacement;
+ else if (s == "ClickMousePlacement")
+ resource.placement_policy = ClickMousePlacement;
else if (s == "ColSmartPlacement")
resource.placement_policy = ColSmartPlacement;
else //if (s == "RowSmartPlacement")
resource.placement_policy = RowSmartPlacement;
#ifdef HAVE_STRFTIME
- if (config->getValue(screenstr + "strftimeFormat", s))
- resource.strftime_format = s;
- else
+ if (! config->getValue(screenstr + "strftimeFormat",
+ resource.strftime_format))
resource.strftime_format = "%I:%M %p";
#else // !HAVE_STRFTIME
long l;
l = 12;
resource.clock24hour = l == 24;
#endif // HAVE_STRFTIME
+
+ if (! config->getValue(screenstr + "placementIgnoreShaded",
+ resource.ignore_shaded))
+ resource.ignore_shaded = true;
+
+ 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;
+}
+
+
+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());
Workspace *wkspc = new Workspace(this, workspacesList.size());
workspacesList.push_back(wkspc);
saveWorkspaces(getWorkspaceCount());
+ saveWorkspaceNames();
- workspacemenu->insert(wkspc->getName(), wkspc->getMenu(),
- wkspc->getID() + 2);
+ workspacemenu->insertWorkspace(wkspc);
workspacemenu->update();
toolbar->reconfigure();
wkspc->removeAll();
- workspacemenu->remove(wkspc->getID() + 2);
+ workspacemenu->removeWorkspace(wkspc);
workspacemenu->update();
workspacesList.pop_back();
delete wkspc;
saveWorkspaces(getWorkspaceCount());
+ saveWorkspaceNames();
toolbar->reconfigure();
void BScreen::changeWorkspaceID(unsigned int id) {
- if (! current_workspace) return;
-
- if (id != current_workspace->getID()) {
- BlackboxWindow *focused = blackbox->getFocusedWindow();
- if (focused && focused->getScreen() == this && ! focused->isStuck()) {
- if (focused->getWorkspaceNumber() != current_workspace->getID()) {
- fprintf(stderr, "%s is on the wrong workspace, aborting\n",
- focused->getTitle());
- abort();
- }
- current_workspace->setLastFocusedWindow(focused);
- } else {
- // if no window had focus, no need to store a last focus
- current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
- }
- // when we switch workspaces, unfocus whatever was focused
- blackbox->setFocusedWindow((BlackboxWindow *) 0);
+ if (! current_workspace || id == current_workspace->getID()) return;
+
+ BlackboxWindow *focused = blackbox->getFocusedWindow();
+ if (focused && focused->getScreen() == this) {
+ assert(focused->isStuck() ||
+ focused->getWorkspaceNumber() == current_workspace->getID());
+
+ current_workspace->setLastFocusedWindow(focused);
+ } else {
+ // if no window had focus, no need to store a last focus
+ current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
+ }
+
+ // when we switch workspaces, unfocus whatever was focused
+ blackbox->setFocusedWindow((BlackboxWindow *) 0);
- current_workspace->hideAll();
- workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
+ current_workspace->hideAll();
+ workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
- current_workspace = getWorkspace(id);
+ current_workspace = getWorkspace(id);
- xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
- XAtom::cardinal, id);
+ xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
+ XAtom::cardinal, id);
- workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
- toolbar->redrawWorkspaceLabel(True);
+ workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
+ toolbar->redrawWorkspaceLabel(True);
- current_workspace->showAll();
+ current_workspace->showAll();
- if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
- XSync(blackbox->getXDisplay(), False);
- current_workspace->getLastFocusedWindow()->setInputFocus();
- }
+ if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
+ XSync(blackbox->getXDisplay(), False);
+ current_workspace->getLastFocusedWindow()->setInputFocus();
}
updateNetizenCurrentWorkspace();
} else
xatom->setValue(getRootWindow(), XAtom::net_client_list, XAtom::window,
0, 0);
+
+ updateStackingList();
}
BlackboxWindowList stack_order;
/*
- * Get the atacking order from all of the workspaces.
+ * Get the stacking order from all of the workspaces.
* We start with the current workspace so that the sticky windows will be
* in the right order on the current workspace.
* XXX: Do we need to have sticky windows in the list once for each workspace?
for (unsigned int i = 0; i < getWorkspaceCount(); ++i)
if (i != getCurrentWorkspaceID())
getWorkspace(i)->appendStackOrder(stack_order);
-
+
if (stack_order.size() > 0) {
// set the client list atoms
Window *windows = new Window[stack_order.size()];
Window *win_it = windows;
- BlackboxWindowList::iterator it = stack_order.begin();
- const BlackboxWindowList::iterator end = stack_order.end();
+ BlackboxWindowList::iterator it = stack_order.begin(),
+ end = stack_order.end();
for (; it != end; ++it, ++win_it)
*win_it = (*it)->getClientWindow();
xatom->setValue(getRootWindow(), XAtom::net_client_list_stacking,
}
-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->isDesktop()) {
- // 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);
}
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::lowerDesktops(void) {
- if (desktopWindowList.empty()) return;
+void BScreen::lowerWindows(Window *workspace_stack, unsigned int num) {
+ assert(num > 0); // this would cause trouble in the XRaiseWindow call
+
+ Window *session_stack = new Window[(num + desktopWindowList.size())];
+ unsigned int i = 0, k = num;
+
+ XLowerWindow(blackbox->getXDisplay(), workspace_stack[0]);
+
+ while (k--)
+ *(session_stack + i++) = *(workspace_stack + k);
+
+ WindowList::iterator dit = desktopWindowList.begin();
+ const WindowList::iterator d_end = desktopWindowList.end();
+ for (; dit != d_end; ++dit)
+ *(session_stack + i++) = *dit;
- XLowerWindow(blackbox->getXDisplay(), desktopWindowList[0]);
- if (desktopWindowList.size() > 1)
- XRestackWindows(blackbox->getXDisplay(), &desktopWindowList[0],
- desktopWindowList.size());
+ XRestackWindows(blackbox->getXDisplay(), session_stack, i);
+
+ delete [] session_stack;
+
+ updateStackingList();
}
getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
getWorkspace(wkspc_id)->addWindow(w);
}
+ updateStackingList();
}
}
+void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) {
+ if (pe->atom == xatom->getAtom(XAtom::net_desktop_names)) {
+ // _NET_WM_DESKTOP_NAMES
+ WorkspaceList::iterator it = workspacesList.begin();
+ const WorkspaceList::iterator end = workspacesList.end();
+ for (; it != end; ++it) {
+ (*it)->readName(); // re-read its name from the window property
+ workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName());
+ }
+ workspacemenu->update();
+ toolbar->reconfigure();
+ saveWorkspaceNames();
+ }
+}
+
+
void BScreen::toggleFocusModel(FocusModel model) {
std::for_each(windowList.begin(), windowList.end(),
std::mem_fun(&BlackboxWindow::ungrabButtons));
}
BFont *b = new BFont(blackbox->getXDisplay(), this, family, i, bold,
- italic);
+ italic, resource.aa_fonts);
if (b->valid())
return b;
else