Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2022-11-12 17:57:25 +0300
committerAntonio Vazquez <blendergit@gmail.com>2022-11-12 17:57:25 +0300
commit53989894ca27907ce3be56ecd03ab8fa9bd42f7c (patch)
tree11920bfb916ea5088a30548bc6af4b6f00b57efa /intern/ghost/intern/GHOST_WindowWayland.cpp
parent7c576792c93192d652805e6f5352bff53f161e74 (diff)
parent99fe17f52d78cfd228cc3e839374f54b68e49eea (diff)
Merge branch 'master' into asset-lite-greasepencil
Diffstat (limited to 'intern/ghost/intern/GHOST_WindowWayland.cpp')
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.cpp293
1 files changed, 175 insertions, 118 deletions
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index ad94a02b514..ef53f6a02e6 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -77,8 +77,13 @@ static void gwl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor)
delete decor;
}
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_Window
+ * \{ */
+
struct GWL_Window {
GHOST_WindowWayland *ghost_window = nullptr;
+ GHOST_SystemWayland *ghost_system = nullptr;
struct wl_surface *wl_surface = nullptr;
/**
* Outputs on which the window is currently shown on.
@@ -102,6 +107,8 @@ struct GWL_Window {
WGL_XDG_Decor_Window *xdg_decor = nullptr;
wl_egl_window *egl_window = nullptr;
+
+ std::string title;
bool is_maximised = false;
bool is_fullscreen = false;
bool is_active = false;
@@ -111,6 +118,115 @@ struct GWL_Window {
int32_t size_pending[2] = {0, 0};
};
+static void gwl_window_title_set(GWL_Window *win, const char *title)
+{
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ WGL_LibDecor_Window &decor = *win->libdecor;
+ libdecor_frame_set_title(decor.frame, title);
+ }
+ else
+#endif
+ {
+ WGL_XDG_Decor_Window &decor = *win->xdg_decor;
+ xdg_toplevel_set_title(decor.toplevel, title);
+ }
+
+ win->title = title;
+}
+
+static GHOST_TWindowState gwl_window_state_get(const GWL_Window *win)
+{
+ if (win->is_fullscreen) {
+ return GHOST_kWindowStateFullScreen;
+ }
+ if (win->is_maximised) {
+ return GHOST_kWindowStateMaximized;
+ }
+ return GHOST_kWindowStateNormal;
+}
+
+static bool gwl_window_state_set(GWL_Window *win, const GHOST_TWindowState state)
+{
+ const GHOST_TWindowState state_current = gwl_window_state_get(win);
+ switch (state) {
+ case GHOST_kWindowStateNormal:
+ /* Unset states. */
+ switch (state_current) {
+ case GHOST_kWindowStateMaximized: {
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ libdecor_frame_unset_maximized(win->libdecor->frame);
+ }
+ else
+#endif
+ {
+ xdg_toplevel_unset_maximized(win->xdg_decor->toplevel);
+ }
+ break;
+ }
+ case GHOST_kWindowStateFullScreen: {
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ libdecor_frame_unset_fullscreen(win->libdecor->frame);
+ }
+ else
+#endif
+ {
+ xdg_toplevel_unset_fullscreen(win->xdg_decor->toplevel);
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ case GHOST_kWindowStateMaximized: {
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ libdecor_frame_set_maximized(win->libdecor->frame);
+ }
+ else
+#endif
+ {
+ xdg_toplevel_set_maximized(win->xdg_decor->toplevel);
+ }
+ break;
+ }
+ case GHOST_kWindowStateMinimized: {
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ libdecor_frame_set_minimized(win->libdecor->frame);
+ }
+ else
+#endif
+ {
+ xdg_toplevel_set_minimized(win->xdg_decor->toplevel);
+ }
+ break;
+ }
+ case GHOST_kWindowStateFullScreen: {
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ libdecor_frame_set_fullscreen(win->libdecor->frame, nullptr);
+ }
+ else
+#endif
+ {
+ xdg_toplevel_set_fullscreen(win->xdg_decor->toplevel, nullptr);
+ }
+ break;
+ }
+ case GHOST_kWindowStateEmbedded: {
+ return GHOST_kFailure;
+ }
+ }
+ return GHOST_kSuccess;
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
* \{ */
@@ -219,7 +335,7 @@ static void xdg_toplevel_handle_close(void *data, xdg_toplevel * /*xdg_toplevel*
static_cast<GWL_Window *>(data)->ghost_window->close();
}
-static const xdg_toplevel_listener toplevel_listener = {
+static const xdg_toplevel_listener xdg_toplevel_listener = {
xdg_toplevel_handle_configure,
xdg_toplevel_handle_close,
};
@@ -248,6 +364,7 @@ static void frame_handle_configure(struct libdecor_frame *frame,
int size_next[2];
enum libdecor_window_state window_state;
struct libdecor_state *state;
+ bool do_redraw = false;
if (!libdecor_configuration_get_content_size(
configuration, frame, &size_next[0], &size_next[1])) {
@@ -255,11 +372,16 @@ static void frame_handle_configure(struct libdecor_frame *frame,
size_next[1] = win->size[1] / win->scale;
}
+ const int size_prev[2] = {UNPACK2(win->size)};
win->size[0] = win->scale * size_next[0];
win->size[1] = win->scale * size_next[1];
- wl_egl_window_resize(win->egl_window, UNPACK2(win->size), 0, 0);
- win->ghost_window->notify_size();
+ const bool do_resize = (size_prev[0] != win->size[0]) || (size_prev[1] != win->size[1]);
+
+ if (do_resize) {
+ wl_egl_window_resize(win->egl_window, UNPACK2(win->size), 0, 0);
+ win->ghost_window->notify_size();
+ }
if (!libdecor_configuration_get_window_state(configuration, &window_state)) {
window_state = LIBDECOR_WINDOW_STATE_NONE;
@@ -267,14 +389,34 @@ static void frame_handle_configure(struct libdecor_frame *frame,
win->is_maximised = window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED;
win->is_fullscreen = window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN;
+
+ GHOST_SystemWayland *system = win->ghost_system;
+ const bool is_active_prev_ghost = (win->ghost_window ==
+ system->getWindowManager()->getActiveWindow());
win->is_active = window_state & LIBDECOR_WINDOW_STATE_ACTIVE;
+ if (is_active_prev_ghost != win->is_active) {
+ if (win->is_active) {
+ win->ghost_window->activate();
+ }
+ else {
+ win->ghost_window->deactivate();
+ }
+ }
- win->is_active ? win->ghost_window->activate() : win->ghost_window->deactivate();
+ const bool is_active_prev_decor = win->is_active;
+ if (is_active_prev_decor) {
+ /* Without this, activating another window doesn't refresh the title-bar as inactive. */
+ do_redraw = true;
+ }
state = libdecor_state_new(UNPACK2(size_next));
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
+ if (do_redraw) {
+ win->ghost_window->swapBuffers();
+ }
+
win->libdecor->configured = true;
}
@@ -322,7 +464,7 @@ static void xdg_toplevel_decoration_handle_configure(
static_cast<GWL_Window *>(data)->xdg_decor->mode = (zxdg_toplevel_decoration_v1_mode)mode;
}
-static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listener = {
+static const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener = {
xdg_toplevel_decoration_handle_configure,
};
@@ -359,11 +501,16 @@ static void xdg_surface_handle_configure(void *data,
win->ghost_window->notify_size();
}
- if (win->is_active) {
- win->ghost_window->activate();
- }
- else {
- win->ghost_window->deactivate();
+ GHOST_SystemWayland *system = win->ghost_system;
+ const bool is_active_prev_ghost = (win->ghost_window ==
+ system->getWindowManager()->getActiveWindow());
+ if (is_active_prev_ghost != win->is_active) {
+ if (win->is_active) {
+ win->ghost_window->activate();
+ }
+ else {
+ win->ghost_window->deactivate();
+ }
}
xdg_surface_ack_configure(xdg_surface, serial);
@@ -418,7 +565,7 @@ static void surface_handle_leave(void *data,
}
}
-static struct wl_surface_listener wl_surface_listener = {
+static const struct wl_surface_listener wl_surface_listener = {
surface_handle_enter,
surface_handle_leave,
};
@@ -435,7 +582,7 @@ static struct wl_surface_listener wl_surface_listener = {
GHOST_TSuccess GHOST_WindowWayland::hasCursorShape(GHOST_TStandardCursor cursorShape)
{
- return system_->hasCursorShape(cursorShape);
+ return system_->cursor_shape_check(cursorShape);
}
GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
@@ -460,6 +607,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
}
window_->ghost_window = this;
+ window_->ghost_system = system;
window_->size[0] = int32_t(width);
window_->size[1] = int32_t(height);
@@ -483,7 +631,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
wl_surface_set_buffer_scale(window_->wl_surface, window_->scale);
- wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, this);
+ wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_);
window_->egl_window = wl_egl_window_create(
window_->wl_surface, int(window_->size[0]), int(window_->size[1]));
@@ -537,13 +685,13 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
decor.toplevel_decor = zxdg_decoration_manager_v1_get_toplevel_decoration(
system_->xdg_decor_manager(), decor.toplevel);
zxdg_toplevel_decoration_v1_add_listener(
- decor.toplevel_decor, &toplevel_decoration_v1_listener, window_);
+ decor.toplevel_decor, &xdg_toplevel_decoration_v1_listener, window_);
zxdg_toplevel_decoration_v1_set_mode(decor.toplevel_decor,
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
}
xdg_surface_add_listener(decor.surface, &xdg_surface_listener, window_);
- xdg_toplevel_add_listener(decor.toplevel, &toplevel_listener, window_);
+ xdg_toplevel_add_listener(decor.toplevel, &xdg_toplevel_listener, window_);
if (parentWindow && is_dialog) {
WGL_XDG_Decor_Window &decor_parent =
@@ -552,7 +700,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
}
}
- setTitle(title);
+ gwl_window_title_set(window_, title);
wl_surface_set_user_data(window_->wl_surface, this);
@@ -582,7 +730,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
if (use_libdecor == false)
#endif
{
- setState(state);
+ gwl_window_state_set(window_, state);
}
/* EGL context. */
@@ -618,47 +766,35 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mo
GHOST_TSuccess GHOST_WindowWayland::setWindowCursorShape(GHOST_TStandardCursor shape)
{
- const GHOST_TSuccess ok = system_->setCursorShape(shape);
+ const GHOST_TSuccess ok = system_->cursor_shape_set(shape);
m_cursorShape = (ok == GHOST_kSuccess) ? shape : GHOST_kStandardCursorDefault;
return ok;
}
bool GHOST_WindowWayland::getCursorGrabUseSoftwareDisplay()
{
- return system_->getCursorGrabUseSoftwareDisplay(m_cursorGrab);
+ return system_->cursor_grab_use_software_display_get(m_cursorGrab);
}
GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape(
uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor)
{
- return system_->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
+ return system_->cursor_shape_custom_set(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
}
GHOST_TSuccess GHOST_WindowWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap)
{
- return system_->getCursorBitmap(bitmap);
+ return system_->cursor_bitmap_get(bitmap);
}
void GHOST_WindowWayland::setTitle(const char *title)
{
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (use_libdecor) {
- WGL_LibDecor_Window &decor = *window_->libdecor;
- libdecor_frame_set_title(decor.frame, title);
- }
- else
-#endif
- {
- WGL_XDG_Decor_Window &decor = *window_->xdg_decor;
- xdg_toplevel_set_title(decor.toplevel, title);
- }
-
- title_ = title;
+ gwl_window_title_set(window_, title);
}
std::string GHOST_WindowWayland::getTitle() const
{
- return title_.empty() ? "untitled" : title_;
+ return window_->title.empty() ? "untitled" : window_->title;
}
void GHOST_WindowWayland::getWindowBounds(GHOST_Rect &bounds) const
@@ -754,96 +890,17 @@ uint16_t GHOST_WindowWayland::getDPIHint()
GHOST_TSuccess GHOST_WindowWayland::setWindowCursorVisibility(bool visible)
{
- return system_->setCursorVisibility(visible);
+ return system_->cursor_visibility_set(visible);
}
GHOST_TSuccess GHOST_WindowWayland::setState(GHOST_TWindowState state)
{
- switch (state) {
- case GHOST_kWindowStateNormal:
- /* Unset states. */
- switch (getState()) {
- case GHOST_kWindowStateMaximized: {
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (use_libdecor) {
- libdecor_frame_unset_maximized(window_->libdecor->frame);
- }
- else
-#endif
- {
- xdg_toplevel_unset_maximized(window_->xdg_decor->toplevel);
- }
- break;
- }
- case GHOST_kWindowStateFullScreen: {
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (use_libdecor) {
- libdecor_frame_unset_fullscreen(window_->libdecor->frame);
- }
- else
-#endif
- {
- xdg_toplevel_unset_fullscreen(window_->xdg_decor->toplevel);
- }
- break;
- }
- default: {
- break;
- }
- }
- break;
- case GHOST_kWindowStateMaximized: {
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (use_libdecor) {
- libdecor_frame_set_maximized(window_->libdecor->frame);
- }
- else
-#endif
- {
- xdg_toplevel_set_maximized(window_->xdg_decor->toplevel);
- }
- break;
- }
- case GHOST_kWindowStateMinimized: {
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (use_libdecor) {
- libdecor_frame_set_minimized(window_->libdecor->frame);
- }
- else
-#endif
- {
- xdg_toplevel_set_minimized(window_->xdg_decor->toplevel);
- }
- break;
- }
- case GHOST_kWindowStateFullScreen: {
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (use_libdecor) {
- libdecor_frame_set_fullscreen(window_->libdecor->frame, nullptr);
- }
- else
-#endif
- {
- xdg_toplevel_set_fullscreen(window_->xdg_decor->toplevel, nullptr);
- }
- break;
- }
- case GHOST_kWindowStateEmbedded: {
- return GHOST_kFailure;
- }
- }
- return GHOST_kSuccess;
+ return gwl_window_state_set(window_, state) ? GHOST_kSuccess : GHOST_kFailure;
}
GHOST_TWindowState GHOST_WindowWayland::getState() const
{
- if (window_->is_fullscreen) {
- return GHOST_kWindowStateFullScreen;
- }
- if (window_->is_maximised) {
- return GHOST_kWindowStateMaximized;
- }
- return GHOST_kWindowStateNormal;
+ return gwl_window_state_get(window_);
}
GHOST_TSuccess GHOST_WindowWayland::invalidate()
@@ -1070,7 +1127,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
/* As this is a low-level function, we might want adding this event to be optional,
* always add the event unless it causes issues. */
- GHOST_System *system = (GHOST_System *)GHOST_ISystem::getSystem();
+ GHOST_SystemWayland *system = window_->ghost_system;
system->pushEvent(
new GHOST_Event(system->getMilliSeconds(), GHOST_kEventWindowDPIHintChanged, this));
}