summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2019-05-16 01:06:21 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-05-16 01:22:54 +0200
commitf55965b5e84ac61a58aaed6e055680ca317a8540 (patch)
tree1fb4f3bba1990bab449896b2c770f2dd719187bf
parenta4b0dfff431579b45fc4d4c6439e74d79fc0e859 (diff)
downloadserenity-f55965b5e84ac61a58aaed6e055680ca317a8540.zip
WindowServer/GMenu: Adjust the popup position to fit the window inside the screen
Rather than passing a "top_anchored" bool. Fixes #22.
-rw-r--r--Applications/Taskbar/TaskbarButton.cpp2
-rw-r--r--LibGUI/GMenu.cpp3
-rw-r--r--LibGUI/GMenu.h2
-rw-r--r--Servers/WindowServer/WSAPITypes.h1
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp2
-rw-r--r--Servers/WindowServer/WSEvent.h5
-rw-r--r--Servers/WindowServer/WSEventLoop.cpp2
-rw-r--r--Servers/WindowServer/WSMenu.cpp18
-rw-r--r--Servers/WindowServer/WSMenu.h2
9 files changed, 20 insertions, 17 deletions
diff --git a/Applications/Taskbar/TaskbarButton.cpp b/Applications/Taskbar/TaskbarButton.cpp
index 0deea6309c..c7e2f60fdc 100644
--- a/Applications/Taskbar/TaskbarButton.cpp
+++ b/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()
diff --git a/LibGUI/GMenu.cpp b/LibGUI/GMenu.cpp
index 2a1864802d..c97d5cbddf 100644
--- a/LibGUI/GMenu.cpp
+++ b/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);
}
diff --git a/LibGUI/GMenu.h b/LibGUI/GMenu.h
index 3019444557..a5280393dc 100644
--- a/LibGUI/GMenu.h
+++ b/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;
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h
index 7ba9095516..2f54a0beaa 100644
--- a/Servers/WindowServer/WSAPITypes.h
+++ b/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;
diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp
index 57bd34adc9..81ba62134d 100644
--- a/Servers/WindowServer/WSClientConnection.cpp
+++ b/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)
diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h
index d894044e21..72cd89c2f0 100644
--- a/Servers/WindowServer/WSEvent.h
+++ b/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 {
diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp
index adb2873b78..e32ec7343f 100644
--- a/Servers/WindowServer/WSEventLoop.cpp
+++ b/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));
diff --git a/Servers/WindowServer/WSMenu.cpp b/Servers/WindowServer/WSMenu.cpp
index d900a49b6b..3d36316f30 100644
--- a/Servers/WindowServer/WSMenu.cpp
+++ b/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);
}
diff --git a/Servers/WindowServer/WSMenu.h b/Servers/WindowServer/WSMenu.h
index 43f66f838d..b9a9713256 100644
--- a/Servers/WindowServer/WSMenu.h
+++ b/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;