TaskbarWindow.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "TaskbarWindow.h"
  2. #include "TaskbarButton.h"
  3. #include <LibC/SharedBuffer.h>
  4. #include <LibGUI/GBoxLayout.h>
  5. #include <LibGUI/GButton.h>
  6. #include <LibGUI/GDesktop.h>
  7. #include <LibGUI/GEventLoop.h>
  8. #include <LibGUI/GFrame.h>
  9. #include <LibGUI/GWindow.h>
  10. #include <WindowServer/WSAPITypes.h>
  11. #include <stdio.h>
  12. //#define EVENT_DEBUG
  13. TaskbarWindow::TaskbarWindow()
  14. {
  15. set_window_type(GWindowType::Taskbar);
  16. set_title("Taskbar");
  17. on_screen_rect_change(GDesktop::the().rect());
  18. GDesktop::the().on_rect_change = [this](const Rect& rect) { on_screen_rect_change(rect); };
  19. auto widget = GFrame::construct();
  20. widget->set_fill_with_background_color(true);
  21. widget->set_layout(make<GBoxLayout>(Orientation::Horizontal));
  22. widget->layout()->set_margins({ 3, 2, 3, 2 });
  23. widget->layout()->set_spacing(3);
  24. widget->set_frame_thickness(1);
  25. widget->set_frame_shape(FrameShape::Panel);
  26. widget->set_frame_shadow(FrameShadow::Raised);
  27. set_main_widget(widget);
  28. WindowList::the().aid_create_button = [this](auto& identifier) {
  29. return create_button(identifier);
  30. };
  31. }
  32. TaskbarWindow::~TaskbarWindow()
  33. {
  34. }
  35. void TaskbarWindow::on_screen_rect_change(const Rect& rect)
  36. {
  37. Rect new_rect { rect.x(), rect.bottom() - taskbar_height() + 1, rect.width(), taskbar_height() };
  38. set_rect(new_rect);
  39. }
  40. GButton* TaskbarWindow::create_button(const WindowIdentifier& identifier)
  41. {
  42. auto button = TaskbarButton::construct(identifier, main_widget());
  43. button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
  44. button->set_preferred_size(140, 22);
  45. button->set_checkable(true);
  46. button->set_text_alignment(TextAlignment::CenterLeft);
  47. return button;
  48. }
  49. static bool should_include_window(GWindowType window_type)
  50. {
  51. return window_type == GWindowType::Normal;
  52. }
  53. void TaskbarWindow::wm_event(GWMEvent& event)
  54. {
  55. WindowIdentifier identifier { event.client_id(), event.window_id() };
  56. switch (event.type()) {
  57. case GEvent::WM_WindowRemoved: {
  58. #ifdef EVENT_DEBUG
  59. auto& removed_event = static_cast<GWMWindowRemovedEvent&>(event);
  60. dbgprintf("WM_WindowRemoved: client_id=%d, window_id=%d\n",
  61. removed_event.client_id(),
  62. removed_event.window_id());
  63. #endif
  64. WindowList::the().remove_window(identifier);
  65. update();
  66. break;
  67. }
  68. case GEvent::WM_WindowRectChanged: {
  69. #ifdef EVENT_DEBUG
  70. auto& changed_event = static_cast<GWMWindowRectChangedEvent&>(event);
  71. dbgprintf("WM_WindowRectChanged: client_id=%d, window_id=%d, rect=%s\n",
  72. changed_event.client_id(),
  73. changed_event.window_id(),
  74. changed_event.rect().to_string().characters());
  75. #endif
  76. break;
  77. }
  78. case GEvent::WM_WindowIconBitmapChanged: {
  79. auto& changed_event = static_cast<GWMWindowIconBitmapChangedEvent&>(event);
  80. #ifdef EVENT_DEBUG
  81. dbgprintf("WM_WindowIconBitmapChanged: client_id=%d, window_id=%d, icon_buffer_id=%d\n",
  82. changed_event.client_id(),
  83. changed_event.window_id(),
  84. changed_event.icon_buffer_id());
  85. #endif
  86. if (auto* window = WindowList::the().window(identifier)) {
  87. auto buffer = SharedBuffer::create_from_shared_buffer_id(changed_event.icon_buffer_id());
  88. ASSERT(buffer);
  89. window->button()->set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *buffer, changed_event.icon_size()));
  90. }
  91. break;
  92. }
  93. case GEvent::WM_WindowStateChanged: {
  94. auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event);
  95. #ifdef EVENT_DEBUG
  96. dbgprintf("WM_WindowStateChanged: client_id=%d, window_id=%d, title=%s, rect=%s, is_active=%u, is_minimized=%u\n",
  97. changed_event.client_id(),
  98. changed_event.window_id(),
  99. changed_event.title().characters(),
  100. changed_event.rect().to_string().characters(),
  101. changed_event.is_active(),
  102. changed_event.is_minimized());
  103. #endif
  104. if (!should_include_window(changed_event.window_type()))
  105. break;
  106. auto& window = WindowList::the().ensure_window(identifier);
  107. window.set_title(changed_event.title());
  108. window.set_rect(changed_event.rect());
  109. window.set_active(changed_event.is_active());
  110. window.set_minimized(changed_event.is_minimized());
  111. if (window.is_minimized()) {
  112. window.button()->set_foreground_color(Color::DarkGray);
  113. window.button()->set_text(String::format("[%s]", changed_event.title().characters()));
  114. } else {
  115. window.button()->set_foreground_color(Color::Black);
  116. window.button()->set_text(changed_event.title());
  117. }
  118. window.button()->set_checked(changed_event.is_active());
  119. break;
  120. }
  121. default:
  122. break;
  123. }
  124. }