summaryrefslogtreecommitdiffstats
path: root/xbmc/windowing/wayland/ShellSurfaceXdgShell.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xbmc/windowing/wayland/ShellSurfaceXdgShell.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/xbmc/windowing/wayland/ShellSurfaceXdgShell.cpp b/xbmc/windowing/wayland/ShellSurfaceXdgShell.cpp
new file mode 100644
index 0000000..e92d33c
--- /dev/null
+++ b/xbmc/windowing/wayland/ShellSurfaceXdgShell.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "ShellSurfaceXdgShell.h"
+
+#include "Registry.h"
+#include "messaging/ApplicationMessenger.h"
+
+using namespace KODI::WINDOWING::WAYLAND;
+
+namespace
+{
+
+IShellSurface::State ConvertStateFlag(wayland::xdg_toplevel_state flag)
+{
+ switch(flag)
+ {
+ case wayland::xdg_toplevel_state::activated:
+ return IShellSurface::STATE_ACTIVATED;
+ case wayland::xdg_toplevel_state::fullscreen:
+ return IShellSurface::STATE_FULLSCREEN;
+ case wayland::xdg_toplevel_state::maximized:
+ return IShellSurface::STATE_MAXIMIZED;
+ case wayland::xdg_toplevel_state::resizing:
+ return IShellSurface::STATE_RESIZING;
+ default:
+ throw std::runtime_error(std::string("Unknown xdg_toplevel state flag ") + std::to_string(static_cast<std::underlying_type<decltype(flag)>::type> (flag)));
+ }
+}
+
+}
+
+CShellSurfaceXdgShell* CShellSurfaceXdgShell::TryCreate(IShellSurfaceHandler& handler, CConnection& connection, const wayland::surface_t& surface, std::string const& title, std::string const& class_)
+{
+ wayland::xdg_wm_base_t shell;
+ CRegistry registry{connection};
+ registry.RequestSingleton(shell, 1, 1, false);
+ registry.Bind();
+
+ if (shell)
+ {
+ return new CShellSurfaceXdgShell(handler, connection.GetDisplay(), shell, surface, title, class_);
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+CShellSurfaceXdgShell::CShellSurfaceXdgShell(IShellSurfaceHandler& handler, wayland::display_t& display, const wayland::xdg_wm_base_t& shell, const wayland::surface_t& surface, std::string const& title, std::string const& app_id)
+: m_handler{handler}, m_display{display}, m_shell{shell}, m_surface{surface}, m_xdgSurface{m_shell.get_xdg_surface(m_surface)}, m_xdgToplevel{m_xdgSurface.get_toplevel()}
+{
+ m_shell.on_ping() = [this](std::uint32_t serial)
+ {
+ m_shell.pong(serial);
+ };
+ m_xdgSurface.on_configure() = [this](std::uint32_t serial)
+ {
+ m_handler.OnConfigure(serial, m_configuredSize, m_configuredState);
+ };
+ m_xdgToplevel.on_close() = [this]()
+ {
+ m_handler.OnClose();
+ };
+ m_xdgToplevel.on_configure() = [this](std::int32_t width, std::int32_t height,
+ const std::vector<wayland::xdg_toplevel_state>& states) {
+ m_configuredSize.Set(width, height);
+ m_configuredState.reset();
+ for (auto state : states)
+ {
+ m_configuredState.set(ConvertStateFlag(state));
+ }
+ };
+ m_xdgToplevel.set_app_id(app_id);
+ m_xdgToplevel.set_title(title);
+ // Set sensible minimum size
+ m_xdgToplevel.set_min_size(300, 200);
+}
+
+void CShellSurfaceXdgShell::Initialize()
+{
+ // Commit surface to confirm role
+ // Don't do it in constructor since SetFullScreen might be called before
+ m_surface.commit();
+ // Make sure we get the initial configure before continuing
+ m_display.roundtrip();
+}
+
+void CShellSurfaceXdgShell::AckConfigure(std::uint32_t serial)
+{
+ m_xdgSurface.ack_configure(serial);
+}
+
+CShellSurfaceXdgShell::~CShellSurfaceXdgShell() noexcept
+{
+ // xdg_shell is picky: must destroy toplevel role before surface
+ m_xdgToplevel.proxy_release();
+ m_xdgSurface.proxy_release();
+}
+
+void CShellSurfaceXdgShell::SetFullScreen(const wayland::output_t& output, float)
+{
+ // xdg_shell does not support refresh rate setting at the moment
+ m_xdgToplevel.set_fullscreen(output);
+}
+
+void CShellSurfaceXdgShell::SetWindowed()
+{
+ m_xdgToplevel.unset_fullscreen();
+}
+
+void CShellSurfaceXdgShell::SetMaximized()
+{
+ m_xdgToplevel.set_maximized();
+}
+
+void CShellSurfaceXdgShell::UnsetMaximized()
+{
+ m_xdgToplevel.unset_maximized();
+}
+
+void CShellSurfaceXdgShell::SetMinimized()
+{
+ m_xdgToplevel.set_minimized();
+}
+
+void CShellSurfaceXdgShell::SetWindowGeometry(CRectInt geometry)
+{
+ m_xdgSurface.set_window_geometry(geometry.x1, geometry.y1, geometry.Width(), geometry.Height());
+}
+
+void CShellSurfaceXdgShell::StartMove(const wayland::seat_t& seat, std::uint32_t serial)
+{
+ m_xdgToplevel.move(seat, serial);
+}
+
+void CShellSurfaceXdgShell::StartResize(const wayland::seat_t& seat, std::uint32_t serial, wayland::shell_surface_resize edge)
+{
+ // wl_shell shell_surface_resize is identical to xdg_shell resize_edge
+ m_xdgToplevel.resize(seat, serial, static_cast<std::uint32_t> (edge));
+}
+
+void CShellSurfaceXdgShell::ShowShellContextMenu(const wayland::seat_t& seat, std::uint32_t serial, CPointInt position)
+{
+ m_xdgToplevel.show_window_menu(seat, serial, position.x, position.y);
+}