瀏覽代碼

WindowServer: Compute some layout rects in WSMenuManager up front

Currently menu applets are laid out relative to the "audio rect" which
is the rect of the little audio muted state icon thingy.

There was an issue where applets would be placed at a negative X coord
if they were added to the WindowServer before the first time drawing
the menubar.
Andreas Kling 5 年之前
父節點
當前提交
6e6e0b9de8
共有 3 個文件被更改,包括 38 次插入32 次删除
  1. 30 24
      Servers/WindowServer/WSMenuManager.cpp
  2. 5 0
      Servers/WindowServer/WSMenuManager.h
  3. 3 8
      Servers/WindowServer/WSWindowManager.cpp

+ 30 - 24
Servers/WindowServer/WSMenuManager.cpp

@@ -3,6 +3,7 @@
 #include <LibDraw/Font.h>
 #include <LibDraw/Painter.h>
 #include <WindowServer/WSMenuManager.h>
+#include <WindowServer/WSScreen.h>
 #include <WindowServer/WSWindowManager.h>
 #include <time.h>
 #include <unistd.h>
@@ -34,6 +35,26 @@ WSMenuManager::WSMenuManager()
             last_update_time = now;
         }
     });
+
+    auto menubar_rect = this->menubar_rect();
+
+    int username_width = Font::default_bold_font().width(m_username);
+    m_username_rect = {
+        menubar_rect.right() - menubar_menu_margin() / 2 - Font::default_bold_font().width(m_username),
+        menubar_rect.y(),
+        username_width,
+        menubar_rect.height()
+    };
+
+    int time_width = Font::default_font().width("2222-22-22 22:22:22");
+    m_time_rect = {
+        m_username_rect.left() - menubar_menu_margin() / 2 - time_width,
+        menubar_rect.y(),
+        time_width,
+        menubar_rect.height()
+    };
+
+    m_audio_rect = { m_time_rect.right() - time_width - 20, m_time_rect.y() + 1, 12, 16 };
 }
 
 WSMenuManager::~WSMenuManager()
@@ -43,7 +64,7 @@ WSMenuManager::~WSMenuManager()
 void WSMenuManager::setup()
 {
     m_window = WSWindow::construct(*this, WSWindowType::Menubar);
-    m_window->set_rect(WSWindowManager::the().menubar_rect());
+    m_window->set_rect(menubar_rect());
 }
 
 bool WSMenuManager::is_open(const WSMenu& menu) const
@@ -58,7 +79,7 @@ bool WSMenuManager::is_open(const WSMenu& menu) const
 void WSMenuManager::draw()
 {
     auto& wm = WSWindowManager::the();
-    auto menubar_rect = wm.menubar_rect();
+    auto menubar_rect = this->menubar_rect();
 
     if (m_needs_window_resize) {
         m_window->set_rect(menubar_rect);
@@ -87,16 +108,7 @@ void WSMenuManager::draw()
         return true;
     });
 
-    int username_width = Font::default_bold_font().width(m_username);
-
-    // FIXME: This rect should only be computed once.
-    Rect username_rect {
-        menubar_rect.right() - wm.menubar_menu_margin() / 2 - Font::default_bold_font().width(m_username),
-        menubar_rect.y(),
-        username_width,
-        menubar_rect.height()
-    };
-    painter.draw_text(username_rect, m_username, Font::default_bold_font(), TextAlignment::CenterRight, Color::Black);
+    painter.draw_text(m_username_rect, m_username, Font::default_bold_font(), TextAlignment::CenterRight, Color::Black);
 
     time_t now = time(nullptr);
     auto* tm = localtime(&now);
@@ -107,20 +119,9 @@ void WSMenuManager::draw()
         tm->tm_hour,
         tm->tm_min,
         tm->tm_sec);
-    int time_width = wm.font().width(time_text);
 
-    // FIXME: This rect should only be computed once.
-    Rect time_rect {
-        username_rect.left() - wm.menubar_menu_margin() / 2 - time_width,
-        menubar_rect.y(),
-        time_width,
-        menubar_rect.height()
-    };
-
-    painter.draw_text(time_rect, time_text, wm.font(), TextAlignment::CenterRight, Color::Black);
 
-    // FIXME: This rect should only be computed once.
-    m_audio_rect = { time_rect.right() - wm.font().width(time_text) - 20, time_rect.y() + 1, 12, 16 };
+    painter.draw_text(m_time_rect, time_text, wm.font(), TextAlignment::CenterRight, Color::Black);
 
     auto& audio_bitmap = m_audio_muted ? *m_muted_bitmap : *m_unmuted_bitmap;
     painter.blit(m_audio_rect.location(), audio_bitmap, audio_bitmap.rect());
@@ -322,3 +323,8 @@ void WSMenuManager::invalidate_applet(WSMenuApplet& applet, const Rect& rect)
     draw_applet(applet);
     window().invalidate();
 }
+
+Rect WSMenuManager::menubar_rect() const
+{
+    return { 0, 0, WSScreen::the().rect().width(), 18 };
+}

+ 5 - 0
Servers/WindowServer/WSMenuManager.h

@@ -23,6 +23,9 @@ public:
 
     Vector<WeakPtr<WSMenu>>& open_menu_stack() { return m_open_menu_stack; }
 
+    Rect menubar_rect() const;
+    static int menubar_menu_margin() { return 16; }
+
     void set_needs_window_resize();
 
     WSMenu* current_menu() { return m_current_menu.ptr(); }
@@ -64,6 +67,8 @@ private:
     OwnPtr<AClientConnection> m_audio_client;
 
     Rect m_audio_rect;
+    Rect m_username_rect;
+    Rect m_time_rect;
 
     bool m_needs_window_resize { false };
     bool m_bar_open { false };

+ 3 - 8
Servers/WindowServer/WSWindowManager.cpp

@@ -241,11 +241,6 @@ void WSWindowManager::set_resolution(int width, int height)
     }
 }
 
-int WSWindowManager::menubar_menu_margin() const
-{
-    return 16;
-}
-
 void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
 {
     if (menubar)
@@ -255,11 +250,11 @@ void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
 #ifdef DEBUG_MENUS
     dbg() << "[WM] Current menubar is now " << menubar;
 #endif
-    Point next_menu_location { menubar_menu_margin() / 2, 0 };
+    Point next_menu_location { WSMenuManager::menubar_menu_margin() / 2, 0 };
     int index = 0;
     for_each_active_menubar_menu([&](WSMenu& menu) {
         int text_width = index == 1 ? Font::default_bold_font().width(menu.name()) : font().width(menu.name());
-        menu.set_rect_in_menubar({ next_menu_location.x() - menubar_menu_margin() / 2, 0, text_width + menubar_menu_margin(), menubar_rect().height() - 1 });
+        menu.set_rect_in_menubar({ next_menu_location.x() - WSMenuManager::menubar_menu_margin() / 2, 0, text_width + WSMenuManager::menubar_menu_margin(), menubar_rect().height() - 1 });
         menu.set_text_rect_in_menubar({ next_menu_location, { text_width, menubar_rect().height() } });
         next_menu_location.move_by(menu.rect_in_menubar().width(), 0);
         ++index;
@@ -926,7 +921,7 @@ Rect WSWindowManager::menubar_rect() const
 {
     if (active_fullscreen_window())
         return {};
-    return { 0, 0, WSScreen::the().rect().width(), 18 };
+    return m_menu_manager.menubar_rect();
 }
 
 void WSWindowManager::draw_window_switcher()