diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index be48b49685..44b4839580 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -65,24 +65,25 @@ enum window_alignment { // window flags enum { - B_NOT_MOVABLE = 0x00000001, - B_NOT_CLOSABLE = 0x00000020, - B_NOT_ZOOMABLE = 0x00000040, - B_NOT_MINIMIZABLE = 0x00004000, - B_NOT_RESIZABLE = 0x00000002, - B_NOT_H_RESIZABLE = 0x00000004, - B_NOT_V_RESIZABLE = 0x00000008, - B_AVOID_FRONT = 0x00000080, - B_AVOID_FOCUS = 0x00002000, - B_WILL_ACCEPT_FIRST_CLICK = 0x00000010, - B_OUTLINE_RESIZE = 0x00001000, - B_NO_WORKSPACE_ACTIVATION = 0x00000100, - B_NOT_ANCHORED_ON_ACTIVATE = 0x00020000, - B_ASYNCHRONOUS_CONTROLS = 0x00080000, - B_QUIT_ON_WINDOW_CLOSE = 0x00100000, - B_SAME_POSITION_IN_ALL_WORKSPACES = 0x00200000, - B_AUTO_UPDATE_SIZE_LIMITS = 0x00400000, - B_CLOSE_ON_ESCAPE = 0x00800000 + B_NOT_MOVABLE = 0x00000001, + B_NOT_CLOSABLE = 0x00000020, + B_NOT_ZOOMABLE = 0x00000040, + B_NOT_MINIMIZABLE = 0x00004000, + B_NOT_RESIZABLE = 0x00000002, + B_NOT_H_RESIZABLE = 0x00000004, + B_NOT_V_RESIZABLE = 0x00000008, + B_AVOID_FRONT = 0x00000080, + B_AVOID_FOCUS = 0x00002000, + B_WILL_ACCEPT_FIRST_CLICK = 0x00000010, + B_OUTLINE_RESIZE = 0x00001000, + B_NO_WORKSPACE_ACTIVATION = 0x00000100, + B_NOT_ANCHORED_ON_ACTIVATE = 0x00020000, + B_ASYNCHRONOUS_CONTROLS = 0x00080000, + B_QUIT_ON_WINDOW_CLOSE = 0x00100000, + B_SAME_POSITION_IN_ALL_WORKSPACES = 0x00200000, + B_AUTO_UPDATE_SIZE_LIMITS = 0x00400000, + B_CLOSE_ON_ESCAPE = 0x00800000, + B_NO_SERVER_SIDE_WINDOW_MODIFIERS = 0x00000200 }; #define B_CURRENT_WORKSPACE 0 diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 0cb9c82b00..7f5cc9d94c 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -108,7 +108,8 @@ Window::Window(const BRect& frame, const char *name, fDrawingEngine(drawingEngine), fDesktop(window->Desktop()), - fLastMousePosition(0.0, 0.0), + fLastMousePosition(0.0f, 0.0f), + fMouseMoveDistance(0.0f), fLastMoveTime(0), fCurrentUpdateSession(&fUpdateSessions[0]), @@ -761,14 +762,19 @@ Window::MouseDown(BMessage* message, BPoint where, int32* _viewToken) if (!fBorderRegionValid) GetBorderRegion(&fBorderRegion); + int32 modifiers = _ExtractModifiers(message); + bool inBorderRegion = fBorderRegion.Contains(where); + bool windowModifier = (fFlags & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0 + && (~modifiers & (B_COMMAND_KEY | B_CONTROL_KEY)) == 0; + // default action is to drag the Window - if (fBorderRegion.Contains(where)) { + if (windowModifier || inBorderRegion) { // clicking Window visible area click_type action = DEC_DRAG; - if (fDecorator) - action = _ActionFor(message); + if (inBorderRegion && fDecorator != NULL) + action = _ActionFor(message, modifiers); // ignore clicks on decorator buttons if the // non-floating window doesn't have focus @@ -853,6 +859,7 @@ Window::MouseDown(BMessage* message, BPoint where, int32* _viewToken) fDesktop->SetFocusWindow(this); if (action == DEC_DRAG) { fActivateOnMouseUp = true; + fMouseMoveDistance = 0.0f; fLastMoveTime = system_time(); } } @@ -1072,9 +1079,13 @@ Window::MouseMoved(BMessage *message, BPoint where, int32* _viewToken, // used for window moving/resizing/sliding the tab fLastMousePosition += delta; - // the window was moved, it doesn't come to - // the front in FFM mode when the mouse is released - fActivateOnMouseUp = false; + // If the window was moved enough, it doesn't come to + // the front in FFM mode when the mouse is released. + if (fActivateOnMouseUp) { + fMouseMoveDistance += sqrtf(delta.x * delta.x + delta.y * delta.y); + if (fMouseMoveDistance > 4.0f) + fActivateOnMouseUp = false; + } // change focus in FFM mode DesktopSettings desktopSettings(fDesktop); @@ -2055,24 +2066,41 @@ Window::_UpdateContentRegion() } +int32 +Window::_ExtractModifiers(const BMessage* message) const +{ + int32 modifiers; + if (message->FindInt32("modifiers", &modifiers) != B_OK) + modifiers = 0; + return modifiers; +} + + click_type -Window::_ActionFor(const BMessage* msg) const +Window::_ActionFor(const BMessage* message) const +{ + if (fDecorator == NULL) + return DEC_NONE; + + int32 modifiers = _ExtractModifiers(message); + return _ActionFor(message, modifiers); +} + + +click_type +Window::_ActionFor(const BMessage* message, int32 modifiers) const { if (fDecorator == NULL) return DEC_NONE; BPoint where; - if (msg->FindPoint("where", &where) != B_OK) + if (message->FindPoint("where", &where) != B_OK) return DEC_NONE; int32 buttons; - if (msg->FindInt32("buttons", &buttons) != B_OK) + if (message->FindInt32("buttons", &buttons) != B_OK) buttons = 0; - int32 modifiers; - if (msg->FindInt32("modifiers", &modifiers) != B_OK) - modifiers = 0; - return fDecorator->Clicked(where, buttons, modifiers); } diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h index 94ee30d957..d36e8b11a1 100644 --- a/src/servers/app/Window.h +++ b/src/servers/app/Window.h @@ -256,7 +256,11 @@ protected: void _UpdateContentRegion(); + int32 _ExtractModifiers( + const BMessage* message) const; click_type _ActionFor(const BMessage* message) const; + click_type _ActionFor(const BMessage* message, + int32 modifiers) const; void _ObeySizeLimits(); void _PropagatePosition(); @@ -311,6 +315,7 @@ protected: ::Desktop* fDesktop; BPoint fLastMousePosition; + float fMouseMoveDistance; bigtime_t fLastMoveTime; // The synchronization, which client drawing commands