diff --git a/src/servers/app/Decorator.cpp b/src/servers/app/Decorator.cpp index 63b8a52bee..977c16a5df 100644 --- a/src/servers/app/Decorator.cpp +++ b/src/servers/app/Decorator.cpp @@ -361,7 +361,7 @@ Decorator::GetFootprint(BRegion *region) - \c DEC_DRAG : Moves the window to the front and prepares to move the window - \c DEC_MOVETOBACK : Moves the window to the back of the stack - \c DEC_MOVETOFRONT : Moves the window to the front of the stack - - \c DEC_SLIDETAB : Initiates tab-sliding, including calling SlideTab() + - \c DEC_SLIDETAB : Initiates tab-sliding - \c DEC_RESIZE : Handle window resizing as appropriate - \c DEC_RESIZE_L @@ -418,23 +418,6 @@ Decorator::MoveBy(BPoint pt) MoveBy(pt.x, pt.y); } -/*! - \brief Moves the tab by the specified amount - \param dx x offset - \param dy y offset - \return The new tab rectangle. - - Slides the tab by the x or y value. This function is not required to be - implemented by subclasses. Note that the tab rectangle returned does not - necessarily reflect _tabrect offset by the amount given - few people want to - slide a tab right off the window - that would be a Bad Thing (TM). -*/ -BRect -Decorator::SlideTab(float dx, float dy) -{ - return BRect(0, 0, 0, 0); -} - /*! \brief Resizes the decorator frame \param dx x offset diff --git a/src/servers/app/DefaultDecorator.cpp b/src/servers/app/DefaultDecorator.cpp index 3d2a07c48d..7846ffcfbc 100644 --- a/src/servers/app/DefaultDecorator.cpp +++ b/src/servers/app/DefaultDecorator.cpp @@ -218,13 +218,6 @@ DefaultDecorator::GetFootprint(BRegion *region) } } -BRect -DefaultDecorator::SlideTab(float dx, float dy) -{ - //return Decorator::SlideTab(dx,dy); - return _tabrect; -} - click_type DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers) { @@ -289,6 +282,9 @@ DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers) // Clicking in the tab? if (_tabrect.Contains(pt)) { + // tab sliding in any case if either shift key is held down + if (modifiers & B_SHIFT_KEY) + return DEC_SLIDETAB; // Here's part of our window management stuff if (buttons == B_SECONDARY_MOUSE_BUTTON) return DEC_MOVETOBACK; @@ -353,9 +349,11 @@ DefaultDecorator::_DoLayout() // calculate our tab rect if (hasTab) { + // tab is initially on the left + fTabOffset = 0; // distance from one item of the tab bar to another. // In this case the text and close/zoom rects - fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 7 : 10; + fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 12 : 20; font_height fh; _drawdata.Font().Height(&fh); diff --git a/src/servers/app/DefaultDecorator.h b/src/servers/app/DefaultDecorator.h index d57d33a707..00d19ef830 100644 --- a/src/servers/app/DefaultDecorator.h +++ b/src/servers/app/DefaultDecorator.h @@ -51,7 +51,6 @@ public: virtual void GetFootprint(BRegion *region); - virtual BRect SlideTab(float dx, float dy); virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers); @@ -90,8 +89,7 @@ private: int32 fBorderWidth; -// bool fSlidingTab; -// uint32 fTabOffset; + uint32 fTabOffset; float fTextOffset; float fMinTabWidth; diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index ea35cb14c6..b95af40909 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -106,7 +106,11 @@ Desktop::AddDriver(DisplayDriver *driver) // The driver is now owned by the screen // TODO: be careful of screen initialization - monitor may not support 640x480 +#if __HAIKU__ + screen->SetMode(1400, 1050, B_RGB32, 60.f); +#else screen->SetMode(800, 600, B_RGB32, 60.f); +#endif fScreenList.AddItem(screen); } else { diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index bf715adb1c..ccb0cc3789 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -939,7 +939,7 @@ Layer::IsHidden(void) const void Layer::PushState() { - LayerData *data = new LayerData(); + LayerData *data = new LayerData(*fLayerData); data->prevState = fLayerData; fLayerData = data; } @@ -1043,7 +1043,7 @@ Layer::Scale() const LayerData *ld = fLayerData; do { - scale += ld->Scale(); + scale *= ld->Scale(); } while ((ld = ld->prevState)); return scale; diff --git a/src/servers/app/LayerData.cpp b/src/servers/app/LayerData.cpp index cd8dd71bf3..96f09b4423 100644 --- a/src/servers/app/LayerData.cpp +++ b/src/servers/app/LayerData.cpp @@ -325,7 +325,7 @@ LayerData::LayerData(const LayerData &data) } // destructor -LayerData::~LayerData(void) +LayerData::~LayerData() { delete prevState; } diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 762d455a75..ab0752d12d 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -274,7 +274,7 @@ ServerApp::MonitorApp(void *data) status_t err = B_OK; while (!app->fQuitting) { - STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort)); +// STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort)); err = reader.GetNextMessage(code, B_INFINITE_TIMEOUT); if (err < B_OK) { STRACE(("ServerApp::MonitorApp(): GetNextMessage returned %s\n", strerror(err))); @@ -1575,6 +1575,7 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) case AS_GET_ESCAPEMENTS_AS_FLOATS: { FTRACE(("ServerApp %s: AS_GET_ESCAPEMENTS_AS_FLOATS\n", fSignature.String())); +//printf("ServerApp %s: AS_GET_ESCAPEMENTS_AS_FLOATS\n", fSignature.String()); // Attached Data: // 1) uint16 - family ID // 2) uint16 - style ID @@ -1608,16 +1609,15 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) int32 numChars; link.Read(&numChars); +//printf(" numChars: %ld\n", numChars); -/* char charArray[numChars]; - for (int32 i = 0; i < numChars; i++) { - link.Read(&charArray[i]); - }*/ uint32 numBytes; link.Read(&numBytes); +//printf(" numBytes: %ld\n", numBytes); char* charArray = new char[numBytes]; link.Read(charArray, numBytes); +//printf(" charArray[numBytes - 1]: '%c'\n", charArray[numBytes - 1]); float* escapements = new float[numChars]; // figure out escapements @@ -1629,6 +1629,8 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) font.SetRotation(rotation); font.SetFlags(flags); +//if (true) { +//memset(escapements, 0, numChars * sizeof(float)); if (font.GetEscapements(charArray, numChars, escapements, delta)) { fLink.StartMessage(SERVER_TRUE); fLink.Attach(escapements, numChars * sizeof(float)); @@ -1721,7 +1723,7 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) case AS_SCREEN_GET_MODE: { STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", fSignature.String())); -printf("ServerApp %s: AS_SCREEN_GET_MODE\n", fSignature.String()); +//printf("ServerApp %s: AS_SCREEN_GET_MODE\n", fSignature.String()); // Attached data // 1) int32 port to reply to // 2) screen_id diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index 657945294e..03bf909d0f 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -104,6 +104,8 @@ WinBorder::WinBorder(const BRect &r, fIsResizing(false), + fIsSlidingTab(false), + fInUpdate(false), fRequestSent(false), @@ -157,167 +159,6 @@ WinBorder::~WinBorder() delete fDecorator; } -//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator -void -WinBorder::RebuildFullRegion() -{ - STRACE(("WinBorder(%s)::RebuildFullRegion()\n",GetName())); - - fFull.MakeEmpty(); - - // Winborder holds Decorator's full regions. if any... - if (fDecorator) - fDecorator->GetFootprint(&fFull); -} - -/*! - \brief Handles B_MOUSE_DOWN events and takes appropriate actions - \param evt PointerEvent object containing the info from the last B_MOUSE_DOWN message - \param sendMessage flag to send a B_MOUSE_DOWN message to the client - - This function searches to see if the B_MOUSE_DOWN message is being sent to the window tab - or frame. If it is not, the message is passed on to the appropriate view in the client - BWindow. If the WinBorder is the target, then the proper action flag is set. -*/ -click_type -WinBorder::MouseDown(const PointerEvent& event) -{ - click_type action = _ActionFor(event); - - if (fDecorator) { - // find out where user clicked in Decorator - switch(action) { - case DEC_CLOSE: - fIsClosing = true; - fDecorator->SetClose(true); - STRACE_CLICK(("===> DEC_CLOSE\n")); - break; - - case DEC_ZOOM: - fIsZooming = true; - fDecorator->SetZoom(true); - STRACE_CLICK(("===> DEC_ZOOM\n")); - break; - - case DEC_MINIMIZE: - fIsMinimizing = true; - fDecorator->SetMinimize(true); - STRACE_CLICK(("===> DEC_MINIMIZE\n")); - break; - - case DEC_DRAG: - fIsDragging = true; - fBringToFrontOnRelease = true; - fLastMousePosition = event.where; - STRACE_CLICK(("===> DEC_DRAG\n")); - break; - - case DEC_RESIZE: - fIsResizing = true; - fLastMousePosition = event.where; - fResizingClickOffset = event.where - fFrame.RightBottom(); - STRACE_CLICK(("===> DEC_RESIZE\n")); - break; - - default: - break; - } - } - return action; -} - -/*! - \brief Handles B_MOUSE_MOVED events and takes appropriate actions - \param evt PointerEvent object containing the info from the last B_MOUSE_MOVED message - - This function doesn't do much except test continue any move/resize operations in progress - or check to see if the user clicked on a tab button (close, zoom, etc.) and then moused - away to prevent the operation from occurring -*/ -void -WinBorder::MouseMoved(const PointerEvent& event) -{ - if (fDecorator) { - if (fIsZooming) { - fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM); - } else if (fIsClosing) { - fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE); - } else if (fIsMinimizing) { - fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE); - } - } - if (fIsDragging) { - // we will not come to front if we ever actually moved - fBringToFrontOnRelease = false; - - BPoint delta = event.where - fLastMousePosition; - MoveBy(delta.x, delta.y); - } - if (fIsResizing) { - BRect frame(fFrame.LeftTop(), event.where - fResizingClickOffset); - - BPoint delta = frame.RightBottom() - fFrame.RightBottom(); - ResizeBy(delta.x, delta.y); - } - fLastMousePosition = event.where; -} - -/*! - \brief Handles B_MOUSE_UP events and takes appropriate actions - \param evt PointerEvent object containing the info from the last B_MOUSE_UP message - - This function resets any state objects (is_resizing flag and such) and if resetting a - button click flag, takes the appropriate action (i.e. clearing the close button flag also - takes steps to close the window). -*/ -void -WinBorder::MouseUp(const PointerEvent& event) -{ - if (fDecorator) { - click_type action = _ActionFor(event); - - if (fIsZooming) { - fIsZooming = false; - fDecorator->SetZoom(false); - if (action == DEC_ZOOM) - Window()->Zoom(); - return; - } - if (fIsClosing) { - fIsClosing = false; - fDecorator->SetClose(false); - if (action == DEC_CLOSE) - Window()->Quit(); - return; - } - if (fIsMinimizing) { - fIsMinimizing = false; - fDecorator->SetMinimize(false); - if (action == DEC_MINIMIZE) - Window()->Minimize(true); - return; - } - } - if (fBringToFrontOnRelease) { - // TODO: We would have dragged the window if - // the mouse would have moved, but it didn't - // move -> This will bring the window to the - // front on R5 in FFM mode! - } - fIsDragging = false; - fIsResizing = false; - fBringToFrontOnRelease = false; -} - -//! Sets the decorator focus to active or inactive colors -void -WinBorder::HighlightDecorator(const bool &active) -{ - STRACE(("Decorator->Highlight\n")); - if (fDecorator) - fDecorator->SetFocus(active); -} - //! redraws a certain section of the window border void WinBorder::Draw(const BRect &r) @@ -442,6 +283,19 @@ y = (float)int32(y); } } +//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator +void +WinBorder::RebuildFullRegion() +{ + STRACE(("WinBorder(%s)::RebuildFullRegion()\n",GetName())); + + fFull.MakeEmpty(); + + // Winborder holds Decorator's full regions. if any... + if (fDecorator) + fDecorator->GetFootprint(&fFull); +} + //! Sets the minimum and maximum sizes of the window void WinBorder::SetSizeLimits(float minWidth, float maxWidth, @@ -469,7 +323,7 @@ WinBorder::SetSizeLimits(float minWidth, float maxWidth, if (fMaxHeight < fMinHeight) fMaxHeight = fMinHeight; -#if 0 // On R5, Windows don't automatically resize +#if 0 // On R5, Windows don't automatically resize (the code works though) // Automatically resize the window to fit these new limits // if it does not already. float minWidthDiff = fMinWidth - fFrame.Width(); @@ -504,6 +358,181 @@ WinBorder::GetSizeLimits(float* minWidth, float* maxWidth, *maxHeight = fMaxHeight; } +/*! + \brief Handles B_MOUSE_DOWN events and takes appropriate actions + \param evt PointerEvent object containing the info from the last B_MOUSE_DOWN message + \param sendMessage flag to send a B_MOUSE_DOWN message to the client + + This function searches to see if the B_MOUSE_DOWN message is being sent to the window tab + or frame. If it is not, the message is passed on to the appropriate view in the client + BWindow. If the WinBorder is the target, then the proper action flag is set. +*/ +click_type +WinBorder::MouseDown(const PointerEvent& event) +{ + click_type action = _ActionFor(event); + + if (fDecorator) { + // find out where user clicked in Decorator + switch(action) { + case DEC_CLOSE: + fIsClosing = true; + fDecorator->SetClose(true); + STRACE_CLICK(("===> DEC_CLOSE\n")); + break; + + case DEC_ZOOM: + fIsZooming = true; + fDecorator->SetZoom(true); + STRACE_CLICK(("===> DEC_ZOOM\n")); + break; + + case DEC_MINIMIZE: + fIsMinimizing = true; + fDecorator->SetMinimize(true); + STRACE_CLICK(("===> DEC_MINIMIZE\n")); + break; + + case DEC_DRAG: + fIsDragging = true; + fBringToFrontOnRelease = true; + fLastMousePosition = event.where; + STRACE_CLICK(("===> DEC_DRAG\n")); + break; + + case DEC_RESIZE: + fIsResizing = true; + fLastMousePosition = event.where; + fResizingClickOffset = event.where - fFrame.RightBottom(); + STRACE_CLICK(("===> DEC_RESIZE\n")); + break; + + case DEC_SLIDETAB: + fIsSlidingTab = true; + fLastMousePosition = event.where; +// fResizingClickOffset = event.where - fFrame.RightBottom(); + STRACE_CLICK(("===> DEC_SLIDETAB\n")); + break; + + default: + break; + } + } + return action; +} + +/*! + \brief Handles B_MOUSE_MOVED events and takes appropriate actions + \param evt PointerEvent object containing the info from the last B_MOUSE_MOVED message + + This function doesn't do much except test continue any move/resize operations in progress + or check to see if the user clicked on a tab button (close, zoom, etc.) and then moused + away to prevent the operation from occurring +*/ +void +WinBorder::MouseMoved(const PointerEvent& event) +{ + if (fDecorator) { + if (fIsZooming) { + fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM); + } else if (fIsClosing) { + fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE); + } else if (fIsMinimizing) { + fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE); + } + } + if (fIsDragging) { + // we will not come to front if we ever actually moved + fBringToFrontOnRelease = false; + + BPoint delta = event.where - fLastMousePosition; + MoveBy(delta.x, delta.y); + } + if (fIsResizing) { + BRect frame(fFrame.LeftTop(), event.where - fResizingClickOffset); + + BPoint delta = frame.RightBottom() - fFrame.RightBottom(); + ResizeBy(delta.x, delta.y); + } + if (fIsSlidingTab) { + } + fLastMousePosition = event.where; +} + +/*! + \brief Handles B_MOUSE_UP events and takes appropriate actions + \param evt PointerEvent object containing the info from the last B_MOUSE_UP message + + This function resets any state objects (is_resizing flag and such) and if resetting a + button click flag, takes the appropriate action (i.e. clearing the close button flag also + takes steps to close the window). +*/ +void +WinBorder::MouseUp(const PointerEvent& event) +{ + if (fDecorator) { + click_type action = _ActionFor(event); + + if (fIsZooming) { + fIsZooming = false; + fDecorator->SetZoom(false); + if (action == DEC_ZOOM) + Window()->Zoom(); + return; + } + if (fIsClosing) { + fIsClosing = false; + fDecorator->SetClose(false); + if (action == DEC_CLOSE) + Window()->Quit(); + return; + } + if (fIsMinimizing) { + fIsMinimizing = false; + fDecorator->SetMinimize(false); + if (action == DEC_MINIMIZE) + Window()->Minimize(true); + return; + } + } + if (fBringToFrontOnRelease) { + // TODO: We would have dragged the window if + // the mouse would have moved, but it didn't + // move -> This will bring the window to the + // front on R5 in FFM mode! + } + fIsDragging = false; + fIsResizing = false; + fIsSlidingTab = false; + fBringToFrontOnRelease = false; +} + +// SetTabLocation +void +WinBorder::SetTabLocation(float location) +{ + if (fDecorator) + fDecorator->SetTabLocation(location); +} + +// TabLocation +float +WinBorder::TabLocation() const +{ + if (fDecorator) + return fDecorator->TabLocation(); + return 0.0; +} + +//! Sets the decorator focus to active or inactive colors +void +WinBorder::HighlightDecorator(bool active) +{ + STRACE(("Decorator->Highlight\n")); + if (fDecorator) + fDecorator->SetFocus(active); +} + //! Returns true if the point is in the WinBorder's screen area bool WinBorder::HasPoint(const BPoint& pt) const diff --git a/src/servers/app/WinBorder.h b/src/servers/app/WinBorder.h index 1b6546eae7..5d055ab288 100644 --- a/src/servers/app/WinBorder.h +++ b/src/servers/app/WinBorder.h @@ -104,7 +104,7 @@ class WinBorder : public Layer { void UpdateDecorator(); void UpdateFont(); void UpdateScreen(); - + virtual bool HasClient() { return false; } inline Decorator* GetDecorator() const { return fDecorator; } @@ -114,7 +114,11 @@ class WinBorder : public Layer { inline uint32 WindowFlags() const { return fWindowFlags; } inline uint32 Workspaces() const { return fWorkspaces; } - void HighlightDecorator(const bool &active); + // 0.0 -> left .... 1.0 -> right + void SetTabLocation(float location); + float TabLocation() const; + + void HighlightDecorator(bool active); bool HasPoint(const BPoint &pt) const; @@ -166,6 +170,8 @@ class WinBorder : public Layer { bool fIsResizing; + bool fIsSlidingTab; + bool fInUpdate; bool fRequestSent; diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index c96b321e40..8b6f2e659a 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -366,12 +366,27 @@ void DisplayDriverPainter::InvertRect(const BRect &r) { if (Lock()) { - fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(r)); + BRect vr(min_c(r.left, r.right), + min_c(r.top, r.bottom), + max_c(r.left, r.right), + max_c(r.top, r.bottom)); + vr = fPainter->ClipRect(vr); + if (vr.IsValid()) { + fGraphicsCard->HideSoftwareCursor(vr); - BRect touched = fPainter->InvertRect(r); + // try hardware optimized version first + if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) { + BRegion region(vr); + region.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->InvertRegion(region); + } else { + fPainter->InvertRect(vr); - fGraphicsCard->Invalidate(touched); - fGraphicsCard->ShowSoftwareCursor(); + fGraphicsCard->Invalidate(vr); + } + + fGraphicsCard->ShowSoftwareCursor(); + } Unlock(); }