Skip to content

WindowServer+Taskbar: Add an optional global menu #25939

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Base/home/anon/.config/Taskbar.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ Browser=0:Browser.af
FileManager=1:FileManager.af
Terminal=2:Terminal.af
TextEditor=3:TextEditor.af

[GlobalMenu]
Enabled=false
3 changes: 3 additions & 0 deletions Userland/Applications/DisplaySettings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ stringify_gml(BackgroundSettings.gml BackgroundSettingsGML.h background_settings
stringify_gml(DesktopSettings.gml DesktopSettingsGML.h desktop_settings_gml)
stringify_gml(EffectsSettings.gml EffectsSettingsGML.h effects_settings_gml)
stringify_gml(FontSettings.gml FontSettingsGML.h font_settings_gml)
stringify_gml(InterfaceSettings.gml InterfaceSettingsGML.h interface_settings_gml)
stringify_gml(MonitorSettings.gml MonitorSettingsGML.h monitor_settings_window_gml)
stringify_gml(ThemesSettings.gml ThemesSettingsGML.h themes_settings_gml)

Expand All @@ -18,6 +19,7 @@ set(SOURCES
FontSettingsWidget.cpp
MonitorSettingsWidget.cpp
MonitorWidget.cpp
InterfaceSettingsWidget.cpp
ThemePreviewWidget.cpp
ThemesSettingsWidget.cpp
main.cpp
Expand All @@ -28,6 +30,7 @@ set(GENERATED_SOURCES
DesktopSettingsGML.h
EffectsSettingsGML.h
FontSettingsGML.h
InterfaceSettingsGML.h
MonitorSettingsGML.h
ThemesSettingsGML.h
)
Expand Down
33 changes: 33 additions & 0 deletions Userland/Applications/DisplaySettings/InterfaceSettings.gml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@GUI::Widget {
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
margins: [8]
spacing: 8
}

@GUI::GroupBox {
preferred_height: "shrink"
title: "Global menu"
layout: @GUI::VerticalBoxLayout {
margins: [8]
spacing: 2
}

@GUI::Widget {
layout: @GUI::HorizontalBoxLayout {
spacing: 16
}

@GUI::Widget {
layout: @GUI::VerticalBoxLayout {
margins: [4, 0, 0, 0]
}

@GUI::CheckBox {
name: "global_menu_checkbox"
text: "Enable the global menu"
}
}
}
}
}
39 changes: 39 additions & 0 deletions Userland/Applications/DisplaySettings/InterfaceSettingsWidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2023, Filiph Sandström <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include "InterfaceSettingsWidget.h"
#include <Applications/DisplaySettings/InterfaceSettingsGML.h>
#include <LibConfig/Client.h>
#include <LibGUI/CheckBox.h>

namespace GUI {

namespace DisplaySettings {

InterfaceSettingsWidget::InterfaceSettingsWidget()
{
load_from_gml(interface_settings_gml).release_value_but_fixme_should_propagate_errors();

m_global_menu = *find_descendant_of_type_named<GUI::CheckBox>("global_menu_checkbox");
load_settings();

m_global_menu->on_checked = [this](bool) {
set_modified(true);
};
}

void InterfaceSettingsWidget::load_settings()
{
m_global_menu->set_checked(Config::read_bool("Taskbar"sv, "GlobalMenu"sv, "Enabled"sv, false));
}

void InterfaceSettingsWidget::apply_settings()
{
Config::write_bool("Taskbar"sv, "GlobalMenu"sv, "Enabled"sv, m_global_menu->is_checked());
}
}

}
32 changes: 32 additions & 0 deletions Userland/Applications/DisplaySettings/InterfaceSettingsWidget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023, Filiph Sandström <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <LibGUI/SettingsWindow.h>
#include <LibGUI/SystemEffects.h>

namespace GUI {

namespace DisplaySettings {

class InterfaceSettingsWidget final : public SettingsWindow::Tab {
C_OBJECT(InterfaceSettingsWidget);

public:
virtual ~InterfaceSettingsWidget() override = default;

virtual void apply_settings() override;

private:
InterfaceSettingsWidget();

void load_settings();
RefPtr<GUI::CheckBox> m_global_menu;
};
}

}
6 changes: 5 additions & 1 deletion Userland/Applications/DisplaySettings/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "DesktopSettingsWidget.h"
#include "EffectsSettingsWidget.h"
#include "FontSettingsWidget.h"
#include "InterfaceSettingsWidget.h"
#include "MonitorSettingsWidget.h"
#include "ThemesSettingsWidget.h"
#include <LibConfig/Client.h>
Expand All @@ -25,7 +26,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio thread recvfd sendfd rpath cpath wpath unix proc exec"));

auto app = TRY(GUI::Application::create(arguments));
Config::pledge_domain("WindowManager");
Config::pledge_domains({ "WindowManager", "Taskbar" });

StringView selected_tab;
Core::ArgsParser args_parser;
Expand All @@ -43,9 +44,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
(void)TRY(window->add_tab<DisplaySettings::MonitorSettingsWidget>("Monitor"_string, "monitor"sv));
(void)TRY(window->add_tab<DisplaySettings::DesktopSettingsWidget>("Workspaces"_string, "workspaces"sv));
(void)TRY(window->add_tab<GUI::DisplaySettings::EffectsSettingsWidget>("Effects"_string, "effects"sv));
(void)TRY(window->add_tab<GUI::DisplaySettings::InterfaceSettingsWidget>("Interface"_string, "interface"sv));
window->set_active_tab(selected_tab);

window->set_icon(app_icon.bitmap_for_size(16));
// FIXME: Support overflowing tabs
window->resize(440, 570);

window->show();
return app->exec();
Expand Down
1 change: 1 addition & 0 deletions Userland/Services/Taskbar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ serenity_component(
set(SOURCES
main.cpp
ClockWidget.cpp
GlobalMenuWindow.cpp
QuickLaunchWidget.cpp
ShutdownDialog.cpp
TaskbarButton.cpp
Expand Down
98 changes: 98 additions & 0 deletions Userland/Services/Taskbar/GlobalMenuWindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2022, Filiph Sandström <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include "GlobalMenuWindow.h"
#include <AK/Debug.h>
#include <AK/IterationDecision.h>
#include <LibGUI/BoxLayout.h>
#include <LibGUI/ConnectionToWindowManagerServer.h>
#include <LibGUI/ConnectionToWindowServer.h>
#include <LibGUI/Desktop.h>
#include <LibGUI/Frame.h>
#include <LibGUI/Menu.h>
#include <LibGUI/Painter.h>
#include <LibGUI/Window.h>
#include <LibGfx/Forward.h>
#include <LibGfx/Palette.h>
#include <serenity.h>
#include <stdio.h>

class MenuWidget final : public GUI::Widget {
C_OBJECT(MenuWidget);

public:
virtual ~MenuWidget() override = default;

private:
MenuWidget() = default;

virtual void paint_event(GUI::PaintEvent&) override
{
GUI::Painter painter(*this);
painter.fill_rect({ 0, 0, width(), GlobalMenuWindow::global_menu_height() }, palette().button());
painter.draw_line({ 0, height() - 1 }, { width() - 1, height() - 1 }, palette().threed_highlight());
}
};

GlobalMenuWindow::GlobalMenuWindow()
{
set_window_type(GUI::WindowType::GlobalMenu);
set_title("Global Menu");

auto const& rect = GUI::Desktop::the().rects()[GUI::Desktop::the().main_screen_index()];
set_rect({ rect.x(), rect.y(), rect.width(), global_menu_height() });

auto main_widget = set_main_widget<MenuWidget>();
main_widget->set_layout<GUI::HorizontalBoxLayout>();
main_widget->layout()->set_margins(GUI::Margins(0, 6, 1, 6));
main_widget->set_height(GlobalMenuWindow::global_menu_height());

m_global_menu_area_container = main_widget->add<GUI::Frame>();
m_global_menu_area_container->set_layout<GUI::VerticalBoxLayout>();
m_global_menu_area_container->set_frame_style(Gfx::FrameStyle::NoFrame);

m_enabled = Config::read_bool("Taskbar"sv, "GlobalMenu"sv, "Enabled"sv, false);
update_global_menu_enabled();
}

void GlobalMenuWindow::config_bool_did_change(StringView domain, StringView group, StringView key, bool value)
{
if (domain == "Taskbar"sv && group == "GlobalMenu"sv) {
if (key == "Enabled"sv) {
m_enabled = value;
}

update_global_menu_enabled();
update_global_menu_area();
}
}

void GlobalMenuWindow::update_global_menu_enabled()
{
if (m_enabled)
show();
else
hide();

GUI::ConnectionToWindowManagerServer::the().async_set_global_menu_area_enabled(m_enabled);
}
void GlobalMenuWindow::update_global_menu_area()
{
if (!main_widget())
return;

m_global_menu_area_container->update();

auto rect = m_global_menu_area_container->window_relative_rect().centered_within(main_widget()->rect());
GUI::ConnectionToWindowManagerServer::the().async_set_global_menu_area_rect(rect.translated(-1, 0));
}

void GlobalMenuWindow::screen_rects_change_event(GUI::ScreenRectsChangeEvent& event)
{
auto const& rect = event.rects()[event.main_screen_index()];
set_rect({ rect.x(), rect.y(), rect.width(), global_menu_height() });
update_global_menu_area();
}
39 changes: 39 additions & 0 deletions Userland/Services/Taskbar/GlobalMenuWindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2022, Filiph Sandström <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <LibConfig/Client.h>
#include <LibConfig/Listener.h>
#include <LibGUI/Frame.h>
#include <LibGUI/Widget.h>
#include <LibGUI/Window.h>

class GlobalMenuWindow final : public GUI::Window
, public Config::Listener {
C_OBJECT(GlobalMenuWindow);

public:
virtual ~GlobalMenuWindow() override = default;

static int global_menu_height() { return 26; }

virtual void config_bool_did_change(StringView, StringView, StringView, bool) override;

private:
explicit GlobalMenuWindow();

void on_screen_rects_change(Vector<Gfx::IntRect, 4> const&, size_t);

void update_global_menu_area();
void update_global_menu_enabled();

virtual void screen_rects_change_event(GUI::ScreenRectsChangeEvent&) override;

bool m_enabled { false };
Gfx::IntSize m_global_menu_area_size;
RefPtr<GUI::Frame> m_global_menu_area_container;
};
15 changes: 8 additions & 7 deletions Userland/Services/Taskbar/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/

#include "GlobalMenuWindow.h"
#include "ShutdownDialog.h"
#include "TaskbarWindow.h"
#include <AK/Debug.h>
Expand Down Expand Up @@ -58,20 +59,20 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)

TRY(Core::System::pledge("stdio recvfd sendfd proc exec rpath"));

auto window = TRY(TaskbarWindow::create());
auto taskbar = TRY(TaskbarWindow::create());

auto menu = TRY(build_system_menu(*window));
auto menu = TRY(build_system_menu(*taskbar));
menu->realize_menu_if_needed();
window->add_system_menu(menu);

window->show();

window->make_window_manager(
taskbar->add_system_menu(menu);
taskbar->show();
taskbar->make_window_manager(
WindowServer::WMEventMask::WindowStateChanges
| WindowServer::WMEventMask::WindowRemovals
| WindowServer::WMEventMask::WindowIconChanges
| WindowServer::WMEventMask::WorkspaceChanges);

auto global_menu = TRY(GlobalMenuWindow::try_create());

return app->exec();
}

Expand Down
1 change: 1 addition & 0 deletions Userland/Services/WindowServer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(SOURCES
Compositor.cpp
Cursor.cpp
EventLoop.cpp
GlobalMenu.cpp
main.cpp
Menu.cpp
Menubar.cpp
Expand Down
3 changes: 2 additions & 1 deletion Userland/Services/WindowServer/ConnectionFromClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,8 @@ void ConnectionFromClient::create_window(i32 window_id, i32 process_id, Gfx::Int
window->refresh_client_size();
}
if (window->type() == WindowType::Desktop) {
window->set_rect(Screen::bounding_rect());
// FIXME: Use the window's screen.
window->set_rect(WindowManager::the().desktop_rect(Screen::main()));
window->recalculate_rect();
}
window->set_alpha_hit_threshold(alpha_hit_threshold);
Expand Down
Loading
Loading