#include "i18n.hh"
#include "blackbox.hh"
+#include "Clientmenu.hh"
#include "Font.hh"
#include "GCCache.hh"
#include "Iconmenu.hh"
return;
}
- if (isKDESystrayWindow()) {
- screen->addSystrayWindow(client.window);
- delete this;
- return;
- }
-
frame.window = createToplevelWindow();
frame.plate = createChildWindow(frame.window);
associateClientWindow();
// adjust the window decorations/behavior based on the window type
switch (window_type) {
case Type_Desktop:
- // desktop windows are not managed by us, we just make sure they stay on the
- // bottom.
- return;
-
case Type_Dock:
- // docks (such as kicker) cannot be moved, and appear on all workspaces
- functions &= ~(Func_Move);
- flags.stuck = True;
- case Type_Toolbar:
case Type_Menu:
+ case Type_Toolbar:
case Type_Utility:
- // these windows have minimal decorations, only a titlebar, and cannot
- // be resized or iconified
- decorations &= ~(Decor_Maximize | Decor_Handle | Decor_Border |
- Decor_Iconify);
- functions &= ~(Func_Resize | Func_Maximize | Func_Iconify);
- break;
-
case Type_Splash:
- // splash screens have no functionality or decorations, they are left up
- // to the application which created them
+ // none of these windows are decorated or manipulated by the window manager
decorations = 0;
functions = 0;
+ blackbox_attrib.workspace = 0; // we do need to belong to a workspace
+ flags.stuck = True; // we show up on all workspaces
break;
case Type_Dialog:
client.normal_hint_flags & (PPosition|USPosition)) {
applyGravity(frame.rect);
- if (blackbox->isStartup() ||
- client.rect.intersects(screen->availableArea()))
+ if (blackbox->isStartup() || client.rect.intersects(screen->getRect()))
place_window = False;
}
ButtonMotionMask | EnterWindowMask;
return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(),
- -1, -1, 1, 1, frame.border_w, screen->getDepth(),
+ 0, 0, 1, 1, frame.border_w, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask,
&attrib_create);
}
XSelectInput(blackbox->getXDisplay(), frame.plate, SubstructureRedirectMask);
XGrabServer(blackbox->getXDisplay());
- XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
- XReparentWindow(blackbox->getXDisplay(), client.window, frame.plate, 0, 0);
+
+ unsigned long event_mask = PropertyChangeMask | FocusChangeMask |
+ StructureNotifyMask;
XSelectInput(blackbox->getXDisplay(), client.window,
- PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
+ event_mask & ~StructureNotifyMask);
+ XReparentWindow(blackbox->getXDisplay(), client.window, frame.plate, 0, 0);
+ XSelectInput(blackbox->getXDisplay(), client.window, event_mask);
+
XUngrabServer(blackbox->getXDisplay());
XRaiseWindow(blackbox->getXDisplay(), frame.plate);
void BlackboxWindow::reconfigure(void) {
+ restoreGravity(client.rect);
upsize();
+ applyGravity(frame.rect);
positionWindows();
decorate();
redrawWindowFrame();
if (functions & Func_Resize)
blackbox->grabButton(Button3, Mod1Mask, frame.window, True,
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
- GrabModeAsync, frame.window,
- blackbox->getLowerRightAngleCursor());
+ GrabModeAsync, frame.window, None);
// alt+middle lowers the window
blackbox->grabButton(Button2, Mod1Mask, frame.window, True,
ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
// add window to the appropriate group
BWindowGroup *group = blackbox->searchGroup(client.window_group);
- if (! group) // no group found, create it!
- group = new BWindowGroup(blackbox, client.window_group);
- group->addWindow(this);
+ if (! group) { // no group found, create it!
+ new BWindowGroup(blackbox, client.window_group);
+ group = blackbox->searchGroup(client.window_group);
+ }
+ if (group)
+ group->addWindow(this);
}
client.wm_hint_flags = wmhint->flags;
}
-bool BlackboxWindow::isKDESystrayWindow(void) {
- Window systray;
- if (xatom->getValue(client.window, XAtom::kde_net_wm_system_tray_window_for,
- XAtom::window, systray) && systray)
- return True;
- return False;
-}
-
-
BlackboxWindow *BlackboxWindow::getTransientFor(void) const {
if (client.transient_for &&
client.transient_for != (BlackboxWindow*) ~0ul)
return True;
}
#endif
- if (! frame.rect.intersects(screen->getRect())) {
- // client is outside the screen, move it to the center
- configure((screen->getWidth() - frame.rect.width()) / 2,
- (screen->getHeight() - frame.rect.height()) / 2,
- frame.rect.width(), frame.rect.height());
- }
+ /*
+ 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
+ it.
+ */
+ if (window_type == Type_Normal || window_type == Type_Dialog)
+ if (! frame.rect.intersects(screen->getRect())) {
+ // client is outside the screen, move it to the center
+ configure((screen->getWidth() - frame.rect.width()) / 2,
+ (screen->getHeight() - frame.rect.height()) / 2,
+ frame.rect.width(), frame.rect.height());
+ }
if (client.transientList.size() > 0) {
// transfer focus to any modal transients
* split second, leaving us with a ghost window... so, we need to do this
* while the X server is grabbed
*/
+ unsigned long event_mask = PropertyChangeMask | FocusChangeMask |
+ StructureNotifyMask;
XGrabServer(blackbox->getXDisplay());
- XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
- XUnmapWindow(blackbox->getXDisplay(), client.window);
XSelectInput(blackbox->getXDisplay(), client.window,
- PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
+ event_mask & ~StructureNotifyMask);
+ XUnmapWindow(blackbox->getXDisplay(), client.window);
+ XSelectInput(blackbox->getXDisplay(), client.window, event_mask);
XUngrabServer(blackbox->getXDisplay());
XUnmapWindow(blackbox->getXDisplay(), frame.window);
XGrabServer(blackbox->getXDisplay());
- XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
- XUnmapWindow(blackbox->getXDisplay(), client.window);
+ unsigned long event_mask = PropertyChangeMask | FocusChangeMask |
+ StructureNotifyMask;
XSelectInput(blackbox->getXDisplay(), client.window,
- PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
+ event_mask & ~StructureNotifyMask);
+ XUnmapWindow(blackbox->getXDisplay(), client.window);
+ XSelectInput(blackbox->getXDisplay(), client.window, event_mask);
XUngrabServer(blackbox->getXDisplay());
void BlackboxWindow::setWorkspace(unsigned int n) {
blackbox_attrib.flags |= AttribWorkspace;
blackbox_attrib.workspace = n;
+ if (n == BSENTINEL) { // iconified window
+ /*
+ we set the workspace to 'all workspaces' so that taskbars will show the
+ window. otherwise, it made uniconifying a window imposible without the
+ blackbox workspace menu
+ */
+ n = 0xffffffff;
+ }
xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal, n);
}
if (! flags.iconic)
screen->reassociateWindow(this, BSENTINEL, True);
- else
- // temporary fix since sticky windows suck. set the hint to what we
- // actually hold in our data.
- xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal,
- blackbox_attrib.workspace);
+ // temporary fix since sticky windows suck. set the hint to what we
+ // actually hold in our data.
+ xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal,
+ blackbox_attrib.workspace);
setState(current_state);
} else {
if (isFocused())
blackbox->setFocusedWindow(this);
+
+ Clientmenu *menu = screen->getWorkspace(blackbox_attrib.workspace)->getMenu();
+ menu->setItemSelected(window_number, isFocused());
}
default:
show();
screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
- if (! blackbox->isStartup() && (isTransient() || screen->doFocusNew())) {
- XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped..
- setInputFocus();
+ if (isNormal()) {
+ if (! blackbox->isStartup()) {
+ XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped
+ if (screen->doFocusNew()|| (isTransient() && getTransientFor() &&
+ getTransientFor()->isFocused())) {
+ setInputFocus();
+ }
+ if (screen->getPlacementPolicy() == BScreen::ClickMousePlacement) {
+ int x, y, rx, ry;
+ Window c, r;
+ unsigned int m;
+ XQueryPointer(blackbox->getXDisplay(), screen->getRootWindow(),
+ &r, &c, &rx, &ry, &x, &y, &m);
+ beginMove(rx, ry);
+ }
+ }
}
break;
}
configure(req.x(), req.y(), req.width(), req.height());
}
- if (cr->value_mask & CWStackMode) {
+ if (cr->value_mask & CWStackMode && !isDesktop()) {
switch (cr->detail) {
case Below:
case BottomIf:
client.window);
#endif
- if (frame.maximize_button == be->window) {
+ if (frame.maximize_button == be->window && be->button <= 3) {
redrawMaximizeButton(True);
} else if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
if (! flags.focused)
if (frame.title == be->window || frame.label == be->window) {
if (((be->time - lastButtonPressTime) <=
blackbox->getDoubleClickInterval()) ||
- (be->state & ControlMask)) {
+ (be->state == ControlMask)) {
lastButtonPressTime = 0;
shade();
} else {
// mouse wheel up
} else if (be->button == 4) {
if ((be->window == frame.label ||
- be->window == frame.title) &&
+ be->window == frame.title ||
+ be->window == frame.maximize_button ||
+ be->window == frame.iconify_button ||
+ be->window == frame.close_button) &&
! flags.shaded)
shade();
// mouse wheel down
} else if (be->button == 5) {
if ((be->window == frame.label ||
- be->window == frame.title) &&
+ be->window == frame.title ||
+ be->window == frame.maximize_button ||
+ be->window == frame.iconify_button ||
+ be->window == frame.close_button) &&
flags.shaded)
shade();
}
client.window);
#endif
- if (re->window == frame.maximize_button) {
+ if (re->window == frame.maximize_button &&
+ re->button >= 1 && re->button <= 3) {
if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
(re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
maximize(re->button);
} else {
redrawMaximizeButton(flags.maximized);
}
- } else if (re->window == frame.iconify_button) {
+ } else if (re->window == frame.iconify_button && re->button == 1) {
if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
(re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
iconify();
} else {
redrawIconifyButton(False);
}
- } else if (re->window == frame.close_button) {
+ } else if (re->window == frame.close_button & re->button == 1) {
if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
(re->y >= 0 && re->y <= static_cast<signed>(frame.button_w)))
close();
} else if (flags.resizing) {
doResize(me->x_root, me->y_root);
} else {
- if (! flags.resizing && (me->state & Button1Mask) &&
- (functions & Func_Move) &&
+ if (!flags.resizing && me->state & Button1Mask && (functions & Func_Move) &&
(frame.title == me->window || frame.label == me->window ||
frame.handle == me->window || frame.window == me->window)) {
beginMove(me->x_root, me->y_root);
} else if ((functions & Func_Resize) &&
- (((me->state & Button1Mask) &&
- (me->window == frame.right_grip ||
- me->window == frame.left_grip)) ||
- (me->state & (Mod1Mask | Button3Mask) &&
- me->window == frame.window))) {
- beginResize(me->x_root, me->y_root,
- (me->window == frame.left_grip) ? BottomLeft : BottomRight);
+ (me->state & Button1Mask && (me->window == frame.right_grip ||
+ me->window == frame.left_grip)) ||
+ (me->state & Button3Mask && me->state & Mod1Mask &&
+ me->window == frame.window)) {
+ unsigned int zones = screen->getResizeZones();
+ Corner corner;
+
+ if (me->window == frame.left_grip) {
+ corner = BottomLeft;
+ } else if (me->window == frame.right_grip || zones == 1) {
+ corner = BottomRight;
+ } else {
+ bool top;
+ bool left = (me->x_root - frame.rect.x() <=
+ static_cast<signed>(frame.rect.width() / 2));
+ if (zones == 2)
+ top = False;
+ else // (zones == 4)
+ top = (me->y_root - frame.rect.y() <=
+ static_cast<signed>(frame.rect.height() / 2));
+ corner = (top ? (left ? TopLeft : TopRight) :
+ (left ? BottomLeft : BottomRight));
+ }
+
+ beginResize(me->x_root, me->y_root, corner);
}
}
}
return;
}
- /*
- watch for destroy notify on the group window (in addition to
- any other events we are looking for)
-
- since some managed windows can also be window group controllers,
- we need to make sure that we don't clobber the event mask for the
- managed window
- */
XSelectInput(blackbox->getXDisplay(), group,
- wattrib.your_event_mask | StructureNotifyMask);
+ PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
blackbox->saveGroupSearch(group, this);
}