# include <stdio.h>
# endif // HAVE_STDIO_H
#endif // DEBUG
-}
-#include <cstdlib>
+#ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+#endif // HAVE_STDLIB_H
+}
#include "i18n.hh"
#include "blackbox.hh"
#include "Window.hh"
#include "Windowmenu.hh"
#include "Workspace.hh"
-#include "Slit.hh"
using std::string;
+using std::abs;
// change this to change what modifier keys openbox uses for mouse bindings
// for example: Mod1Mask | ControlMask
return;
}
- // set the eventmask early in the game so that we make sure we get
- // all the events we are interested in
- XSetWindowAttributes attrib_set;
- attrib_set.event_mask = PropertyChangeMask | FocusChangeMask |
- StructureNotifyMask;
- attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
- ButtonMotionMask;
- XChangeWindowAttributes(blackbox->getXDisplay(), client.window,
- CWEventMask|CWDontPropagate, &attrib_set);
-
// fetch client size and placement
XWindowAttributes wattrib;
- if ((! XGetWindowAttributes(blackbox->getXDisplay(),
- client.window, &wattrib)) ||
- (! wattrib.screen) || wattrib.override_redirect) {
+ if (! XGetWindowAttributes(blackbox->getXDisplay(),
+ client.window, &wattrib) ||
+ ! wattrib.screen || wattrib.override_redirect) {
#ifdef DEBUG
fprintf(stderr,
"BlackboxWindow::BlackboxWindow(): XGetWindowAttributes failed\n");
return;
}
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: initial (%d, %d) w: %d, h: %d\n", client.window,
+ wattrib.x, wattrib.y, wattrib.width, wattrib.height);
+#endif // DEBUG
+
+ // set the eventmask early in the game so that we make sure we get
+ // all the events we are interested in
+ XSetWindowAttributes attrib_set;
+ attrib_set.event_mask = PropertyChangeMask | FocusChangeMask |
+ StructureNotifyMask;
+ attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask;
+ XChangeWindowAttributes(blackbox->getXDisplay(), client.window,
+ CWEventMask|CWDontPropagate, &attrib_set);
+
flags.moving = flags.resizing = flags.shaded = flags.visible =
flags.iconic = flags.focused = flags.stuck = flags.modal =
flags.send_focus_message = flags.shaped = flags.skip_taskbar =
Decor_Iconify | Decor_Maximize;
functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
- client.wm_hint_flags = client.normal_hint_flags = 0;
+ client.normal_hint_flags = 0;
client.window_group = None;
client.transient_for = 0;
+ current_state = NormalState;
+
/*
get the initial size and location of client window (relative to the
_root window_). This position is the reference point used with the
getWMHints();
getWMNormalHints();
- if (client.initial_state == WithdrawnState) {
- screen->getSlit()->addClient(client.window);
- delete this;
- return;
- }
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: after hints (%d, %d) w: %d, h: %d\n", client.window,
+ client.rect.x(), client.rect.y(),
+ client.rect.width(), client.rect.height());
+#endif // DEBUG
frame.window = createToplevelWindow();
frame.plate = createChildWindow(frame.window);
}
upsize();
+#ifdef DFEBUG
+ fprintf(stderr, "0x%lx: sizes reflect the frame from now on\n",
+ client.window);
+ fprintf(stderr, "0x%lx: after upsize (%d, %d) w: %d, h: %d\n", client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
+
setAllowedActions();
bool place_window = True;
place_window = False;
}
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: after gravity (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
+
// add the window's strut. note this is done *after* placing the window.
screen->addStrut(&client.strut);
updateStrut();
// place the window
configure(frame.rect.x(), frame.rect.y(),
frame.rect.width(), frame.rect.height());
+
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: after configure (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
}
// preserve the window's initial state on first map, and its current state
// across a restart
- if (! getState()) {
- if (client.wm_hint_flags & StateHint)
- current_state = client.initial_state;
- else
- current_state = NormalState;
- }
+ unsigned long initial_state = current_state;
+ if (! getState())
+ current_state = initial_state;
// get sticky state from our parent window if we've got one
if (isTransient() && client.transient_for != (BlackboxWindow *) ~0ul &&
if (flags.shaded) {
flags.shaded = False;
- unsigned long orig_state = current_state;
+ initial_state = current_state;
shade();
/*
At this point in the life of a window, current_state should only be set
to IconicState if the window was an *icon*, not if it was shaded.
*/
- if (orig_state != IconicState)
+ if (initial_state != IconicState)
current_state = NormalState;
}
stick();
}
- if (flags.maximized && (functions & Func_Maximize)) {
+ if (flags.maximized && (functions & Func_Maximize))
remaximize();
- }
/*
When the window is mapped (and also when its attributes are restored), the
XMapSubwindows(blackbox->getXDisplay(), frame.window);
redrawWindowFrame();
+
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: end of constructor (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
}
void BlackboxWindow::ungrabButtons(void) {
- if ((! screen->isSloppyFocus()) || screen->doClickRaise())
+ if (! screen->isSloppyFocus() || screen->doClickRaise())
blackbox->ungrabButton(Button1, 0, frame.plate);
blackbox->ungrabButton(Button1, ModMask, frame.window);
if (proto[i] == xatom->getAtom(XAtom::wm_delete_window)) {
decorations |= Decor_Close;
functions |= Func_Close;
- } else if (proto[i] == xatom->getAtom(XAtom::wm_take_focus))
+ } else if (proto[i] == xatom->getAtom(XAtom::wm_take_focus)) {
flags.send_focus_message = True;
- else if (proto[i] == xatom->getAtom(XAtom::blackbox_structure_messages))
- screen->addNetizen(new Netizen(screen, client.window));
+ }
}
XFree(proto);
*/
void BlackboxWindow::getWMHints(void) {
focus_mode = F_Passive;
- client.initial_state = NormalState;
// remove from current window group
if (client.window_group) {
}
if (wmhint->flags & StateHint)
- client.initial_state = wmhint->initial_state;
+ current_state = wmhint->initial_state;
if (wmhint->flags & WindowGroupHint) {
client.window_group = wmhint->window_group;
group->addWindow(this);
}
- client.wm_hint_flags = wmhint->flags;
XFree(wmhint);
}
if (blackbox_hint->flags & AttribDecoration) {
switch (blackbox_hint->decoration) {
case DecorNone:
- // clear all decorations except close
- decorations &= Decor_Close;
- // clear all functions except close
- functions &= Func_Close;
-
+ decorations = 0;
break;
case DecorTiny:
decorations |= Decor_Titlebar | Decor_Iconify;
decorations &= ~(Decor_Border | Decor_Handle | Decor_Maximize);
- functions |= Func_Move | Func_Iconify;
functions &= ~(Func_Resize | Func_Maximize);
break;
case DecorTool:
decorations |= Decor_Titlebar;
decorations &= ~(Decor_Iconify | Decor_Border | Decor_Handle);
- functions |= Func_Move;
functions &= ~(Func_Resize | Func_Maximize | Func_Iconify);
break;
default:
decorations |= Decor_Titlebar | Decor_Border | Decor_Handle |
Decor_Iconify | Decor_Maximize;
- functions |= Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
-
break;
}
void BlackboxWindow::getTransientInfo(void) {
if (client.transient_for &&
client.transient_for != (BlackboxWindow *) ~0ul) {
- // the transient for hint was removed, so we need to tell our
- // previous transient_for that we are going away
+ // reset transient_for in preparation of looking for a new owner
client.transient_for->client.transientList.remove(this);
}
assert(! flags.iconic &&
(flags.stuck || // window must be on the current workspace or sticky
blackbox_attrib.workspace == screen->getCurrentWorkspaceID()));
-#if 0
- // if the window is not visible, mark the window as wanting focus rather
- // than give it focus.
- if (! flags.visible) {
- Workspace *wkspc = screen->getWorkspace(blackbox_attrib.workspace);
- wkspc->setLastFocusedWindow(this);
- return True;
- }
-#endif
+
/*
We only do this check for normal windows and dialogs because other windows
do this on purpose, such as kde's kicker, and we don't want to go moving
// re-maximizes the window to take into account availableArea changes
void BlackboxWindow::remaximize(void) {
+ if (flags.shaded) {
+ // we only update the window's attributes otherwise we lose the shade bit
+ switch(flags.maximized) {
+ case 1:
+ blackbox_attrib.flags |= AttribMaxHoriz | AttribMaxVert;
+ blackbox_attrib.attrib |= AttribMaxHoriz | AttribMaxVert;
+ break;
+
+ case 2:
+ blackbox_attrib.flags |= AttribMaxVert;
+ blackbox_attrib.attrib |= AttribMaxVert;
+ break;
+
+ case 3:
+ blackbox_attrib.flags |= AttribMaxHoriz;
+ blackbox_attrib.attrib |= AttribMaxHoriz;
+ break;
+ }
+ return;
+ }
+
// save the original dimensions because maximize will wipe them out
int premax_x = blackbox_attrib.premax_x,
premax_y = blackbox_attrib.premax_y,
blackbox_attrib.premax_h = h;
}
+ if (net->flags & AttribDecoration) {
+ switch (net->decoration) {
+ case DecorNone:
+ decorations = 0;
+
+ break;
+
+ default:
+ case DecorNormal:
+ decorations |= Decor_Titlebar | Decor_Handle | Decor_Border |
+ Decor_Iconify | Decor_Maximize;
+
+ break;
+
+ case DecorTiny:
+ decorations |= Decor_Titlebar | Decor_Iconify;
+ decorations &= ~(Decor_Border | Decor_Handle | Decor_Maximize);
+
+ break;
+
+ case DecorTool:
+ decorations |= Decor_Titlebar;
+ decorations &= ~(Decor_Iconify | Decor_Border | Decor_Handle);
+
+ break;
+ }
+
+ // sanity check the new decor
+ if (! (functions & Func_Resize) || isTransient())
+ decorations &= ~(Decor_Maximize | Decor_Handle);
+ if (! (functions & Func_Maximize))
+ decorations &= ~Decor_Maximize;
+
+ if (decorations & Decor_Titlebar) {
+ if (functions & Func_Close) // close button is controlled by function
+ decorations |= Decor_Close; // not decor type
+ } else {
+ if (flags.shaded) // we can not be shaded if we lack a titlebar
+ shade();
+ }
+
+ if (flags.visible && frame.window) {
+ XMapSubwindows(blackbox->getXDisplay(), frame.window);
+ XMapWindow(blackbox->getXDisplay(), frame.window);
+ }
+
+ reconfigure();
+ setState(current_state);
+ }
+
// with the state set it will then be the map event's job to read the
// window's state and behave accordingly
case InactiveState:
case ZoomState:
default:
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: just before show (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
show();
screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
if (isNormal()) {
}
reconfigure();
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: transient hint (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif
}
break;
if (old_rect != frame.rect)
reconfigure();
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: normal hint (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
break;
}
applyGravity(req);
}
- if (cr->value_mask & CWWidth)
+ if (cr->value_mask & CWWidth) {
req.setWidth(cr->width + frame.margin.left + frame.margin.right);
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: new width - %d\n", client.window, cr->width);
+#endif // DEBUG
+ }
- if (cr->value_mask & CWHeight)
+ if (cr->value_mask & CWHeight) {
req.setHeight(cr->height + frame.margin.top + frame.margin.bottom);
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: new height - %d\n", client.window, cr->height);
+#endif // DEBUG
+ }
configure(req.x(), req.y(), req.width(), req.height());
}
break;
}
}
+
+#ifdef DEBUG
+ fprintf(stderr, "0x%lx: change request (%d, %d) w: %d, h: %d\n",
+ client.window,
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+#endif // DEBUG
}
bool snapped = False;
const Rect &winrect = snapwin->frameRect();
- int dleft = std::abs(wright - winrect.left()),
- dright = std::abs(wleft - winrect.right()),
- dtop = std::abs(wbottom - winrect.top()),
- dbottom = std::abs(wtop - winrect.bottom());
+ int dleft = abs(wright - winrect.left()),
+ dright = abs(wleft - winrect.right()),
+ dtop = abs(wbottom - winrect.top()),
+ dbottom = abs(wtop - winrect.bottom());
if (wtop >= (signed)(winrect.y() - frame.rect.height() + 1) &&
wtop < (signed)(winrect.y() + winrect.height() - 1)) {
if (snapped) {
if (screen->getWindowCornerSnap()) {
// try corner-snap to its other sides
- dtop = std::abs(wtop - winrect.top());
- dbottom = std::abs(wbottom - winrect.bottom());
+ dtop = abs(wtop - winrect.top());
+ dbottom = abs(wbottom - winrect.bottom());
if (dtop < snap_distance && dtop <= dbottom)
dy = winrect.top();
else if (dbottom < snap_distance)
if (snapped) {
if (screen->getWindowCornerSnap()) {
// try corner-snap to its other sides
- dleft = std::abs(wleft - winrect.left());
- dright = std::abs(wright - winrect.right());
+ dleft = abs(wleft - winrect.left());
+ dright = abs(wright - winrect.right());
if (dleft < snap_distance && dleft <= dright)
dx = winrect.left();
else if (dright < snap_distance)
frame.rect.height())))
continue;
- int dleft = std::abs(wleft - srect.left()),
- dright = std::abs(wright - srect.right()),
- dtop = std::abs(wtop - srect.top()),
- dbottom = std::abs(wbottom - srect.bottom());
+ int dleft = abs(wleft - srect.left()),
+ dright = abs(wright - srect.right()),
+ dtop = abs(wtop - srect.top()),
+ dbottom = abs(wbottom - srect.bottom());
// snap left?
if (dleft < snap_distance && dleft <= dright)
}
-void BlackboxWindow::changeBlackboxHints(BlackboxHints *net) {
+void BlackboxWindow::changeBlackboxHints(const BlackboxHints *net) {
if ((net->flags & AttribShaded) &&
((blackbox_attrib.attrib & AttribShaded) !=
(net->attrib & AttribShaded)))
if (net->flags & AttribDecoration) {
switch (net->decoration) {
case DecorNone:
- // clear all decorations except close
- decorations &= Decor_Close;
+ decorations = 0;
break;