/** Process an enter notify event. */ void HandleEnterNotify(const XCrossingEvent *event) { ClientNode *np; Cursor cur; np = FindClient(event->window); if(np) { if( !(np->state.status & STAT_ACTIVE) && (settings.focusModel == FOCUS_SLOPPY)) { FocusClient(np); } if(np->parent == event->window) { np->borderAction = GetBorderActionType(np, event->x, event->y); cur = GetFrameCursor(np->borderAction); JXDefineCursor(display, np->parent, cur); } else if(np->borderAction != BA_NONE) { SetDefaultCursor(np->parent); np->borderAction = BA_NONE; } } }
/** Handle a motion notify event. */ void HandleMotionNotify(const XMotionEvent *event) { ClientNode *np; Cursor cur; if(event->is_hint) { return; } np = FindClientByParent(event->window); if(np) { BorderActionType action; action = GetBorderActionType(np, event->x, event->y); if(np->borderAction != action) { np->borderAction = action; cur = GetFrameCursor(action); JXDefineCursor(display, np->parent, cur); } } }
/** Handle a motion notify event. */ void HandleMotionNotify(const XMotionEvent *event) { ClientNode *np; Cursor cur; BorderActionType action; if(event->is_hint) { return; } SetMousePosition(event->x_root, event->y_root); np = FindClientByParent(event->window); if(np && (np->state.border & BORDER_OUTLINE)) { action = GetBorderActionType(np, event->x, event->y); if(np->borderAction != action) { np->borderAction = action; cur = GetFrameCursor(action); JXDefineCursor(display, np->parent, cur); } } }
/** Take the appropriate action for a click on a client border. */ void DispatchBorderButtonEvent(const XButtonEvent *event, ClientNode *np) { static Time lastClickTime = 0; static int lastX = 0, lastY = 0; static char doubleClickActive = 0; BorderActionType action; int bsize; /* Middle click starts a move unless it's over the maximize button. */ action = GetBorderActionType(np, event->x, event->y); if(event->button == Button2 && action != BA_MAXIMIZE) { MoveClient(np, event->x, event->y); return; } /* Determine the size of the border. */ if(np->state.border & BORDER_OUTLINE) { bsize = settings.borderWidth; } else { bsize = 0; } /* Other buttons are context sensitive. */ switch(action & 0x0F) { case BA_RESIZE: /* Border */ if(event->type == ButtonPress) { if(event->button == Button1) { ResizeClient(np, action, event->x, event->y); } else if(event->button == Button3) { const int x = np->x + event->x - bsize; const int y = np->y + event->y - settings.titleHeight - bsize; ShowWindowMenu(np, x, y, 0); } } break; case BA_MOVE: /* Title bar */ if(event->button == Button1) { if(event->type == ButtonPress) { if(doubleClickActive && event->time != lastClickTime && event->time - lastClickTime <= settings.doubleClickSpeed && abs(event->x - lastX) <= settings.doubleClickDelta && abs(event->y - lastY) <= settings.doubleClickDelta) { MaximizeClientDefault(np); doubleClickActive = 0; } else { if(MoveClient(np, event->x, event->y)) { doubleClickActive = 0; } else { doubleClickActive = 1; lastClickTime = event->time; lastX = event->x; lastY = event->y; } } } } else if(event->button == Button3) { const int x = np->x + event->x - bsize; const int y = np->y + event->y - settings.titleHeight - bsize; ShowWindowMenu(np, x, y, 0); } else if(event->button == Button4) { ShadeClient(np); } else if(event->button == Button5) { UnshadeClient(np); } break; case BA_MENU: /* Menu button */ if(event->button == Button4) { ShadeClient(np); } else if(event->button == Button5) { UnshadeClient(np); } else if(event->type == ButtonPress) { const int x = np->x + event->x - bsize; const int y = np->y + event->y - settings.titleHeight - bsize; ShowWindowMenu(np, x, y, 0); } break; case BA_CLOSE: /* Close button */ if(event->type == ButtonRelease && (event->button == Button1 || event->button == Button3)) { DeleteClient(np); } break; case BA_MAXIMIZE: /* Maximize button */ if(event->type == ButtonRelease) { switch(event->button) { case Button1: MaximizeClientDefault(np); break; case Button2: MaximizeClient(np, np->state.maxFlags ^ MAX_VERT); break; case Button3: MaximizeClient(np, np->state.maxFlags ^ MAX_HORIZ); break; default: break; } } break; case BA_MINIMIZE: /* Minimize button */ if(event->type == ButtonRelease) { if(event->button == Button3) { if(np->state.status & STAT_SHADED) { UnshadeClient(np); } else { ShadeClient(np); } } else if(event->button == Button1) { MinimizeClient(np, 1); } } break; default: break; } DiscardEnterEvents(); }
/** Take the appropriate action for a click on a client border. */ void DispatchBorderButtonEvent(const XButtonEvent *event, ClientNode *np) { static Time lastClickTime = 0; static int lastX = 0, lastY = 0; static int doubleClickActive = 0; BorderActionType action; int bsize; action = GetBorderActionType(np, event->x, event->y); switch(action & 0x0F) { case BA_RESIZE: if(event->type == ButtonPress) { ResizeClient(np, action, event->x, event->y); } break; case BA_MOVE: if(event->type == ButtonPress) { if(doubleClickActive && abs(event->time - lastClickTime) > 0 && abs(event->time - lastClickTime) <= doubleClickSpeed && abs(event->x - lastX) <= doubleClickDelta && abs(event->y - lastY) <= doubleClickDelta) { MaximizeClientDefault(np); doubleClickActive = 0; } else { if(MoveClient(np, event->x, event->y)) { doubleClickActive = 0; } else { doubleClickActive = 1; lastClickTime = event->time; lastX = event->x; lastY = event->y; } } } break; case BA_MENU: if(event->type == ButtonPress) { if(np->state.border & BORDER_OUTLINE) { bsize = borderWidth; } else { bsize = 0; } ShowWindowMenu(np, np->x + event->x - bsize, np->y + event->y - titleHeight - bsize); } break; case BA_CLOSE: if(event->type == ButtonRelease) { DeleteClient(np); } break; case BA_MAXIMIZE: if(event->type == ButtonRelease) { MaximizeClientDefault(np); } break; case BA_MINIMIZE: if(event->type == ButtonRelease) { MinimizeClient(np); } break; default: break; } }