mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:27:45 +00:00
Taskbar: Don't create buttons for modal windows
Since the user can't really do much with windows that are blocked by a modal window, there is no point in showing multiple buttons.
This commit is contained in:
parent
bbdf0665fc
commit
a269e3e573
5 changed files with 114 additions and 24 deletions
|
@ -35,6 +35,7 @@
|
||||||
#include <LibGUI/Frame.h>
|
#include <LibGUI/Frame.h>
|
||||||
#include <LibGUI/Painter.h>
|
#include <LibGUI/Painter.h>
|
||||||
#include <LibGUI/Window.h>
|
#include <LibGUI/Window.h>
|
||||||
|
#include <LibGUI/WindowServerConnection.h>
|
||||||
#include <LibGfx/Palette.h>
|
#include <LibGfx/Palette.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -74,10 +75,6 @@ TaskbarWindow::TaskbarWindow()
|
||||||
|
|
||||||
m_default_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/window.png");
|
m_default_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/window.png");
|
||||||
|
|
||||||
WindowList::the().aid_create_button = [this](auto& identifier) {
|
|
||||||
return create_button(identifier);
|
|
||||||
};
|
|
||||||
|
|
||||||
create_quick_launch_bar();
|
create_quick_launch_bar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +158,67 @@ static bool should_include_window(GUI::WindowType window_type, bool is_frameless
|
||||||
return window_type == GUI::WindowType::Normal && !is_frameless;
|
return window_type == GUI::WindowType::Normal && !is_frameless;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskbarWindow::add_window_button(::Window& window, const WindowIdentifier& identifier)
|
||||||
|
{
|
||||||
|
if (window.button())
|
||||||
|
return;
|
||||||
|
window.set_button(create_button(identifier));
|
||||||
|
auto* button = window.button();
|
||||||
|
button->on_click = [window = &window, identifier, button](auto) {
|
||||||
|
// We need to look at the button's checked state here to figure
|
||||||
|
// out if the application is active or not. That's because this
|
||||||
|
// button's window may not actually be active when a modal window
|
||||||
|
// is displayed, in which case window->is_active() would return
|
||||||
|
// false because window is the modal window's owner (which is not
|
||||||
|
// active)
|
||||||
|
if (window->is_minimized() || !button->is_checked()) {
|
||||||
|
GUI::WindowServerConnection::the().post_message(Messages::WindowServer::WM_SetActiveWindow(identifier.client_id(), identifier.window_id()));
|
||||||
|
} else {
|
||||||
|
GUI::WindowServerConnection::the().post_message(Messages::WindowServer::WM_SetWindowMinimized(identifier.client_id(), identifier.window_id(), true));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskbarWindow::remove_window_button(::Window& window)
|
||||||
|
{
|
||||||
|
auto* button = window.button();
|
||||||
|
if (!button)
|
||||||
|
return;
|
||||||
|
window.set_button(nullptr);
|
||||||
|
button->remove_from_parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskbarWindow::update_window_button(::Window& window, bool show_as_active)
|
||||||
|
{
|
||||||
|
auto* button = window.button();
|
||||||
|
if (!button)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (window.is_minimized()) {
|
||||||
|
button->set_foreground_color(Color::DarkGray);
|
||||||
|
} else {
|
||||||
|
button->set_foreground_color(Color::Black);
|
||||||
|
}
|
||||||
|
button->set_text(window.title());
|
||||||
|
button->set_checked(show_as_active);
|
||||||
|
}
|
||||||
|
|
||||||
|
::Window* TaskbarWindow::find_window_owner(::Window& window) const
|
||||||
|
{
|
||||||
|
if (!window.is_modal())
|
||||||
|
return &window;
|
||||||
|
|
||||||
|
::Window* parent = nullptr;
|
||||||
|
auto* current_window = &window;
|
||||||
|
while (current_window) {
|
||||||
|
parent = WindowList::the().find_parent(*current_window);
|
||||||
|
if (!parent || !parent->is_modal())
|
||||||
|
break;
|
||||||
|
current_window = parent;
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
void TaskbarWindow::wm_event(GUI::WMEvent& event)
|
void TaskbarWindow::wm_event(GUI::WMEvent& event)
|
||||||
{
|
{
|
||||||
WindowIdentifier identifier { event.client_id(), event.window_id() };
|
WindowIdentifier identifier { event.client_id(), event.window_id() };
|
||||||
|
@ -198,6 +256,7 @@ void TaskbarWindow::wm_event(GUI::WMEvent& event)
|
||||||
if (auto* window = WindowList::the().window(identifier)) {
|
if (auto* window = WindowList::the().window(identifier)) {
|
||||||
auto buffer = SharedBuffer::create_from_shbuf_id(changed_event.icon_buffer_id());
|
auto buffer = SharedBuffer::create_from_shbuf_id(changed_event.icon_buffer_id());
|
||||||
ASSERT(buffer);
|
ASSERT(buffer);
|
||||||
|
if (window->button())
|
||||||
window->button()->set_icon(Gfx::Bitmap::create_with_shared_buffer(Gfx::BitmapFormat::RGBA32, *buffer, changed_event.icon_size()));
|
window->button()->set_icon(Gfx::Bitmap::create_with_shared_buffer(Gfx::BitmapFormat::RGBA32, *buffer, changed_event.icon_size()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -217,18 +276,27 @@ void TaskbarWindow::wm_event(GUI::WMEvent& event)
|
||||||
if (!should_include_window(changed_event.window_type(), changed_event.is_frameless()))
|
if (!should_include_window(changed_event.window_type(), changed_event.is_frameless()))
|
||||||
break;
|
break;
|
||||||
auto& window = WindowList::the().ensure_window(identifier);
|
auto& window = WindowList::the().ensure_window(identifier);
|
||||||
|
window.set_parent_identifier({ changed_event.parent_client_id(), changed_event.parent_window_id() });
|
||||||
|
if (!window.is_modal())
|
||||||
|
add_window_button(window, identifier);
|
||||||
|
else
|
||||||
|
remove_window_button(window);
|
||||||
window.set_title(changed_event.title());
|
window.set_title(changed_event.title());
|
||||||
window.set_rect(changed_event.rect());
|
window.set_rect(changed_event.rect());
|
||||||
|
window.set_modal(changed_event.is_modal());
|
||||||
window.set_active(changed_event.is_active());
|
window.set_active(changed_event.is_active());
|
||||||
window.set_minimized(changed_event.is_minimized());
|
window.set_minimized(changed_event.is_minimized());
|
||||||
window.set_progress(changed_event.progress());
|
window.set_progress(changed_event.progress());
|
||||||
if (window.is_minimized()) {
|
|
||||||
window.button()->set_foreground_color(Color::DarkGray);
|
auto* window_owner = find_window_owner(window);
|
||||||
} else {
|
if (window_owner == &window) {
|
||||||
window.button()->set_foreground_color(Color::Black);
|
update_window_button(window, window.is_active());
|
||||||
|
} else if (window_owner) {
|
||||||
|
// check the window owner's button if the modal's window button
|
||||||
|
// would have been checked
|
||||||
|
ASSERT(window.is_modal());
|
||||||
|
update_window_button(*window_owner, window.is_active());
|
||||||
}
|
}
|
||||||
window.button()->set_text(changed_event.title());
|
|
||||||
window.button()->set_checked(changed_event.is_active());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -42,6 +42,10 @@ private:
|
||||||
void create_quick_launch_bar();
|
void create_quick_launch_bar();
|
||||||
void on_screen_rect_change(const Gfx::IntRect&);
|
void on_screen_rect_change(const Gfx::IntRect&);
|
||||||
NonnullRefPtr<GUI::Button> create_button(const WindowIdentifier&);
|
NonnullRefPtr<GUI::Button> create_button(const WindowIdentifier&);
|
||||||
|
void add_window_button(::Window&, const WindowIdentifier&);
|
||||||
|
void remove_window_button(::Window&);
|
||||||
|
void update_window_button(::Window&, bool);
|
||||||
|
::Window* find_window_owner(::Window&) const;
|
||||||
|
|
||||||
virtual void wm_event(GUI::WMEvent&) override;
|
virtual void wm_event(GUI::WMEvent&) override;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
class WindowIdentifier {
|
class WindowIdentifier {
|
||||||
public:
|
public:
|
||||||
|
WindowIdentifier() = default;
|
||||||
WindowIdentifier(int client_id, int window_id)
|
WindowIdentifier(int client_id, int window_id)
|
||||||
: m_client_id(client_id)
|
: m_client_id(client_id)
|
||||||
, m_window_id(window_id)
|
, m_window_id(window_id)
|
||||||
|
@ -44,6 +45,11 @@ public:
|
||||||
return m_client_id == other.m_client_id && m_window_id == other.m_window_id;
|
return m_client_id == other.m_client_id && m_window_id == other.m_window_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_valid() const
|
||||||
|
{
|
||||||
|
return m_client_id != -1 && m_window_id != -1;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_client_id { -1 };
|
int m_client_id { -1 };
|
||||||
int m_window_id { -1 };
|
int m_window_id { -1 };
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WindowList.h"
|
#include "WindowList.h"
|
||||||
#include <LibGUI/WindowServerConnection.h>
|
|
||||||
|
|
||||||
WindowList& WindowList::the()
|
WindowList& WindowList::the()
|
||||||
{
|
{
|
||||||
|
@ -35,6 +34,19 @@ WindowList& WindowList::the()
|
||||||
return *s_the;
|
return *s_the;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window* WindowList::find_parent(const Window& window)
|
||||||
|
{
|
||||||
|
if (!window.parent_identifier().is_valid())
|
||||||
|
return nullptr;
|
||||||
|
for (auto& it : m_windows)
|
||||||
|
{
|
||||||
|
auto& w = *it.value;
|
||||||
|
if (w.identifier() == window.parent_identifier())
|
||||||
|
return &w;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Window* WindowList::window(const WindowIdentifier& identifier)
|
Window* WindowList::window(const WindowIdentifier& identifier)
|
||||||
{
|
{
|
||||||
auto it = m_windows.find(identifier);
|
auto it = m_windows.find(identifier);
|
||||||
|
@ -49,14 +61,6 @@ Window& WindowList::ensure_window(const WindowIdentifier& identifier)
|
||||||
if (it != m_windows.end())
|
if (it != m_windows.end())
|
||||||
return *it->value;
|
return *it->value;
|
||||||
auto window = make<Window>(identifier);
|
auto window = make<Window>(identifier);
|
||||||
window->set_button(aid_create_button(identifier));
|
|
||||||
window->button()->on_click = [window = window.ptr(), identifier](auto) {
|
|
||||||
if (window->is_minimized() || !window->is_active()) {
|
|
||||||
GUI::WindowServerConnection::the().post_message(Messages::WindowServer::WM_SetActiveWindow(identifier.client_id(), identifier.window_id()));
|
|
||||||
} else {
|
|
||||||
GUI::WindowServerConnection::the().post_message(Messages::WindowServer::WM_SetWindowMinimized(identifier.client_id(), identifier.window_id(), true));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
auto& window_ref = *window;
|
auto& window_ref = *window;
|
||||||
m_windows.set(identifier, move(window));
|
m_windows.set(identifier, move(window));
|
||||||
return window_ref;
|
return window_ref;
|
||||||
|
|
|
@ -45,7 +45,10 @@ public:
|
||||||
m_button->remove_from_parent();
|
m_button->remove_from_parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowIdentifier identifier() const { return m_identifier; }
|
const WindowIdentifier& identifier() const { return m_identifier; }
|
||||||
|
|
||||||
|
void set_parent_identifier(const WindowIdentifier& parent_identifier) { m_parent_identifier = parent_identifier; }
|
||||||
|
const WindowIdentifier& parent_identifier() const { return m_parent_identifier; }
|
||||||
|
|
||||||
String title() const { return m_title; }
|
String title() const { return m_title; }
|
||||||
void set_title(const String& title) { m_title = title; }
|
void set_title(const String& title) { m_title = title; }
|
||||||
|
@ -62,11 +65,15 @@ public:
|
||||||
void set_minimized(bool minimized) { m_minimized = minimized; }
|
void set_minimized(bool minimized) { m_minimized = minimized; }
|
||||||
bool is_minimized() const { return m_minimized; }
|
bool is_minimized() const { return m_minimized; }
|
||||||
|
|
||||||
|
void set_modal(bool modal) { m_modal = modal; }
|
||||||
|
bool is_modal() const { return m_modal; }
|
||||||
|
|
||||||
void set_progress(int progress)
|
void set_progress(int progress)
|
||||||
{
|
{
|
||||||
if (m_progress == progress)
|
if (m_progress == progress)
|
||||||
return;
|
return;
|
||||||
m_progress = progress;
|
m_progress = progress;
|
||||||
|
if (m_button)
|
||||||
m_button->update();
|
m_button->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +83,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WindowIdentifier m_identifier;
|
WindowIdentifier m_identifier;
|
||||||
|
WindowIdentifier m_parent_identifier;
|
||||||
String m_title;
|
String m_title;
|
||||||
Gfx::IntRect m_rect;
|
Gfx::IntRect m_rect;
|
||||||
RefPtr<GUI::Button> m_button;
|
RefPtr<GUI::Button> m_button;
|
||||||
RefPtr<Gfx::Bitmap> m_icon;
|
RefPtr<Gfx::Bitmap> m_icon;
|
||||||
bool m_active { false };
|
bool m_active { false };
|
||||||
bool m_minimized { false };
|
bool m_minimized { false };
|
||||||
|
bool m_modal { false };
|
||||||
int m_progress { -1 };
|
int m_progress { -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,12 +105,11 @@ public:
|
||||||
callback(*it.value);
|
callback(*it.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window* find_parent(const Window&);
|
||||||
Window* window(const WindowIdentifier&);
|
Window* window(const WindowIdentifier&);
|
||||||
Window& ensure_window(const WindowIdentifier&);
|
Window& ensure_window(const WindowIdentifier&);
|
||||||
void remove_window(const WindowIdentifier&);
|
void remove_window(const WindowIdentifier&);
|
||||||
|
|
||||||
Function<NonnullRefPtr<GUI::Button>(const WindowIdentifier&)> aid_create_button;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HashMap<WindowIdentifier, NonnullOwnPtr<Window>> m_windows;
|
HashMap<WindowIdentifier, NonnullOwnPtr<Window>> m_windows;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue