diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index 5b1d6893fa..02b2cdeadd 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -283,6 +283,7 @@ private: struct unpack_cookie; class Shortcut; + friend class BAlert; friend class BApplication; friend class BBitmap; friend class BView; @@ -303,6 +304,7 @@ private: virtual void task_looper(); + BPoint AlertPosition(const BRect& frame); virtual BMessage* ConvertToMessage(void* raw, int32 code); void AddShortcut(uint32 key, uint32 modifiers, diff --git a/src/kits/interface/Alert.cpp b/src/kits/interface/Alert.cpp index ce513cf457..476f35312f 100644 --- a/src/kits/interface/Alert.cpp +++ b/src/kits/interface/Alert.cpp @@ -576,13 +576,10 @@ BAlert::_InitObject(const char* text, const char* button0, const char* button1, // Position the alert so that it is centered vertically but offset a bit // horizontally in the parent window's frame or, if unavailable, the // screen frame. - BWindow* window = + BWindow* parent = dynamic_cast(BLooper::LooperForThread(find_thread(NULL))); - const BRect frame = window != NULL ? window->Frame() - : (BScreen(this)).Frame(); - - CenterIn(frame.InsetByCopy(0, frame.Height() / 2) - .OffsetBySelf(0, -frame.Height() / 4)); + const BRect frame = parent != NULL ? parent->Frame() : BScreen(this).Frame(); + MoveTo(dynamic_cast(this)->AlertPosition(frame)); } diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index a7ef4a8ffe..fd77d14d95 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -3891,6 +3891,58 @@ BWindow::_KeyboardNavigation() } +/*! + \brief Return the position of the window centered horizontally to the passed + in \a frame and vertically 3/4 from the top of \a frame. + + If the window is on the borders + + \param width The width of the window. + \param height The height of the window. + \param frame The \a frame to center the window in. + + \return The new window position. +*/ +BPoint +BWindow::AlertPosition(const BRect& frame) +{ + float width = Bounds().Width(); + float height = Bounds().Height(); + + BPoint point(frame.left + (frame.Width() / 2.0f) - (width / 2.0f), + frame.top + (frame.Height() / 4.0f) - ceil(height / 3.0f)); + + BRect screenFrame = BScreen(this).Frame(); + if (frame == screenFrame) { + // reference frame is screen frame, skip the below adjustments + return point; + } + + float borderWidth; + float tabHeight; + _GetDecoratorSize(&borderWidth, &tabHeight); + + // clip the x position within the horizontal edges of the screen + if (point.x < screenFrame.left + borderWidth) + point.x = screenFrame.left + borderWidth; + else if (point.x + width > screenFrame.right - borderWidth) + point.x = screenFrame.right - borderWidth - width; + + // lower the window down if it is covering the window tab + float tabPosition = frame.LeftTop().y + tabHeight + borderWidth; + if (point.y < tabPosition) + point.y = tabPosition; + + // clip the y position within the vertical edges of the screen + if (point.y < screenFrame.top + borderWidth) + point.y = screenFrame.top + borderWidth; + else if (point.y + height > screenFrame.bottom - borderWidth) + point.y = screenFrame.bottom - borderWidth - height; + + return point; +} + + BMessage* BWindow::ConvertToMessage(void* raw, int32 code) { diff --git a/src/kits/tracker/FilePanel.cpp b/src/kits/tracker/FilePanel.cpp index ae89580f9e..806c48f410 100644 --- a/src/kits/tracker/FilePanel.cpp +++ b/src/kits/tracker/FilePanel.cpp @@ -40,6 +40,9 @@ All rights reserved. #include #include #include +#include +#include +#include #include "AutoLock.h" #include "Commands.h" @@ -122,6 +125,13 @@ BFilePanel::Show() // window in a different workspace, reopen in current fWindow->SetWorkspaces(workspace); + // Position the file panel like an alert + BWindow* parent = + dynamic_cast(BLooper::LooperForThread(find_thread(NULL))); + const BRect frame = parent != NULL ? parent->Frame() + : BScreen(fWindow).Frame(); + fWindow->MoveTo(dynamic_cast(fWindow)->AlertPosition(frame)); + if (!IsShowing()) fWindow->Show();