提交 7e15d287 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!104 window: fullscreen & toast window

Merge pull request !104 from Night/master
......@@ -64,6 +64,7 @@ void PlatformApiStub::update_window_state(const WindowStateUpdate &state) {
out->set_frame_bottom(in.frame.bottom);
out->set_task_id(in.task_id);
out->set_stack_id(in.stack_id);
out->set_videofullscreen(false);
};
for (const auto &window : state.updated_windows) {
......
......@@ -277,6 +277,8 @@ set(SOURCES
anbox/platform/sdl/sdl_wrapper.h
anbox/platform/sdl/window.cpp
anbox/platform/sdl/window.h
anbox/platform/sdl/toast_window.cpp
anbox/platform/sdl/toast_window.h
anbox/protobuf/anbox_bridge.proto
anbox/protobuf/anbox_container.proto
......
......@@ -84,7 +84,8 @@ void PlatformApiSkeleton::handle_window_state_update_event(const anbox::protobuf
graphics::Rect(window.frame_left(), window.frame_top(),
window.frame_right(), window.frame_bottom()),
window.package_name(), wm::Task::Id(window.task_id()),
wm::Stack::Id(window.stack_id()));
wm::Stack::Id(window.stack_id()),
window.has_videofullscreen() && window.videofullscreen());
};
wm::WindowState::List updated;
......
......@@ -196,6 +196,7 @@ anbox::cmds::SessionManager::SessionManager()
platform->set_window_manager(window_manager);
platform->set_renderer(gl_server->renderer());
platform->create_toast_window();
window_manager->setup();
android_api_stub->set_platform(platform);
......
......@@ -18,6 +18,7 @@
#include "anbox/graphics/multi_window_composer_strategy.h"
#include "anbox/wm/manager.h"
#include "anbox/utils.h"
#include "anbox/logger.h"
namespace anbox {
namespace graphics {
......@@ -25,10 +26,27 @@ MultiWindowComposerStrategy::MultiWindowComposerStrategy(const std::shared_ptr<w
std::map<std::shared_ptr<wm::Window>, RenderableList> MultiWindowComposerStrategy::process_layers(const RenderableList &renderables) {
WindowRenderableList win_layers;
bool bGetToast = false; // if don't have toast frame, tell wm to hide toast_window
for (const auto &renderable : renderables) {
// Ignore all surfaces which are not meant for a task
if (!utils::string_starts_with(renderable.name(), "org.anbox.surface."))
if (renderable.name() == "Toast") {
if (bGetToast) {
WARNING("Toast! toast choosed");
continue;
}
auto w = wm_->update_toast_window(renderable.screen_position());
if (w) {
win_layers.insert({w, {renderable}});
} else {
ERROR("Toast! get toast window error");
continue;
}
bGetToast = true;
continue;
}
if (!utils::string_starts_with(renderable.name(), "org.anbox.surface.")) {
continue;
}
wm::Task::Id task_id = 0;
if (sscanf(renderable.name().c_str(), "org.anbox.surface.%d", &task_id) != 1 || !task_id)
......@@ -36,7 +54,6 @@ std::map<std::shared_ptr<wm::Window>, RenderableList> MultiWindowComposerStrateg
auto w = wm_->find_window_for_task(task_id);
if (!w) continue;
if (win_layers.find(w) == win_layers.end()) {
win_layers.insert({w, {renderable}});
continue;
......@@ -44,6 +61,9 @@ std::map<std::shared_ptr<wm::Window>, RenderableList> MultiWindowComposerStrateg
win_layers[w].push_back(renderable);
}
if (!bGetToast) { // hide toast window
wm_->update_toast_window(Rect(0, 0, 0, 0));
}
for (auto &w : win_layers) {
const auto &renderables = w.second;
......
......@@ -72,6 +72,7 @@ class BasePlatform {
virtual void set_renderer(const std::shared_ptr<Renderer> &renderer) = 0;
virtual void set_window_manager(const std::shared_ptr<wm::Manager> &window_manager) = 0;
virtual void create_toast_window() = 0;
virtual bool restore_app(const std::string &package_name) = 0;
virtual bool supports_multi_window() const = 0;
......
......@@ -87,5 +87,10 @@ std::string NullPlatform::ime_socket_file() const {
ERROR("Not implemented");
return "";
}
void NullPlatform::create_toast_window() {
ERROR("Not implemented");
}
} // namespace wm
} // namespace anbox
......@@ -36,6 +36,7 @@ class NullPlatform : public BasePlatform {
std::shared_ptr<audio::Source> create_audio_source() override;
void set_renderer(const std::shared_ptr<Renderer> &renderer) override;
void set_window_manager(const std::shared_ptr<wm::Manager> &window_manager) override;
void create_toast_window() override;
bool supports_multi_window() const override;
int get_user_window_event() const override;
std::string ime_socket_file() const override;
......
......@@ -26,6 +26,7 @@
#include "anbox/platform/sdl/audio_sink.h"
#include "anbox/platform/alsa/audio_source.h"
#include "anbox/system_configuration.h"
#include "anbox/platform/sdl/toast_window.h"
#include "anbox/wm/manager.h"
......@@ -155,6 +156,20 @@ void Platform::set_renderer(const std::shared_ptr<Renderer> &renderer) {
renderer_ = renderer;
}
void Platform::create_toast_window() {
/* This is used to create window to show toast message in android.
* In normal time, it is hided. When a toast frame comes in, show toast window.
* Run create_toast_window after set_renderer and set_window_manager, if not toast_window
* will have no use.
*/
auto w = std::make_shared<ToastWindow>(renderer_, anbox::graphics::Rect(0, 0, 0, 0));
if (window_manager_) {
window_manager_->set_toast_window(w);
} else {
WARNING("toast window set failed!!!");
}
}
void Platform::set_window_manager(const std::shared_ptr<wm::Manager> &window_manager) {
window_manager_ = window_manager;
}
......
......@@ -63,6 +63,7 @@ class Platform : public std::enable_shared_from_this<Platform>,
void set_renderer(const std::shared_ptr<Renderer> &renderer) override;
void set_window_manager(const std::shared_ptr<wm::Manager> &window_manager) override;
void create_toast_window() override;
void set_clipboard_data(const ClipboardData &data) override;
ClipboardData get_clipboard_data() override;
......
#include "anbox/platform/sdl/toast_window.h"
#include "anbox/logger.h"
namespace anbox {
namespace platform {
namespace sdl {
ToastWindow::ToastWindow(const std::shared_ptr<Renderer> &renderer, const graphics::Rect &frame)
: wm::Window(renderer, 0, frame, "toast") {
window_ = SDL_CreateWindow("toast", frame.left(), frame.top(), frame.width(), frame.height(),
SDL_WINDOW_BORDERLESS | SDL_WINDOW_TOOLTIP);
if (!window_) {
const auto message = utils::string_format("Failed to create window: %s", SDL_GetError());
return;
}
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWindowWMInfo(window_, &info);
switch (info.subsystem) {
#if defined(X11_SUPPORT)
case SDL_SYSWM_X11:
native_display_ = static_cast<EGLNativeDisplayType>(info.info.x11.display);
set_native_handle(static_cast<EGLNativeWindowType>(info.info.x11.window));
break;
#endif
#if defined(WAYLAND_SUPPORT)
case SDL_SYSWM_WAYLAND:
native_display_ = reinterpret_cast<EGLNativeDisplayType>(info.info.wl.display);
set_native_handle(reinterpret_cast<EGLNativeWindowType>(info.info.wl.surface));
break;
#endif
#if defined(MIR_SUPPORT)
case SDL_SYSWM_MIR: {
native_display_ = static_cast<EGLNativeDisplayType>(mir_connection_get_egl_native_display(info.info.mir.connection));
auto buffer_stream = mir_surface_get_buffer_stream(info.info.mir.surface);
set_native_handle(reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(buffer_stream)));
break;
}
#endif
default:
ERROR("Unknown subsystem (%d)", info.subsystem);
}
SDL_HideWindow(window_);
attach();
}
ToastWindow::~ToastWindow() {
release();
}
void ToastWindow::update_state(const wm::WindowState::List &states) {
auto state = states[0];
if (state.stack() == wm::Stack::Id::Default) {
SDL_HideWindow(window_);
return;
}
if (frame() != state.frame()) {
SDL_SetWindowSize(window_, state.frame().width(), state.frame().height());
SDL_SetWindowPosition(window_, state.frame().left(), state.frame().top());
update_frame(state.frame());
}
SDL_ShowWindow(window_);
}
} // namespace sdl
} // namespace platform
} // namespace anbox
#ifndef ANBOX_PLATFORM_SDL_TOAST_WINDOW_H_
#define ANBOX_PLATFORM_SDL_TOAST_WINDOW_H_
#include "anbox/wm/window.h"
#include "anbox/platform/sdl/sdl_wrapper.h"
class Renderer;
namespace anbox {
namespace platform {
namespace sdl {
class ToastWindow : public std::enable_shared_from_this<ToastWindow>, public wm::Window {
public:
ToastWindow(const std::shared_ptr<Renderer> &renderer,
const graphics::Rect &frame);
~ToastWindow();
void update_state(const wm::WindowState::List &states) override;
private:
SDL_Window *window_;
EGLNativeDisplayType native_display_;
};
} // namespace sdl
} // namespace platform
} // namespace anbox
#endif
......@@ -157,6 +157,9 @@ Window::~Window() {
}
bool Window::title_event_filter(int x, int y) {
if (fullscreen_) {
return false;
}
std::vector<graphics::Rect> dis_area;
{
std::lock_guard<std::mutex> l(mutex_);
......@@ -174,6 +177,10 @@ bool Window::title_event_filter(int x, int y) {
SDL_HitTestResult Window::on_window_hit(SDL_Window *window, const SDL_Point *pt, void *data) {
auto platform_window = reinterpret_cast<Window*>(data);
if (platform_window->get_fullscreen()) {
return SDL_HITTEST_NORMAL;
}
int w = 0, h = 0;
SDL_GetWindowSize(window, &w, &h);
......@@ -344,6 +351,19 @@ void Window::setResizing(bool resizing) {
}
void Window::update_state(const wm::WindowState::List &states) {
for (auto ws : states)
{
if (!fullscreen_ && ws.videofullscreen()) {
SDL_SetWindowFullscreen(window_, SDL_WINDOW_FULLSCREEN_DESKTOP);
fullscreen_ = true;
} else if (fullscreen_ && !ws.videofullscreen()) {
SDL_SetWindowFullscreen(window_, 0);
fullscreen_ = false;
}
if (fullscreen_) {
return;
}
}
if (!initialized.load() && !states.empty()) {
int w = 0;
int h = 0;
......
......@@ -83,6 +83,7 @@ class Window : public std::enable_shared_from_this<Window>, public wm::Window {
void setResizing(bool resizing) override;
void restore_window();
bool get_fullscreen() { return fullscreen_; }
Id id() const;
std::uint32_t window_id() const;
Uint32 GetWindowFlags(){return SDL_GetWindowFlags(window_);}
......@@ -111,6 +112,7 @@ class Window : public std::enable_shared_from_this<Window>, public wm::Window {
std::uint32_t visible_property;
std::vector<graphics::Rect> dis_area_;
std::mutex mutex_;
bool fullscreen_ = false;
};
} // namespace sdl
} // namespace platform
......
......@@ -78,6 +78,7 @@ message WindowStateUpdateEvent {
required int32 frame_bottom = 7;
required int32 task_id = 8;
required int32 stack_id = 9;
required bool videoFullscreen = 10;
}
repeated WindowState windows = 1;
repeated WindowState removed_windows = 2;
......
......@@ -41,10 +41,12 @@ class Manager {
virtual void remove_task(const Task::Id &task) = 0;
virtual void insert_task(const Task::Id &task, std::shared_ptr<wm::Window> pt) = 0;
virtual void erase_task(const Task::Id &task) = 0;
virtual std::shared_ptr<Window> update_toast_window(const anbox::graphics::Rect &rect) = 0;
virtual std::string get_title(const std::string &package_name) = 0;
// FIXME only applies for the multi-window case
virtual std::shared_ptr<Window> find_window_for_task(const Task::Id &task) = 0;
virtual void set_toast_window(std::shared_ptr<wm::Window> tw) = 0;
};
} // namespace wm
} // namespace anbox
......
......@@ -44,7 +44,7 @@ void MultiWindowManager::apply_window_state_update(const WindowState::List &upda
for (const auto &window : updated) {
// Ignore all windows which are not part of the freeform task stack
if (window.stack() != Stack::Id::Freeform) continue;
if (window.stack() != Stack::Id::Freeform && window.stack() != Stack::Id::Fullscreen) continue;
// And also those which don't have a surface mapped at the moment
if (!window.has_surface()) continue;
......@@ -150,5 +150,29 @@ std::string MultiWindowManager::get_title(const std::string &package_name) {
return package_name;
}
}
std::shared_ptr<Window> MultiWindowManager::update_toast_window(const anbox::graphics::Rect &rect) {
auto stack = wm::Stack::Id::Freeform;
if (rect == graphics::Rect(0, 0, 0, 0)) {
stack = wm::Stack::Id::Default;
}
auto update_window = wm::WindowState{
wm::Display::Id{0},
true,
rect,
"",
wm::Task::Id{0},
stack,
};
if (toast_window_) {
toast_window_->update_state({update_window});
}
return toast_window_;
}
void MultiWindowManager::set_toast_window(std::shared_ptr<Window> tw) {
toast_window_ = tw;
}
} // namespace wm
} // namespace anbox
......@@ -53,6 +53,8 @@ class MultiWindowManager : public Manager {
void remove_task(const Task::Id &task) override;
void insert_task(const Task::Id &task, std::shared_ptr<wm::Window> pt) override;
void erase_task(const Task::Id &task) override;
std::shared_ptr<Window> update_toast_window(const anbox::graphics::Rect &rect) override;
void set_toast_window(std::shared_ptr<Window> tw) override;
std::string get_title(const std::string &package_name) override;
private:
......@@ -61,6 +63,7 @@ class MultiWindowManager : public Manager {
std::shared_ptr<bridge::AndroidApiStub> android_api_stub_;
std::shared_ptr<application::Database> app_db_;
std::map<Task::Id, std::shared_ptr<Window>> windows_;
std::shared_ptr<Window> toast_window_;
};
} // namespace wm
} // namespace anbox
......
......@@ -89,5 +89,15 @@ std::string SingleWindowManager::get_title(const std::string &package_name) {
(void)package_name;
return "";
}
std::shared_ptr<Window> SingleWindowManager::update_toast_window(const anbox::graphics::Rect &rect) {
(void)rect;
return nullptr;
}
void SingleWindowManager::set_toast_window(std::shared_ptr<Window> tw) {
(void)tw;
}
} // namespace wm
} // namespace anbox
......@@ -53,6 +53,8 @@ class SingleWindowManager : public Manager {
void insert_task(const Task::Id &task, std::shared_ptr<wm::Window> pt) override;
void erase_task(const Task::Id &task) override;
std::string get_title(const std::string &package_name) override;
std::shared_ptr<Window> update_toast_window(const anbox::graphics::Rect &rect) override;
void set_toast_window(std::shared_ptr<Window> tw) override;
private:
std::weak_ptr<platform::BasePlatform> platform_;
......
......@@ -30,13 +30,15 @@ WindowState::WindowState()
WindowState::WindowState(const Display::Id &display, bool has_surface,
const graphics::Rect &frame,
const std::string &package_name, const Task::Id &task,
const Stack::Id &stack)
const Stack::Id &stack,
const bool videofullscreen)
: display_(display),
has_surface_(has_surface),
frame_(frame),
package_name_(package_name),
task_(task),
stack_(stack) {}
stack_(stack),
videofullscreen_(videofullscreen) {}
WindowState::~WindowState() {}
} // namespace wm
......
......@@ -35,11 +35,12 @@ class WindowState {
WindowState();
WindowState(const Display::Id &display, bool has_surface,
const graphics::Rect &frame, const std::string &package_name,
const Task::Id &task, const Stack::Id &stack);
const Task::Id &task, const Stack::Id &stack, const bool videofullscreen = false);
~WindowState();
Display::Id display() const { return display_; }
bool has_surface() const { return has_surface_; }
bool videofullscreen() const { return videofullscreen_; }
graphics::Rect frame() const { return frame_; }
std::string package_name() const { return package_name_; }
Task::Id task() const { return task_; }
......@@ -52,6 +53,7 @@ class WindowState {
std::string package_name_;
Task::Id task_;
Stack::Id stack_;
bool videofullscreen_;
};
} // namespace wm
} // namespace anbox
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册