1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:07:36 +00:00

WindowServer+TaskBar: Add a taskbar window button popup menu.

This patch only hooks up the minimize and unminimize actions.
This commit is contained in:
Andreas Kling 2019-04-23 23:14:14 +02:00
parent c5c4e54a67
commit 956bd23aae
17 changed files with 158 additions and 56 deletions

View file

@ -210,6 +210,7 @@ struct WSAPI_ClientMessage {
GetWallpaper,
SetWindowOverrideCursor,
WM_SetActiveWindow,
WM_SetWindowMinimized,
PopupMenu,
DismissMenu,
SetWindowIcon,
@ -236,6 +237,7 @@ struct WSAPI_ClientMessage {
struct {
int client_id;
int window_id;
bool minimized;
} wm;
struct {
int menubar_id;
@ -245,6 +247,7 @@ struct WSAPI_ClientMessage {
int shortcut_text_length;
bool enabled;
WSAPI_Point position;
bool top_anchored;
} menu;
struct {
WSAPI_Rect rect;

View file

@ -259,7 +259,7 @@ void WSClientConnection::handle_request(const WSAPIPopupMenuRequest& request)
return;
}
auto& menu = *(*it).value;
menu.popup(position);
menu.popup(position, request.top_anchored());
}
void WSClientConnection::handle_request(const WSAPIDismissMenuRequest& request)
@ -641,6 +641,22 @@ void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& req
WSWindowManager::the().move_to_front_and_make_active(window);
}
void WSClientConnection::handle_request(const WSWMAPISetWindowMinimizedRequest& request)
{
auto* client = WSClientConnection::from_client_id(request.target_client_id());
if (!client) {
post_error("WSWMAPISetWindowMinimizedRequest: Bad client ID");
return;
}
auto it = client->m_windows.find(request.target_window_id());
if (it == client->m_windows.end()) {
post_error("WSWMAPISetWindowMinimizedRequest: Bad window ID");
return;
}
auto& window = *(*it).value;
window.set_minimized(request.is_minimized());
}
void WSClientConnection::on_request(const WSAPIClientRequest& request)
{
switch (request.type()) {
@ -700,6 +716,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request)
return handle_request(static_cast<const WSAPISetWindowOverrideCursorRequest&>(request));
case WSEvent::WMAPISetActiveWindowRequest:
return handle_request(static_cast<const WSWMAPISetActiveWindowRequest&>(request));
case WSEvent::WMAPISetWindowMinimizedRequest:
return handle_request(static_cast<const WSWMAPISetWindowMinimizedRequest&>(request));
case WSEvent::APIPopupMenuRequest:
return handle_request(static_cast<const WSAPIPopupMenuRequest&>(request));
case WSEvent::APIDismissMenuRequest:

View file

@ -73,6 +73,7 @@ private:
void handle_request(const WSAPIGetWallpaperRequest&);
void handle_request(const WSAPISetWindowOverrideCursorRequest&);
void handle_request(const WSWMAPISetActiveWindowRequest&);
void handle_request(const WSWMAPISetWindowMinimizedRequest&);
void handle_request(const WSAPIPopupMenuRequest&);
void handle_request(const WSAPIDismissMenuRequest&);

View file

@ -61,6 +61,7 @@ public:
APIGetWallpaperRequest,
APISetWindowOverrideCursorRequest,
WMAPISetActiveWindowRequest,
WMAPISetWindowMinimizedRequest,
APIPopupMenuRequest,
APIDismissMenuRequest,
__End_API_Client_Requests,
@ -120,6 +121,27 @@ private:
int m_target_window_id;
};
class WSWMAPISetWindowMinimizedRequest : public WSAPIClientRequest {
public:
WSWMAPISetWindowMinimizedRequest(int client_id, int target_client_id, int target_window_id, bool minimized)
: WSAPIClientRequest(WSEvent::WMAPISetWindowMinimizedRequest, client_id)
, m_target_client_id(target_client_id)
, m_target_window_id(target_window_id)
, m_minimized(minimized)
{
}
int target_client_id() const { return m_target_client_id; }
int target_window_id() const { return m_target_window_id; }
bool is_minimized() const { return m_minimized; }
private:
int m_target_client_id;
int m_target_window_id;
bool m_minimized;
};
class WSAPISetGlobalCursorTrackingRequest : public WSAPIClientRequest {
public:
WSAPISetGlobalCursorTrackingRequest(int client_id, int window_id, bool value)
@ -192,19 +214,22 @@ private:
class WSAPIPopupMenuRequest : public WSAPIClientRequest {
public:
WSAPIPopupMenuRequest(int client_id, int menu_id, const Point& position)
WSAPIPopupMenuRequest(int client_id, int menu_id, const Point& position, bool top_anchored)
: 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 {

View file

@ -155,7 +155,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));
post_event(client, make<WSAPIPopupMenuRequest>(client_id, message.menu.menu_id, message.menu.position, message.menu.top_anchored));
break;
case WSAPI_ClientMessage::Type::DismissMenu:
post_event(client, make<WSAPIDismissMenuRequest>(client_id, message.menu.menu_id));
@ -247,6 +247,9 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag
case WSAPI_ClientMessage::Type::WM_SetActiveWindow:
post_event(client, make<WSWMAPISetActiveWindowRequest>(client_id, message.wm.client_id, message.wm.window_id));
break;
case WSAPI_ClientMessage::Type::WM_SetWindowMinimized:
post_event(client, make<WSWMAPISetWindowMinimizedRequest>(client_id, message.wm.client_id, message.wm.window_id, message.wm.minimized));
break;
default:
break;
}

View file

@ -188,11 +188,14 @@ void WSMenu::close()
menu_window()->set_visible(false);
}
void WSMenu::popup(const Point& position)
void WSMenu::popup(const Point& position, bool top_anchored)
{
ASSERT(!is_empty());
auto& window = ensure_menu_window();
window.move_to(position);
if (top_anchored)
window.move_to(position);
else
window.move_to(position.translated(0, -window.height()));
window.set_visible(true);
WSWindowManager::the().set_current_menu(this);
}

View file

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

View file

@ -258,12 +258,12 @@ IterationDecision WSWindowManager::for_each_visible_window_from_back_to_front(Ca
{
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Normal, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Taskbar, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Tooltip, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
return for_each_visible_window_of_type_from_back_to_front(WSWindowType::WindowSwitcher, callback);
}
@ -293,15 +293,15 @@ IterationDecision WSWindowManager::for_each_visible_window_of_type_from_front_to
template<typename Callback>
IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Callback callback)
{
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::WindowSwitcher, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Taskbar, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Tooltip, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Normal, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
return for_each_visible_window_of_type_from_front_to_back(WSWindowType::WindowSwitcher, callback);
return for_each_visible_window_of_type_from_front_to_back(WSWindowType::Normal, callback);
}
template<typename Callback>