diff --git a/wayland_adapter/framework/core/wayland_surface.cpp b/wayland_adapter/framework/core/wayland_surface.cpp index dbd5d557863ce5689010d1407d555b56c60649bc..a2379658f2aa92f47fc0942f0cfecd4e77160d6a 100644 --- a/wayland_adapter/framework/core/wayland_surface.cpp +++ b/wayland_adapter/framework/core/wayland_surface.cpp @@ -197,6 +197,31 @@ OHOS::sptr WaylandSurface::Create(struct wl_client *client, return surface; } +class WaylandWindowListener : public OHOS::Rosen::IWindowChangeListener { +public: + WaylandWindowListener(OHOS::sptr wlSurface) : wlSurface_(wlSurface) {} + ~WaylandWindowListener() = default; + void OnSizeChange(OHOS::Rosen::Rect rect, OHOS::Rosen::WindowSizeChangeReason reason) override; + void OnModeChange(OHOS::Rosen::WindowMode mode) override; + +private: + OHOS::sptr wlSurface_ = nullptr; +}; + +void WaylandWindowListener::OnSizeChange(OHOS::Rosen::Rect rect, OHOS::Rosen::WindowSizeChangeReason reason) +{ + if (wlSurface_ != nullptr) { + wlSurface_->OnSizeChange(rect, reason); + } +} + +void WaylandWindowListener::OnModeChange(OHOS::Rosen::WindowMode mode) +{ + if (wlSurface_ != nullptr) { + wlSurface_->OnModeChange(mode); + } +} + WaylandSurface::WaylandSurface(struct wl_client *client, struct wl_resource *parent, uint32_t version, uint32_t id) : WaylandResourceObject(client, &wl_surface_interface, version, id, &IWaylandSurface::impl_), parent_(parent) {} @@ -361,6 +386,9 @@ void WaylandSurface::CreateWindow() window_->SetInputEventConsumer(listener); window_->Show(); + OHOS::sptr waylandWindowListener = new WaylandWindowListener(this); + window_->RegisterWindowChangeListener(waylandWindowListener); + surfaceNode_ = window_->GetSurfaceNode(); if (surfaceNode_ == nullptr) { LOG_ERROR("GetSurfaceNode failed"); @@ -435,5 +463,22 @@ void WaylandSurface::CopyBuffer(struct wl_shm_buffer *shm) canvas->drawBitmap(srcBitmap, 0, 0); rsSurface_->FlushFrame(framePtr); } + +void WaylandSurface::OnSizeChange(const OHOS::Rosen::Rect& rect, OHOS::Rosen::WindowSizeChangeReason reason) +{ + rect_.x = rect.posX_; + rect_.y = rect.posY_; + rect_.width = rect.width_; + rect_.height = rect.height_; + for (auto &cb : rectCallbacks_) { + cb(rect_); + } +} + +void WaylandSurface::OnModeChange(OHOS::Rosen::WindowMode mode) +{ + LOG_DEBUG("OnModeChange, window mode is %{public}d, ignore", mode); +} + } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/framework/core/wayland_surface.h b/wayland_adapter/framework/core/wayland_surface.h index e7854b4ffe77d2d40494575efedbfc0c3aa2b9dd..13479f47a555108ec9eaad7d91bde80c0ad7d024 100644 --- a/wayland_adapter/framework/core/wayland_surface.h +++ b/wayland_adapter/framework/core/wayland_surface.h @@ -56,6 +56,8 @@ public: void AddCommitCallback(SurfaceCommitCallback callback); void AddRectCallback(SurfaceRectCallback callback); void StartMove(); + void OnSizeChange(const OHOS::Rosen::Rect& rect, OHOS::Rosen::WindowSizeChangeReason reason); + void OnModeChange(OHOS::Rosen::WindowMode mode); private: WaylandSurface(struct wl_client *client, struct wl_resource *parent, uint32_t version, uint32_t id); diff --git a/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp b/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp index 32832bec1b706deff2cdcf00304d515336145466..feba5bacd53d2ced144278db0a887a6af9291d7c 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp +++ b/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp @@ -194,5 +194,18 @@ void WaylandXdgToplevel::HandleCommit() { SendConfigure(); } + +void WaylandXdgToplevel::SetRect(Rect rect) +{ + rect_ = rect; + + struct wl_array states; + uint32_t *s; + wl_array_init(&states); + s = static_cast(wl_array_add(&states, sizeof(uint32_t))); + *s = XDG_TOPLEVEL_STATE_RESIZING; + xdg_toplevel_send_configure(WlResource(), rect.width, rect.height, &states); + wl_array_release(&states); +} } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/framework/stable/wayland_xdg_toplevel.h b/wayland_adapter/framework/stable/wayland_xdg_toplevel.h index fa0f41766c0642b9097b37ce209fe62c8ad3d1ce..23fbb3752063a5139b2c1c7641cb6e48b1d97a51 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_toplevel.h +++ b/wayland_adapter/framework/stable/wayland_xdg_toplevel.h @@ -58,10 +58,7 @@ public: void Resize(uint32_t serial, uint32_t edges); void SendConfigure(); void HandleCommit(); - void SetRect(Rect rect) - { - rect_ = rect; - } + void SetRect(Rect rect); private: WaylandXdgToplevel(const OHOS::sptr &xdgSurface, uint32_t id); diff --git a/wayland_adapter/test/wayland_demo.cpp b/wayland_adapter/test/wayland_demo.cpp index 97dc652228775d74cc09f72c9f7fd79f56b998e9..52ce57f71e0b073b586db6e00acbc5c3122438c9 100644 --- a/wayland_adapter/test/wayland_demo.cpp +++ b/wayland_adapter/test/wayland_demo.cpp @@ -66,6 +66,7 @@ struct buffer { struct wl_buffer *buffer; void *shm_data; bool busy; + int32_t width, height; }; struct window { @@ -180,6 +181,8 @@ static int32_t CreateShmBuffer(struct display *display, struct buffer *buffer, i struct wl_shm_pool *pool = wl_shm_create_pool(display->shm, fd, size); buffer->buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, format); + buffer->width = width; + buffer->height = height; wl_buffer_add_listener(buffer->buffer, &g_bufferListener, buffer); wl_shm_pool_destroy(pool); close(fd); @@ -202,7 +205,15 @@ static void HandleXdgSurfaceConfigure(void *data, struct xdg_surface *surface, u struct xdg_surface_listener g_xdgSurfaceListener = {HandleXdgSurfaceConfigure}; static void HandleXdgToplevelConfigure(void *data, struct xdg_toplevel *xdg_toplevel, - int32_t width, int32_t height, struct wl_array *state) {} + int32_t width, int32_t height, struct wl_array *state) { + + struct window *window = static_cast(data); + if (window->width != width || window->height != height) { + fprintf(stderr, "HandleXdgToplevelConfigure, width:%d, height:%d\n", width, height); + window->width = width; + window->height = height; + } +} static void HandleXdgToplevelClose(void *data, struct xdg_toplevel *xdg_toplevel) { g_running = false; @@ -288,6 +299,11 @@ static struct buffer *WindowNextBuffer(struct window *window) return nullptr; } + if (buffer->buffer && (buffer->width != window->width || buffer->height != window->height)) { + wl_buffer_destroy(buffer->buffer); + buffer->buffer = nullptr; + } + if (!buffer->buffer) { int32_t ret = CreateShmBuffer(window->display, buffer, window->width, window->height, WL_SHM_FORMAT_RGBA8888); if (ret < 0) {