From cee749685f54a86632e294afc73622c1ca6aa9ae Mon Sep 17 00:00:00 2001 From: wangpeiqiang Date: Sat, 29 Aug 2020 15:28:21 +0800 Subject: [PATCH] window: disable clicks in titlebar, while covered by app's frame. if mouse clicks are in titlebar and titlebar is covered by app's frame, disable titlebar function and send click message to android to do app function. --- .../multi_window_composer_strategy.cpp | 7 ++++ src/anbox/graphics/rect.h | 11 ++++++ src/anbox/platform/sdl/platform.cpp | 2 +- src/anbox/platform/sdl/window.cpp | 34 ++++++++++++++++--- src/anbox/platform/sdl/window.h | 6 +++- src/anbox/wm/window.cpp | 2 +- src/anbox/wm/window.h | 3 +- 7 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/anbox/graphics/multi_window_composer_strategy.cpp b/src/anbox/graphics/multi_window_composer_strategy.cpp index c660bd71..7d2cbb6f 100644 --- a/src/anbox/graphics/multi_window_composer_strategy.cpp +++ b/src/anbox/graphics/multi_window_composer_strategy.cpp @@ -95,6 +95,13 @@ std::map, RenderableList> MultiWindowComposerStrateg w.first->setResizing(false); } } + else { + std::vector rects; + for (auto &r : final_renderables) { + rects.push_back(r.screen_position()); + } + w.first->set_dis_area(rects); + } if(!changed) { w.second = final_renderables; diff --git a/src/anbox/graphics/rect.h b/src/anbox/graphics/rect.h index 39037270..f695a19e 100644 --- a/src/anbox/graphics/rect.h +++ b/src/anbox/graphics/rect.h @@ -59,6 +59,17 @@ class Rect { bottom_ == rhs.bottom()); } + Rect operator&(const Rect &rhs) const { + int left = left_ > rhs.left() ? left_ : rhs.left(); + int right = right_ < rhs.right() ? right_ : rhs.right(); + int top = top_ > rhs.top() ? top_ : rhs.top(); + int bottom = bottom_ < rhs.bottom() ? bottom_ : rhs.bottom(); + if (right <= left || bottom <= top) { + return Rect(0, 0, 0, 0); + } + return Rect(left, top, right, bottom); + } + inline bool operator!=(const Rect &rhs) const { return !operator==(rhs); } void merge(const Rect &rhs); diff --git a/src/anbox/platform/sdl/platform.cpp b/src/anbox/platform/sdl/platform.cpp index 4ac31f8c..a98ba743 100644 --- a/src/anbox/platform/sdl/platform.cpp +++ b/src/anbox/platform/sdl/platform.cpp @@ -319,7 +319,7 @@ void Platform::process_input_event(const SDL_Event &event) { for (auto &iter : windows_) { if (auto w = iter.second.lock()) { if (w->window_id() == event.window.windowID && - w->title_event_filter(event.button.y)) { + w->title_event_filter(event.button.x, event.button.y)) { return; } } diff --git a/src/anbox/platform/sdl/window.cpp b/src/anbox/platform/sdl/window.cpp index 3eac96bb..f4c3d4b3 100755 --- a/src/anbox/platform/sdl/window.cpp +++ b/src/anbox/platform/sdl/window.cpp @@ -156,9 +156,19 @@ Window::~Window() { if (window_) SDL_DestroyWindow(window_); } -bool Window::title_event_filter(int point_y) { - const auto top_drag_area_height = graphics::dp_to_pixel(button_size + (button_margin << 1)); - return point_y < top_drag_area_height; +bool Window::title_event_filter(int x, int y) { + std::vector dis_area; + { + std::lock_guard l(mutex_); + dis_area = dis_area_; + } + int cnt = 0; + for (auto &r : dis_area) { + if (x >= r.left() && x <= r.right() && y >= r.top() && y <= r.bottom()) { + cnt++; + } + } + return cnt == 1; } SDL_HitTestResult Window::on_window_hit(SDL_Window *window, const SDL_Point *pt, void *data) { @@ -175,7 +185,7 @@ SDL_HitTestResult Window::on_window_hit(SDL_Window *window, const SDL_Point *pt, SDL_HitTestResult result = SDL_HITTEST_NORMAL; - if (pt->y <= top_drag_area_height) { + if (platform_window->title_event_filter(pt->x, pt->y)) { if (!platform_window->initialized.load()) { INFO("window initialized by click top"); platform_window->initialized = true; @@ -378,6 +388,22 @@ void Window::restore_window() { SDL_RestoreWindow(window_); } } + +void Window::set_dis_area(const std::vector &rects) { + const auto top_drag_area_height = graphics::dp_to_pixel(button_size + (button_margin << 1)); + auto title = graphics::Rect{0, 0, frame().width(), top_drag_area_height}; + std::vector dis_area; + for (auto r : rects) { + auto tmp = r & title; + if (tmp.width() > 0 && tmp.height() > 0) { + dis_area.push_back(tmp); + } + } + { + std::lock_guard l(mutex_); + dis_area_.swap(dis_area); + } +} } // namespace sdl } // namespace platform } // namespace anbox diff --git a/src/anbox/platform/sdl/window.h b/src/anbox/platform/sdl/window.h index 05af468e..6e03ed6f 100755 --- a/src/anbox/platform/sdl/window.h +++ b/src/anbox/platform/sdl/window.h @@ -28,6 +28,7 @@ #include #include #include +#include class Renderer; @@ -71,7 +72,7 @@ class Window : public std::enable_shared_from_this, public wm::Window { bool resizable); ~Window(); - bool title_event_filter(int y) override; + bool title_event_filter(int x, int y) override; void process_event(const SDL_Event &event); bool check_min_state() {return SDL_GetWindowFlags(window_) & SDL_WINDOW_MINIMIZED;} @@ -88,6 +89,7 @@ class Window : public std::enable_shared_from_this, public wm::Window { inline std::uint32_t get_property() { return visible_property; } + void set_dis_area(const std::vector &rects) override; private: static SDL_HitTestResult on_window_hit(SDL_Window *window, const SDL_Point *pt, void *data); @@ -107,6 +109,8 @@ class Window : public std::enable_shared_from_this, public wm::Window { int last_wnd_x{ 0 }; int last_wnd_y{ 0 }; std::uint32_t visible_property; + std::vector dis_area_; + std::mutex mutex_; }; } // namespace sdl } // namespace platform diff --git a/src/anbox/wm/window.cpp b/src/anbox/wm/window.cpp index 05c6a48c..5d2cd71b 100644 --- a/src/anbox/wm/window.cpp +++ b/src/anbox/wm/window.cpp @@ -64,7 +64,7 @@ void Window::release() { renderer_->destroyNativeWindow(native_handle()); } -bool Window::title_event_filter(int y) { +bool Window::title_event_filter(int x, int y) { return false; } } // namespace wm diff --git a/src/anbox/wm/window.h b/src/anbox/wm/window.h index f149bb17..cd1587f6 100644 --- a/src/anbox/wm/window.h +++ b/src/anbox/wm/window.h @@ -55,7 +55,7 @@ class Window { void update_frame(const graphics::Rect &frame); void update_last_frame(const graphics::Rect &frame); - virtual bool title_event_filter(int y); + virtual bool title_event_filter(int x, int y); void set_native_handle(const EGLNativeWindowType &handle); EGLNativeWindowType native_handle() const; @@ -65,6 +65,7 @@ class Window { std::string title() const; virtual bool checkResizeable() { return resizing_; } virtual void setResizing(bool resizing) { resizing_ = resizing; } + virtual void set_dis_area(const std::vector &rects) {}; protected: graphics::Rect last_frame_; bool resizing_{false}; -- GitLab