Browse Source

WindowServer: Make menu windows inherently modal.

It was confusing that you could interact with other windows with a menu up.
Andreas Kling 6 years ago
parent
commit
d5dec1922b

+ 1 - 1
Servers/WindowServer/WSClientConnection.cpp

@@ -197,7 +197,7 @@ void WSClientConnection::handle_request(const WSAPIAddMenuToMenubarRequest& requ
     }
     }
     auto& menubar = *(*it).value;
     auto& menubar = *(*it).value;
     auto& menu = *(*jt).value;
     auto& menu = *(*jt).value;
-    menubar.add_menu(&menu);
+    menubar.add_menu(menu);
     WSAPI_ServerMessage response;
     WSAPI_ServerMessage response;
     response.type = WSAPI_ServerMessage::Type::DidAddMenuToMenubar;
     response.type = WSAPI_ServerMessage::Type::DidAddMenuToMenubar;
     response.menu.menubar_id = menubar_id;
     response.menu.menubar_id = menubar_id;

+ 1 - 0
Servers/WindowServer/WSMenu.cpp

@@ -188,4 +188,5 @@ void WSMenu::popup(const Point& position)
     auto& window = ensure_menu_window();
     auto& window = ensure_menu_window();
     window.move_to(position);
     window.move_to(position);
     window.set_visible(true);
     window.set_visible(true);
+    WSWindowManager::the().set_current_menu(this);
 }
 }

+ 3 - 2
Servers/WindowServer/WSMenu.h

@@ -22,8 +22,9 @@ public:
     const WSClientConnection* client() const { return m_client; }
     const WSClientConnection* client() const { return m_client; }
     int menu_id() const { return m_menu_id; }
     int menu_id() const { return m_menu_id; }
 
 
-    WSMenuBar* menu_bar() { return m_menubar; }
-    const WSMenuBar* menu_bar() const { return m_menubar; }
+    WSMenuBar* menubar() { return m_menubar; }
+    const WSMenuBar* menubar() const { return m_menubar; }
+    void set_menubar(WSMenuBar* menubar) { m_menubar = menubar; }
 
 
     bool is_empty() const { return m_items.is_empty(); }
     bool is_empty() const { return m_items.is_empty(); }
     int item_count() const { return m_items.size(); }
     int item_count() const { return m_items.size(); }

+ 5 - 1
Servers/WindowServer/WSMenuBar.h

@@ -13,7 +13,11 @@ public:
     WSClientConnection& client() { return m_client; }
     WSClientConnection& client() { return m_client; }
     const WSClientConnection& client() const { return m_client; }
     const WSClientConnection& client() const { return m_client; }
     int menubar_id() const { return m_menubar_id; }
     int menubar_id() const { return m_menubar_id; }
-    void add_menu(WSMenu* menu) { m_menus.append(menu); }
+    void add_menu(WSMenu& menu)
+    {
+        menu.set_menubar(this);
+        m_menus.append(&menu);
+    }
 
 
     template<typename Callback>
     template<typename Callback>
     void for_each_menu(Callback callback)
     void for_each_menu(Callback callback)

+ 17 - 2
Servers/WindowServer/WSWindowManager.cpp

@@ -286,6 +286,16 @@ int WSWindowManager::menubar_menu_margin() const
     return 16;
     return 16;
 }
 }
 
 
+void WSWindowManager::set_current_menu(WSMenu* menu)
+{
+    if (m_current_menu == menu)
+        return;
+    if (m_current_menu)
+        m_current_menu->close();
+    if (menu)
+        m_current_menu = menu->make_weak_ptr();
+}
+
 void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
 void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
 {
 {
     if (menubar)
     if (menubar)
@@ -414,7 +424,7 @@ void WSWindowManager::pick_new_active_window()
 
 
 void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event)
 void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event)
 {
 {
-    bool is_hover_with_any_menu_open = event.type() == WSMouseEvent::MouseMove && m_current_menu;
+    bool is_hover_with_any_menu_open = event.type() == WSMouseEvent::MouseMove && m_current_menu && m_current_menu->menubar();
     bool is_mousedown_with_left_button = event.type() == WSMouseEvent::MouseDown && event.button() == MouseButton::Left;
     bool is_mousedown_with_left_button = event.type() == WSMouseEvent::MouseDown && event.button() == MouseButton::Left;
     bool should_open_menu = &menu != current_menu() && (is_hover_with_any_menu_open || is_mousedown_with_left_button);
     bool should_open_menu = &menu != current_menu() && (is_hover_with_any_menu_open || is_mousedown_with_left_button);
 
 
@@ -655,13 +665,18 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*&
     }
     }
 
 
     if (m_current_menu && m_current_menu->menu_window()) {
     if (m_current_menu && m_current_menu->menu_window()) {
-        bool event_is_inside_current_menu = m_current_menu->menu_window()->rect().contains(event.position());
+        auto& window = *m_current_menu->menu_window();
+        bool event_is_inside_current_menu = window.rect().contains(event.position());
         if (!event_is_inside_current_menu) {
         if (!event_is_inside_current_menu) {
             if (m_current_menu->hovered_item())
             if (m_current_menu->hovered_item())
                 m_current_menu->clear_hovered_item();
                 m_current_menu->clear_hovered_item();
             if (event.type() == WSMessage::MouseDown || event.type() == WSMessage::MouseUp)
             if (event.type() == WSMessage::MouseDown || event.type() == WSMessage::MouseUp)
                 close_current_menu();
                 close_current_menu();
+        } else {
+            event_window = &window;
+            window.on_message(event.translated(-window.position()));
         }
         }
+        return;
     }
     }
 
 
     WSWindow* event_window_with_frame = nullptr;
     WSWindow* event_window_with_frame = nullptr;