diff --git a/src/anbox/graphics/multi_window_composer_strategy.cpp b/src/anbox/graphics/multi_window_composer_strategy.cpp index c660bd71e51f0c136139359746ba1ad8a9519e8c..7d2cbb6fc4c67e06577e3a8392253891a0dbcab8 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 39037270a2a7db996fd9a0a1f01beb2b66b0c8d3..f695a19e8111be0730875a06fd4c5693c9160b23 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 4ac31f8c34ff9b1c38ec74ee19af5082155b9d95..a98ba743f9a6eae0df2f52fd42cabcbac7f111f5 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 3eac96bb3b9e6e50028893510b60bf46325ee200..f4c3d4b34df5aaf4275e5380f90348a344e7a788 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 05af468e495bed0e180864c5b738a44dbd91bcb5..6e03ed6fcaf5d4f4f4abe51ca2abfe7a7540f31a 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 05c6a48cdbd755a8161115a26d94ea3c09323d4b..5d2cd71b92af7be5f0313615ddd5e663056a7234 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 f149bb170a71d315f242b5c2f482408e5c7254ac..cd1587f6166f3df241afd28698116330d499ec82 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};