Cleanup: group public utility functions for Wayland System/Window

GHOST methods were mixed in with Wayland specific utility functions,
making it difficult to navigate or know where to add new functions.
This commit is contained in:
Campbell Barton 2022-07-01 11:19:01 +10:00
parent cf64a1d73e
commit 3d3ba9ca8e
4 changed files with 317 additions and 248 deletions

View File

@ -1162,7 +1162,7 @@ static void data_device_handle_selection(void *data,
{
std::lock_guard lock{system_selection_mutex};
system->setSelection(data);
system->selection_set(data);
}
};
@ -2424,9 +2424,9 @@ static const struct wl_registry_listener registry_listener = {
/** \} */
/* -------------------------------------------------------------------- */
/** \name Ghost Implementation
/** \name GHOST Implementation
*
* Wayland specific implementation of the GHOST_System interface.
* WAYLAND specific implementation of the #GHOST_System interface.
* \{ */
GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new display_t)
@ -2849,52 +2849,6 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
return window;
}
wl_display *GHOST_SystemWayland::display()
{
return d->display;
}
wl_compositor *GHOST_SystemWayland::compositor()
{
return d->compositor;
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor *GHOST_SystemWayland::decor_context()
{
return d->decor_context;
}
#else /* WITH_GHOST_WAYLAND_LIBDECOR */
xdg_wm_base *GHOST_SystemWayland::xdg_shell()
{
return d->xdg_shell;
}
zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decoration_manager()
{
return d->xdg_decoration_manager;
}
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
const std::vector<output_t *> &GHOST_SystemWayland::outputs() const
{
return d->outputs;
}
wl_shm *GHOST_SystemWayland::shm() const
{
return d->shm;
}
void GHOST_SystemWayland::setSelection(const std::string &selection)
{
this->selection = selection;
}
/**
* Show the buffer defined by #cursor_buffer_set without changing anything else,
* so #cursor_buffer_hide can be used to display it again.
@ -3464,3 +3418,81 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Direct Data Access
*
* Expose some members via methods.
* \{ */
wl_display *GHOST_SystemWayland::display()
{
return d->display;
}
wl_compositor *GHOST_SystemWayland::compositor()
{
return d->compositor;
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor *GHOST_SystemWayland::decor_context()
{
return d->decor_context;
}
#else /* WITH_GHOST_WAYLAND_LIBDECOR */
xdg_wm_base *GHOST_SystemWayland::xdg_shell()
{
return d->xdg_shell;
}
zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decoration_manager()
{
return d->xdg_decoration_manager;
}
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
const std::vector<output_t *> &GHOST_SystemWayland::outputs() const
{
return d->outputs;
}
wl_shm *GHOST_SystemWayland::shm() const
{
return d->shm;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Query Access
* \{ */
output_t *GHOST_SystemWayland::output_find_by_wl(const struct wl_output *output) const
{
for (output_t *reg_output : this->outputs()) {
if (reg_output->wl_output == output) {
return reg_output;
}
}
return nullptr;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Utility Functions
*
* Functionality only used for the WAYLAND implementation.
* \{ */
void GHOST_SystemWayland::selection_set(const std::string &selection)
{
this->selection = selection;
}
/** \} */

View File

@ -109,23 +109,6 @@ class GHOST_SystemWayland : public GHOST_System {
const bool is_dialog,
const GHOST_IWindow *parentWindow) override;
wl_display *display();
wl_compositor *compositor();
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor *decor_context();
#else
xdg_wm_base *xdg_shell();
zxdg_decoration_manager_v1 *xdg_decoration_manager();
#endif
const std::vector<output_t *> &outputs() const;
wl_shm *shm() const;
void setSelection(const std::string &selection);
GHOST_TSuccess setCursorShape(GHOST_TStandardCursor shape);
GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor cursorShape);
@ -151,6 +134,31 @@ class GHOST_SystemWayland : public GHOST_System {
const GHOST_TGrabCursorMode mode_current,
wl_surface *surface);
/* WAYLAND direct-data access. */
wl_display *display();
wl_compositor *compositor();
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor *decor_context();
#else
xdg_wm_base *xdg_shell();
zxdg_decoration_manager_v1 *xdg_decoration_manager();
#endif
const std::vector<output_t *> &outputs() const;
wl_shm *shm() const;
/* WAYLAND query access. */
output_t *output_find_by_wl(const struct wl_output *output) const;
/* WAYLAND utility functions. */
void selection_set(const std::string &selection);
private:
struct display_t *d;
std::string selection;

View File

@ -323,14 +323,9 @@ static void surface_handle_enter(void *data,
struct wl_surface * /*wl_surface*/,
struct wl_output *output)
{
GHOST_WindowWayland *w = static_cast<GHOST_WindowWayland *>(data);
output_t *reg_output = w->output_find_by_wl(output);
if (reg_output == nullptr) {
return;
}
if (w->outputs_enter(reg_output)) {
w->outputs_changed_update_scale();
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(data);
if (win->outputs_enter_wl(output)) {
win->outputs_changed_update_scale();
}
}
@ -339,12 +334,7 @@ static void surface_handle_leave(void *data,
struct wl_output *output)
{
GHOST_WindowWayland *w = static_cast<GHOST_WindowWayland *>(data);
output_t *reg_output = w->output_find_by_wl(output);
if (reg_output == nullptr) {
return;
}
if (w->outputs_leave(reg_output)) {
if (w->outputs_leave_wl(output)) {
w->outputs_changed_update_scale();
}
}
@ -357,9 +347,9 @@ struct wl_surface_listener wl_surface_listener = {
/** \} */
/* -------------------------------------------------------------------- */
/** \name Ghost Implementation
/** \name GHOST Implementation
*
* Wayland specific implementation of the GHOST_Window interface.
* WAYLAND specific implementation of the #GHOST_Window interface.
* \{ */
GHOST_TSuccess GHOST_WindowWayland::hasCursorShape(GHOST_TStandardCursor cursorShape)
@ -492,157 +482,6 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
setSwapInterval(0);
}
GHOST_TSuccess GHOST_WindowWayland::close()
{
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowClose, this));
}
GHOST_TSuccess GHOST_WindowWayland::activate()
{
if (m_system->getWindowManager()->setActiveWindow(this) == GHOST_kFailure) {
return GHOST_kFailure;
}
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowActivate, this));
}
GHOST_TSuccess GHOST_WindowWayland::deactivate()
{
m_system->getWindowManager()->setWindowInactive(this);
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowDeactivate, this));
}
GHOST_TSuccess GHOST_WindowWayland::notify_size()
{
#ifdef GHOST_OPENGL_ALPHA
setOpaque();
#endif
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowSize, this));
}
wl_surface *GHOST_WindowWayland::surface() const
{
return w->wl_surface;
}
GHOST_WindowWayland *GHOST_WindowWayland::from_surface_find_mut(const wl_surface *surface)
{
GHOST_ASSERT(surface, "argument must not be NULL");
for (GHOST_IWindow *iwin : window_manager->getWindows()) {
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(iwin);
if (surface == win->surface()) {
return win;
}
}
return nullptr;
}
const GHOST_WindowWayland *GHOST_WindowWayland::from_surface_find(const wl_surface *surface)
{
return GHOST_WindowWayland::from_surface_find_mut(surface);
}
GHOST_WindowWayland *GHOST_WindowWayland::from_surface_mut(wl_surface *surface)
{
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface));
GHOST_ASSERT(win == GHOST_WindowWayland::from_surface_find_mut(surface),
"Inconsistent window state, consider using \"from_surface_find_mut\"");
return win;
}
const GHOST_WindowWayland *GHOST_WindowWayland::from_surface(const wl_surface *surface)
{
const GHOST_WindowWayland *win = static_cast<const GHOST_WindowWayland *>(
wl_surface_get_user_data(const_cast<wl_surface *>(surface)));
GHOST_ASSERT(win == GHOST_WindowWayland::from_surface_find(surface),
"Inconsistent window state, consider using \"from_surface_find\"");
return win;
}
const std::vector<output_t *> &GHOST_WindowWayland::outputs()
{
return w->outputs;
}
output_t *GHOST_WindowWayland::output_find_by_wl(struct wl_output *output)
{
for (output_t *reg_output : this->m_system->outputs()) {
if (reg_output->wl_output == output) {
return reg_output;
}
}
return nullptr;
}
bool GHOST_WindowWayland::outputs_changed_update_scale()
{
uint32_t dpi_next;
const int scale_next = outputs_max_scale_or_default(this->outputs(), 0, &dpi_next);
if (scale_next == 0) {
return false;
}
window_t *win = this->w;
const uint32_t dpi_curr = win->dpi;
const int scale_curr = win->scale;
bool changed = false;
if (scale_next != scale_curr) {
/* Unlikely but possible there is a pending size change is set. */
win->size_pending[0] = (win->size_pending[0] / scale_curr) * scale_next;
win->size_pending[1] = (win->size_pending[1] / scale_curr) * scale_next;
win->scale = scale_next;
wl_surface_set_buffer_scale(this->surface(), scale_next);
changed = true;
}
if (dpi_next != dpi_curr) {
/* Using the real DPI will cause wrong scaling of the UI
* use a multiplier for the default DPI as workaround. */
win->dpi = dpi_next;
changed = true;
}
return changed;
}
bool GHOST_WindowWayland::outputs_enter(output_t *reg_output)
{
std::vector<output_t *> &outputs = w->outputs;
auto it = std::find(outputs.begin(), outputs.end(), reg_output);
if (it != outputs.end()) {
return false;
}
outputs.push_back(reg_output);
return true;
}
bool GHOST_WindowWayland::outputs_leave(output_t *reg_output)
{
std::vector<output_t *> &outputs = w->outputs;
auto it = std::find(outputs.begin(), outputs.end(), reg_output);
if (it == outputs.end()) {
return false;
}
outputs.erase(it);
return true;
}
uint16_t GHOST_WindowWayland::dpi() const
{
return w->dpi;
}
int GHOST_WindowWayland::scale() const
{
return w->scale;
}
GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
{
return m_system->setCursorGrab(mode, m_cursorGrab, w->wl_surface);
@ -943,3 +782,192 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Direct Data Access
*
* Expose some members via methods.
* \{ */
uint16_t GHOST_WindowWayland::dpi() const
{
return w->dpi;
}
int GHOST_WindowWayland::scale() const
{
return w->scale;
}
wl_surface *GHOST_WindowWayland::surface() const
{
return w->wl_surface;
}
const std::vector<output_t *> &GHOST_WindowWayland::outputs()
{
return w->outputs;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Query Access
* \{ */
GHOST_WindowWayland *GHOST_WindowWayland::from_surface_find_mut(const wl_surface *surface)
{
GHOST_ASSERT(surface, "argument must not be NULL");
for (GHOST_IWindow *iwin : window_manager->getWindows()) {
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(iwin);
if (surface == win->surface()) {
return win;
}
}
return nullptr;
}
const GHOST_WindowWayland *GHOST_WindowWayland::from_surface_find(const wl_surface *surface)
{
return GHOST_WindowWayland::from_surface_find_mut(surface);
}
GHOST_WindowWayland *GHOST_WindowWayland::from_surface_mut(wl_surface *surface)
{
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface));
GHOST_ASSERT(win == GHOST_WindowWayland::from_surface_find_mut(surface),
"Inconsistent window state, consider using \"from_surface_find_mut\"");
return win;
}
const GHOST_WindowWayland *GHOST_WindowWayland::from_surface(const wl_surface *surface)
{
const GHOST_WindowWayland *win = static_cast<const GHOST_WindowWayland *>(
wl_surface_get_user_data(const_cast<wl_surface *>(surface)));
GHOST_ASSERT(win == GHOST_WindowWayland::from_surface_find(surface),
"Inconsistent window state, consider using \"from_surface_find\"");
return win;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Window Level Functions
*
* High Level Windowing Utilities.
* \{ */
GHOST_TSuccess GHOST_WindowWayland::close()
{
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowClose, this));
}
GHOST_TSuccess GHOST_WindowWayland::activate()
{
if (m_system->getWindowManager()->setActiveWindow(this) == GHOST_kFailure) {
return GHOST_kFailure;
}
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowActivate, this));
}
GHOST_TSuccess GHOST_WindowWayland::deactivate()
{
m_system->getWindowManager()->setWindowInactive(this);
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowDeactivate, this));
}
GHOST_TSuccess GHOST_WindowWayland::notify_size()
{
#ifdef GHOST_OPENGL_ALPHA
setOpaque();
#endif
return m_system->pushEvent(
new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowSize, this));
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public WAYLAND Utility Functions
*
* Functionality only used for the WAYLAND implementation.
* \{ */
bool GHOST_WindowWayland::outputs_changed_update_scale()
{
uint32_t dpi_next;
const int scale_next = outputs_max_scale_or_default(this->outputs(), 0, &dpi_next);
if (scale_next == 0) {
return false;
}
window_t *win = this->w;
const uint32_t dpi_curr = win->dpi;
const int scale_curr = win->scale;
bool changed = false;
if (scale_next != scale_curr) {
/* Unlikely but possible there is a pending size change is set. */
win->size_pending[0] = (win->size_pending[0] / scale_curr) * scale_next;
win->size_pending[1] = (win->size_pending[1] / scale_curr) * scale_next;
win->scale = scale_next;
wl_surface_set_buffer_scale(this->surface(), scale_next);
changed = true;
}
if (dpi_next != dpi_curr) {
/* Using the real DPI will cause wrong scaling of the UI
* use a multiplier for the default DPI as workaround. */
win->dpi = dpi_next;
changed = true;
}
return changed;
}
bool GHOST_WindowWayland::outputs_enter(output_t *reg_output)
{
std::vector<output_t *> &outputs = w->outputs;
auto it = std::find(outputs.begin(), outputs.end(), reg_output);
if (it != outputs.end()) {
return false;
}
outputs.push_back(reg_output);
return true;
}
bool GHOST_WindowWayland::outputs_leave(output_t *reg_output)
{
std::vector<output_t *> &outputs = w->outputs;
auto it = std::find(outputs.begin(), outputs.end(), reg_output);
if (it == outputs.end()) {
return false;
}
outputs.erase(it);
return true;
}
bool GHOST_WindowWayland::outputs_enter_wl(const wl_output *output)
{
output_t *reg_output = m_system->output_find_by_wl(output);
if (!reg_output) {
return false;
}
return outputs_enter(reg_output);
}
bool GHOST_WindowWayland::outputs_leave_wl(const wl_output *output)
{
output_t *reg_output = m_system->output_find_by_wl(output);
if (!reg_output) {
return false;
}
return outputs_leave(reg_output);
}
/** \} */

View File

@ -93,17 +93,14 @@ class GHOST_WindowWayland : public GHOST_Window {
void setOpaque() const;
#endif
/* WAYLAND utility functions. */
GHOST_TSuccess close();
GHOST_TSuccess activate();
GHOST_TSuccess deactivate();
GHOST_TSuccess notify_size();
/* WAYLAND direct-data access. */
uint16_t dpi() const;
int scale() const;
struct wl_surface *surface() const;
const std::vector<output_t *> &outputs();
/* WAYLAND query access. */
/**
* Use window find function when the window may have been closed.
@ -117,18 +114,22 @@ class GHOST_WindowWayland : public GHOST_Window {
static const GHOST_WindowWayland *from_surface(const wl_surface *surface);
static GHOST_WindowWayland *from_surface_mut(wl_surface *surface);
output_t *output_find_by_wl(struct wl_output *output);
/* WAYLAND window-level functions. */
const std::vector<output_t *> &outputs();
GHOST_TSuccess close();
GHOST_TSuccess activate();
GHOST_TSuccess deactivate();
GHOST_TSuccess notify_size();
/* WAYLAND utility functions. */
bool outputs_enter(output_t *reg_output);
bool outputs_leave(output_t *reg_output);
bool outputs_enter_wl(const struct wl_output *output);
bool outputs_leave_wl(const struct wl_output *output);
bool outputs_changed_update_scale();
uint16_t dpi() const;
int scale() const;
private:
GHOST_SystemWayland *m_system;
struct window_t *w;