Skip to content

Commit

Permalink
Merge pull request #3153 from hbatagelo/feature/1369
Browse files Browse the repository at this point in the history
Make server-side decorations scale aware
  • Loading branch information
Saviq authored Dec 15, 2023
2 parents f5f662b + 359a174 commit bc6864b
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 46 deletions.
20 changes: 15 additions & 5 deletions src/server/shell/decoration/basic_decoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,15 @@ void msd::BasicDecoration::set_cursor(std::string const& cursor_image_name)
shell->modify_surface(session, decoration_surface, spec);
}

void msd::BasicDecoration::set_scale(float new_scale)
{
scale = new_scale;
window_state_updated();
}

auto msd::BasicDecoration::new_window_state() const -> std::unique_ptr<WindowState>
{
return std::make_unique<WindowState>(static_geometry, window_surface);
return std::make_unique<WindowState>(static_geometry, window_surface, scale);
}

auto msd::BasicDecoration::create_surface() const -> std::shared_ptr<scene::Surface>
Expand Down Expand Up @@ -369,7 +375,8 @@ void msd::BasicDecoration::update(
&WindowState::titlebar_rect,
&WindowState::left_border_rect,
&WindowState::right_border_rect,
&WindowState::bottom_border_rect}) ||
&WindowState::bottom_border_rect,
&WindowState::scale}) ||
input_updated({
&InputState::buttons}))
{
Expand All @@ -383,7 +390,8 @@ void msd::BasicDecoration::update(
if (window_updated({
&WindowState::focused_state,
&WindowState::side_border_width,
&WindowState::side_border_height}))
&WindowState::side_border_height,
&WindowState::scale}))
{
new_buffers.emplace_back(
buffer_streams->left_border,
Expand All @@ -396,7 +404,8 @@ void msd::BasicDecoration::update(
if (window_updated({
&WindowState::focused_state,
&WindowState::bottom_border_width,
&WindowState::bottom_border_height}))
&WindowState::bottom_border_height,
&WindowState::scale}))
{
new_buffers.emplace_back(
buffer_streams->bottom_border,
Expand All @@ -406,7 +415,8 @@ void msd::BasicDecoration::update(
if (window_updated({
&WindowState::focused_state,
&WindowState::window_name,
&WindowState::titlebar_rect}) ||
&WindowState::titlebar_rect,
&WindowState::scale}) ||
input_updated({
&InputState::buttons}))
{
Expand Down
4 changes: 4 additions & 0 deletions src/server/shell/decoration/basic_decoration.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class BasicDecoration
void request_close();
void set_cursor(std::string const& cursor_image_name);

void set_scale(float scale) override;

protected:
/// Creates an up-to-date WindowState object
auto new_window_state() const -> std::unique_ptr<WindowState>;
Expand All @@ -108,6 +110,8 @@ class BasicDecoration
std::shared_ptr<input::CursorImages> const cursor_images;
std::shared_ptr<scene::Session> const session;

float scale{1.0f};

class BufferStreams;
std::unique_ptr<BufferStreams> buffer_streams;
std::unique_ptr<Renderer> renderer;
Expand Down
59 changes: 57 additions & 2 deletions src/server/shell/decoration/basic_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "basic_manager.h"
#include "decoration.h"

#include <mir/graphics/display_configuration.h>
#include <mir/graphics/null_display_configuration_observer.h>

#include <boost/throw_exception.hpp>
#include <vector>

Expand All @@ -25,9 +28,47 @@ namespace mg = mir::graphics;
namespace msh = mir::shell;
namespace msd = mir::shell::decoration;

msd::BasicManager::BasicManager(DecorationBuilder&& decoration_builder)
: decoration_builder{decoration_builder}
class msd::DisplayConfigurationListener : public mg::NullDisplayConfigurationObserver
{
public:
using Callback = std::function<void(mg::DisplayConfiguration const&)>;

explicit DisplayConfigurationListener(Callback callback) : callback{std::move(callback)} {}

private:
void initial_configuration(std::shared_ptr<mg::DisplayConfiguration const> const& config) override
{
callback(*config);
}
void configuration_applied(std::shared_ptr<mg::DisplayConfiguration const> const& config) override
{
callback(*config);
}

Callback const callback;
};

msd::BasicManager::BasicManager(
ObserverRegistrar<mg::DisplayConfigurationObserver>& display_configuration_observers,
DecorationBuilder&& decoration_builder) :
decoration_builder{std::move(decoration_builder)},
display_config_monitor{std::make_shared<DisplayConfigurationListener>(
[&](mg::DisplayConfiguration const& config)
{
// Use the maximum scale to ensure sharp-looking decorations on all outputs
auto max_output_scale{0.0f};
config.for_each_output(
[&](mg::DisplayConfigurationOutput const& output)
{
if (!output.used || !output.connected) return;
if (!output.valid() || (output.current_mode_index >= output.modes.size())) return;

max_output_scale = std::max(max_output_scale, output.scale);
});
set_scale(max_output_scale);
})}
{
display_configuration_observers.register_interest(display_config_monitor);
}

msd::BasicManager::~BasicManager()
Expand All @@ -53,6 +94,7 @@ void msd::BasicManager::decorate(std::shared_ptr<ms::Surface> const& surface)
lock.unlock();
auto decoration = decoration_builder(locked_shell, surface);
lock.lock();
decoration->set_scale(scale);
decorations[surface.get()] = std::move(decoration);
}
}
Expand Down Expand Up @@ -85,3 +127,16 @@ void msd::BasicManager::undecorate_all()
// Destroy the decorations outside the lock
to_destroy.clear();
}

void msd::BasicManager::set_scale(float new_scale)
{
std::lock_guard lock{mutex};
if (new_scale != scale)
{
scale = new_scale;
for (auto& it : decorations)
{
it.second->set_scale(scale);
}
}
}
18 changes: 15 additions & 3 deletions src/server/shell/decoration/basic_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@
#define MIR_SHELL_DECORATION_BASIC_MANAGER_H_

#include "manager.h"

#include <mir/observer_registrar.h>

#include <functional>
#include <unordered_map>
#include <mutex>

namespace mir::graphics { class DisplayConfigurationObserver; }

namespace mir
{
class Executor;
Expand All @@ -35,17 +40,20 @@ class Shell;
namespace decoration
{
class Decoration;
class DisplayConfigurationListener;

/// Facilitates decorating windows with Mir's built-in server size decorations
class BasicManager
: public Manager
class BasicManager :
public Manager
{
public:
using DecorationBuilder = std::function<std::unique_ptr<Decoration>(
std::shared_ptr<shell::Shell> const& shell,
std::shared_ptr<scene::Surface> const& surface)>;

BasicManager(DecorationBuilder&& decoration_builder);
BasicManager(
mir::ObserverRegistrar<mir::graphics::DisplayConfigurationObserver>& display_configuration_observers,
DecorationBuilder&& decoration_builder);
~BasicManager();

void init(std::weak_ptr<shell::Shell> const& shell) override;
Expand All @@ -55,10 +63,14 @@ class BasicManager

private:
DecorationBuilder const decoration_builder;
std::shared_ptr<DisplayConfigurationListener> const display_config_monitor;
std::weak_ptr<shell::Shell> shell;

std::mutex mutex;
std::unordered_map<scene::Surface*, std::unique_ptr<Decoration>> decorations;
float scale{1.0f};

void set_scale(float new_scale);
};
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/server/shell/decoration/decoration.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Decoration
Decoration() = default;
virtual ~Decoration() = default;

virtual void set_scale(float new_scale) = 0;

private:
Decoration(Decoration const&) = delete;
Decoration& operator=(Decoration const&) = delete;
Expand Down
Loading

0 comments on commit bc6864b

Please sign in to comment.