XEvent ce;
Atom msgtype;
ObFrameContext con;
+ static gint px = -1, py = -1;
+ static guint pb = 0;
switch (e->type) {
case ButtonPress:
+ /* save where the press occured for the first button pressed */
+ if (!pb) {
+ pb = e->xbutton.button;
+ px = e->xbutton.x;
+ py = e->xbutton.y;
+ }
case ButtonRelease:
/* Wheel buttons don't draw because they are an instant click, so it
is a waste of resources to go drawing it.
!keyboard_interactively_grabbed() &&
!menu_frame_visible)
{
- con = frame_context(client, e->xbutton.window);
+ /* use where the press occured */
+ con = frame_context(client, e->xbutton.window, px, py);
con = mouse_button_frame_context(con, e->xbutton.button);
+
+ if (e->type == ButtonRelease && e->xbutton.button == pb)
+ pb = 0, px = py = -1;
+
switch (con) {
case OB_FRAME_CONTEXT_MAXIMIZE:
client->frame->max_press = (e->type == ButtonPress);
}
}
break;
+ case MotionNotify:
+ con = frame_context(client, e->xmotion.window,
+ e->xmotion.x, e->xmotion.y);
+ switch (con) {
+ case OB_FRAME_CONTEXT_TITLEBAR:
+ /* we've left the button area inside the titlebar */
+ if (client->frame->max_hover || client->frame->desk_hover ||
+ client->frame->shade_hover || client->frame->iconify_hover ||
+ client->frame->close_hover)
+ {
+ client->frame->max_hover = FALSE;
+ client->frame->desk_hover = FALSE;
+ client->frame->shade_hover = FALSE;
+ client->frame->iconify_hover = FALSE;
+ client->frame->close_hover = FALSE;
+ frame_adjust_state(client->frame);
+ }
+ break;
+ case OB_FRAME_CONTEXT_MAXIMIZE:
+ if (!client->frame->max_hover) {
+ client->frame->max_hover = TRUE;
+ frame_adjust_state(client->frame);
+ }
+ break;
+ case OB_FRAME_CONTEXT_ALLDESKTOPS:
+ if (!client->frame->desk_hover) {
+ client->frame->desk_hover = TRUE;
+ frame_adjust_state(client->frame);
+ }
+ break;
+ case OB_FRAME_CONTEXT_SHADE:
+ if (!client->frame->shade_hover) {
+ client->frame->shade_hover = TRUE;
+ frame_adjust_state(client->frame);
+ }
+ break;
+ case OB_FRAME_CONTEXT_ICONIFY:
+ if (!client->frame->iconify_hover) {
+ client->frame->iconify_hover = TRUE;
+ frame_adjust_state(client->frame);
+ }
+ break;
+ case OB_FRAME_CONTEXT_CLOSE:
+ if (!client->frame->close_hover) {
+ client->frame->close_hover = TRUE;
+ frame_adjust_state(client->frame);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
case LeaveNotify:
- con = frame_context(client, e->xcrossing.window);
+ con = frame_context(client, e->xcrossing.window,
+ e->xcrossing.x, e->xcrossing.y);
switch (con) {
case OB_FRAME_CONTEXT_MAXIMIZE:
client->frame->max_hover = FALSE;
nofocus = TRUE;
}
- con = frame_context(client, e->xcrossing.window);
+ con = frame_context(client, e->xcrossing.window,
+ e->xcrossing.x, e->xcrossing.y);
switch (con) {
case OB_FRAME_CONTEXT_MAXIMIZE:
client->frame->max_hover = TRUE;
}
if (e->xconfigurerequest.value_mask & CWStackMode) {
+ ObClient *sibling = NULL;
+
+ /* get the sibling */
+ if (e->xconfigurerequest.value_mask & CWSibling) {
+ ObWindow *win;
+ win = g_hash_table_lookup(window_map,
+ &e->xconfigurerequest.above);
+ if (WINDOW_IS_CLIENT(win))
+ sibling = WINDOW_AS_CLIENT(win);
+ }
+
switch (e->xconfigurerequest.detail) {
case Below:
+ ob_debug("ConfigureRequest Below for client %s sibling %s\n",
+ client->title, sibling ? sibling->title : "(all)");
+ /* just lower it */
+ stacking_lower(CLIENT_AS_WINDOW(client));
+ break;
case BottomIf:
- /* Apps are so rude. And this is totally disconnected from
- activation/focus. Bleh. */
- /*client_lower(client);*/
+ ob_debug("ConfigureRequest BottomIf for client %s sibling "
+ "%s\n",
+ client->title, sibling ? sibling->title : "(all)");
+ /* if this client occludes sibling (or anything if NULL), then
+ lower it to the bottom */
+ if (stacking_occluded(sibling, client))
+ stacking_lower(CLIENT_AS_WINDOW(client));
break;
-
case Above:
+ ob_debug("ConfigureRequest Above for client %s sibling %s\n",
+ client->title, sibling ? sibling->title : "(all)");
+ /* activate it rather than just focus it */
+ client_activate(client, FALSE, FALSE);
+ break;
case TopIf:
+ ob_debug("ConfigureRequest TopIf for client %s sibling %s\n",
+ client->title, sibling ? sibling->title : "(all)");
+ if (stacking_occluded(client, sibling))
+ /* activate it rather than just focus it */
+ client_activate(client, FALSE, FALSE);
+ case Opposite:
+ ob_debug("ConfigureRequest Opposite for client %s sibling "
+ "%s\n",
+ client->title, sibling ? sibling->title : "(all)");
+ if (stacking_occluded(client, sibling))
+ /* activate it rather than just focus it */
+ client_activate(client, FALSE, FALSE);
+ else if (stacking_occluded(sibling, client))
+ stacking_lower(CLIENT_AS_WINDOW(client));
default:
- /* Apps are so rude. And this is totally disconnected from
- activation/focus. Bleh. */
- /*client_raise(client);*/
break;
}
}
event_curtime = d->time;
if (focus_client != d->client) {
if (client_focus(d->client) && config_focus_raise)
- client_raise(d->client);
+ stacking_raise(CLIENT_AS_WINDOW(d->client));
}
event_curtime = old;
return FALSE; /* no repeat */