Explorar o código

WindowServer/GMenu: Adjust the popup position to fit the window inside the screen

Rather than passing a "top_anchored" bool. Fixes #22.
Robin Burchell %!s(int64=6) %!d(string=hai) anos
pai
achega
f55965b5e8

+ 1 - 1
Applications/Taskbar/TaskbarButton.cpp

@@ -27,7 +27,7 @@ TaskbarButton::~TaskbarButton()
 
 void TaskbarButton::context_menu_event(GContextMenuEvent&)
 {
-    ensure_menu().popup(screen_relative_rect().location(), /* top_anchored */ false);
+    ensure_menu().popup(screen_relative_rect().location());
 }
 
 GMenu& TaskbarButton::ensure_menu()

+ 1 - 2
LibGUI/GMenu.cpp

@@ -39,7 +39,7 @@ void GMenu::add_separator()
     m_items.append(make<GMenuItem>(m_menu_id, GMenuItem::Separator));
 }
 
-void GMenu::popup(const Point& screen_position, bool top_anchored)
+void GMenu::popup(const Point& screen_position)
 {
     if (!m_menu_id)
         realize_menu();
@@ -47,7 +47,6 @@ void GMenu::popup(const Point& screen_position, bool top_anchored)
     request.type = WSAPI_ClientMessage::Type::PopupMenu;
     request.menu.menu_id = m_menu_id;
     request.menu.position = screen_position;
-    request.menu.top_anchored = top_anchored;
     GEventLoop::post_message_to_server(request);
 }
 

+ 1 - 1
LibGUI/GMenu.h

@@ -21,7 +21,7 @@ public:
     void add_action(Retained<GAction>);
     void add_separator();
 
-    void popup(const Point& screen_position, bool top_anchored = true);
+    void popup(const Point& screen_position);
     void dismiss();
 
     Function<void(unsigned)> on_item_activation;

+ 0 - 1
Servers/WindowServer/WSAPITypes.h

@@ -258,7 +258,6 @@ struct WSAPI_ClientMessage {
             bool checkable;
             bool checked;
             WSAPI_Point position;
-            bool top_anchored;
         } menu;
         struct {
             WSAPI_Rect rect;

+ 1 - 1
Servers/WindowServer/WSClientConnection.cpp

@@ -260,7 +260,7 @@ void WSClientConnection::handle_request(const WSAPIPopupMenuRequest& request)
         return;
     }
     auto& menu = *(*it).value;
-    menu.popup(position, request.top_anchored());
+    menu.popup(position);
 }
 
 void WSClientConnection::handle_request(const WSAPIDismissMenuRequest& request)

+ 1 - 4
Servers/WindowServer/WSEvent.h

@@ -235,22 +235,19 @@ private:
 
 class WSAPIPopupMenuRequest : public WSAPIClientRequest {
 public:
-    WSAPIPopupMenuRequest(int client_id, int menu_id, const Point& position, bool top_anchored)
+    WSAPIPopupMenuRequest(int client_id, int menu_id, const Point& position)
         : WSAPIClientRequest(WSEvent::APIPopupMenuRequest, client_id)
         , m_menu_id(menu_id)
         , m_position(position)
-        , m_top_anchored(top_anchored)
     {
     }
 
     int menu_id() const { return m_menu_id; }
     Point position() const { return m_position; }
-    bool top_anchored() const { return m_top_anchored; }
 
 private:
     int m_menu_id;
     Point m_position;
-    bool m_top_anchored;
 };
 
 class WSAPIDismissMenuRequest : public WSAPIClientRequest {

+ 1 - 1
Servers/WindowServer/WSEventLoop.cpp

@@ -158,7 +158,7 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag
         post_event(client, make<WSAPICreateMenuRequest>(client_id, String(message.text, message.text_length)));
         break;
     case WSAPI_ClientMessage::Type::PopupMenu:
-        post_event(client, make<WSAPIPopupMenuRequest>(client_id, message.menu.menu_id, message.menu.position, message.menu.top_anchored));
+        post_event(client, make<WSAPIPopupMenuRequest>(client_id, message.menu.menu_id, message.menu.position));
         break;
     case WSAPI_ClientMessage::Type::DismissMenu:
         post_event(client, make<WSAPIDismissMenuRequest>(client_id, message.menu.menu_id));

+ 13 - 5
Servers/WindowServer/WSMenu.cpp

@@ -4,6 +4,7 @@
 #include "WSEvent.h"
 #include "WSEventLoop.h"
 #include "WSWindowManager.h"
+#include "WSScreen.h"
 #include <WindowServer/WSAPITypes.h>
 #include <WindowServer/WSClientConnection.h>
 #include <SharedGraphics/CharacterBitmap.h>
@@ -227,14 +228,21 @@ void WSMenu::close()
         menu_window()->set_visible(false);
 }
 
-void WSMenu::popup(const Point& position, bool top_anchored)
+void WSMenu::popup(const Point& position)
 {
     ASSERT(!is_empty());
+
     auto& window = ensure_menu_window();
-    if (top_anchored)
-        window.move_to(position);
-    else
-        window.move_to(position.translated(0, -window.height()));
+    const int margin = 30;
+    Point adjusted_pos = position;
+    if (adjusted_pos.x() + window.width() >= WSScreen::the().width() - margin) {
+        adjusted_pos = adjusted_pos.translated(-window.width(), 0);
+    }
+    if (adjusted_pos.y() + window.height() >= WSScreen::the().height() - margin) {
+        adjusted_pos = adjusted_pos.translated(0, -window.height());
+    }
+
+    window.move_to(adjusted_pos);
     window.set_visible(true);
     WSWindowManager::the().set_current_menu(this);
 }

+ 1 - 1
Servers/WindowServer/WSMenu.h

@@ -74,7 +74,7 @@ public:
 
     void close();
 
-    void popup(const Point&, bool top_anchored);
+    void popup(const Point&);
 
 private:
     virtual void event(CEvent&) override;