Browse Source

Allow to pick X11 vs Wayland on app creation

Signed-off-by: falkTX <falktx@falktx.com>
wayland
falkTX 1 month ago
parent
commit
da7f06c06e
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
6 changed files with 138 additions and 49 deletions
  1. +19
    -1
      dgl/Application.hpp
  2. +8
    -3
      dgl/src/Application.cpp
  3. +19
    -12
      dgl/src/ApplicationPrivateData.cpp
  4. +8
    -5
      dgl/src/ApplicationPrivateData.hpp
  5. +77
    -28
      dgl/src/pugl.cpp
  6. +7
    -0
      dgl/src/pugl.hpp

+ 19
- 1
dgl/Application.hpp View File

@@ -83,10 +83,22 @@ BUILD_CONFIG_SENTINEL(fail_to_link_is_mismatch_dgl_no_shared_resources_off)
class DISTRHO_API Application
{
public:
/**
Type of application to setup, either "classic" or "modern".

What this means depends on the OS.
For now it's only relevant on X11 vs Wayland systems, where X11 is kTypeClassic and Wayland is kTypeModern.
*/
enum Type {
kTypeAuto,
kTypeClassic,
kTypeModern,
};

/**
Constructor for standalone or plugin application.
*/
Application(bool isStandalone = true);
Application(bool isStandalone = true, Type type = kTypeAuto);

/**
Constructor for a standalone application.
@@ -141,6 +153,12 @@ public:
*/
double getTime() const;

/**
Return the application type, either kTypeClassic or kTypeModern.
This function never return kTypeAuto.
*/
Type getType() const noexcept;

/**
Add a callback function to be triggered on every idle cycle.
You can add more than one, and remove them at anytime with removeIdleCallback().


+ 8
- 3
dgl/src/Application.cpp View File

@@ -98,8 +98,8 @@ static void app_idle(void* const app)
}
#endif

Application::Application(const bool isStandalone)
: pData(new PrivateData(isStandalone))
Application::Application(const bool isStandalone, const Type type)
: pData(new PrivateData(isStandalone, type))
{
// build config sentinels
#ifdef DPF_DEBUG
@@ -126,7 +126,7 @@ Application::Application(const bool isStandalone)
}

Application::Application(int argc, char* argv[])
: pData(new PrivateData(true))
: pData(new PrivateData(true, kTypeAuto))
{
#if defined(HAVE_X11) && defined(DISTRHO_OS_LINUX) && defined(DGL_USE_WEB_VIEW)
if (argc >= 2 && std::strcmp(argv[1], "dpf-ld-linux-webview") == 0)
@@ -213,6 +213,11 @@ double Application::getTime() const
return pData->getTime();
}

Application::Type Application::getType() const noexcept
{
return pData->isModern ? kTypeModern : kTypeClassic;
}

void Application::addIdleCallback(IdleCallback* const callback)
{
DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,)


+ 19
- 12
dgl/src/ApplicationPrivateData.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -53,13 +53,28 @@ const char* Application::getClassName() const noexcept

// --------------------------------------------------------------------------------------------------------------------

Application::PrivateData::PrivateData(const bool standalone)
static constexpr inline uint32_t AppTypePuglWorldFlags(Application::Type type) noexcept
{
#ifdef DGL_USING_X11_OR_WAYLAND
return type == Application::kTypeClassic ? PUGL_WORLD_BACKEND_X11 :
type == Application::kTypeModern ? PUGL_WORLD_BACKEND_WAYLAND : 0;
#else
return 0;
#endif
}

Application::PrivateData::PrivateData(const bool standalone, const Type type)
: world(puglNewWorld(standalone ? PUGL_PROGRAM : PUGL_MODULE,
standalone ? PUGL_WORLD_THREADS : 0x0)),
(standalone ? PUGL_WORLD_THREADS : 0) | AppTypePuglWorldFlags(type))),
#ifdef DGL_USING_X11_OR_WAYLAND
isModern(world != nullptr && puglUsingWayland(world)),
#else
isModern(false),
#endif
isStandalone(standalone),
isStarting(true),
isQuitting(false),
isQuittingInNextCycle(false),
isStarting(true),
needsRepaint(false),
visibleWindows(0),
mainThreadHandle(getCurrentThreadHandle()),
@@ -68,15 +83,11 @@ Application::PrivateData::PrivateData(const bool standalone)
{
DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,);

#ifdef DGL_USING_SDL
SDL_Init(SDL_INIT_EVENTS|SDL_INIT_TIMER|SDL_INIT_VIDEO);
#else
#ifdef __EMSCRIPTEN__
puglSetWorldString(world, PUGL_CLASS_NAME, "canvas");
#else
puglSetWorldString(world, PUGL_CLASS_NAME, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE));
#endif
#endif
}

Application::PrivateData::~PrivateData()
@@ -87,12 +98,8 @@ Application::PrivateData::~PrivateData()
windows.clear();
idleCallbacks.clear();

#ifdef DGL_USING_SDL
SDL_Quit();
#else
if (world != nullptr)
puglFreeWorld(world);
#endif
}

// --------------------------------------------------------------------------------------------------------------------


+ 8
- 5
dgl/src/ApplicationPrivateData.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -51,18 +51,21 @@ struct Application::PrivateData {
/** Pugl world instance. */
PuglWorld* const world;

/** Whether the applicating uses modern backend, otherwise classic. */
const bool isModern;

/** Whether the application is running as standalone, otherwise it is part of a plugin. */
const bool isStandalone;

/** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */
bool isStarting;

/** Whether the applicating is about to quit, or already stopped. Defaults to false. */
bool isQuitting;

/** Helper for safely close everything from main thread. */
bool isQuittingInNextCycle;

/** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */
bool isStarting;

/** When true force all windows to be repainted on next idle. */
bool needsRepaint;

@@ -80,7 +83,7 @@ struct Application::PrivateData {
std::list<DGL_NAMESPACE::IdleCallback*> idleCallbacks;

/** Constructor and destructor */
explicit PrivateData(bool standalone);
explicit PrivateData(bool standalone, Type type);
~PrivateData();

/** Flag one window as shown, which increments @a visibleWindows.


+ 77
- 28
dgl/src/pugl.cpp View File

@@ -966,32 +966,85 @@ PuglInternals* puglInitViewInternals(PuglWorld* const world)
PuglWorldInternals* puglInitWorldInternals(PuglWorld* const world, const PuglWorldType type, const PuglWorldFlags flags)
{
bool supportsDecorations = true;
#ifdef HAVE_WAYLAND
const bool usingWayland = puglWaylandStatus(&supportsDecorations);
#else
constexpr bool usingWayland = false;
#endif
d_stdout("Using wayland: %d, compositor supports decorations: %d", usingWayland, supportsDecorations);
bool usingWayland = false;
bool usingX11 = false;

// initial choice by env var
if (const char* const backend = std::getenv("DPF_BACKEND"))
{
if (std::strcmp(backend, "x11") == 0)
usingX11 = true;
else if (std::strcmp(backend, "wayland") != 0)
usingWayland = true;
else
d_stderr("Unknown DPF_BACKEND value, must be 'x11' or 'wayland'");
}

// overridden if required for operation
if (flags & PUGL_WORLD_BACKEND_X11)
{
usingX11 = true;
usingWayland = false;
}
if (flags & PUGL_WORLD_BACKEND_WAYLAND)
{
usingX11 = false;
usingWayland = true;
#ifdef HAVE_WAYLAND
puglWaylandStatus(&supportsDecorations);
#endif
}

// pick backend automatically if none selected
if (! (usingX11 || usingWayland))
{
#ifdef HAVE_WAYLAND
usingWayland = puglWaylandStatus(&supportsDecorations);
if (! usingWayland)
#endif
{
#ifdef HAVE_X11
supportsDecorations = true;
usingX11 = true;
#endif
}

if (! (usingX11 || usingWayland))
{
d_stderr("Could not find a usable windowing backend");
return nullptr;
}
}

if (usingX11)
{
#ifdef HAVE_X11
d_stdout("Using X11");
x11::PuglWorld* const x11world = cast<x11::PuglWorld>(world);
x11::puglSetWorldHandle(x11world, const_cast<char*>(kUsingX11Check));
return cast<PuglWorldInternals>(x11::puglInitWorldInternals(x11world,
static_cast<x11::PuglWorldType>(type),
static_cast<x11::PuglWorldFlags>(flags)));
#else
return nullptr;
#endif
}

#ifdef HAVE_WAYLAND
if (usingWayland)
{
#ifdef HAVE_WAYLAND
d_stdout("Using Wayland, compositor supports decorations: %s", supportsDecorations ? "true" : "false");
wl::PuglWorld* const wlworld = cast<wl::PuglWorld>(world);
wl::puglSetWorldHandle(wlworld, const_cast<char*>(kUsingWaylandCheck));
return cast<PuglWorldInternals>(wl::puglInitWorldInternals(wlworld,
static_cast<wl::PuglWorldType>(type),
static_cast<wl::PuglWorldFlags>(flags)));
#else
return nullptr;
#endif
}
#endif
#ifdef HAVE_X11
x11::PuglWorld* const x11world = cast<x11::PuglWorld>(world);
x11::puglSetWorldHandle(x11world, const_cast<char*>(kUsingX11Check));
return cast<PuglWorldInternals>(x11::puglInitWorldInternals(x11world,
static_cast<x11::PuglWorldType>(type),
static_cast<x11::PuglWorldFlags>(flags)));
#else

return nullptr;
#endif
}


@@ -1182,6 +1235,14 @@ PuglStatus puglViewStringChanged(PuglView* const view, const PuglStringHint key,
return PUGL_BAD_BACKEND;
}

// --------------------------------------------------------------------------------------------------------------------
// X11 or Wayland specific, check if using wayland

bool puglUsingWayland(PuglWorld* const world)
{
return world->handle == kUsingWaylandCheck;
}

#ifdef HAVE_X11

// --------------------------------------------------------------------------------------------------------------------
@@ -1288,18 +1349,6 @@ bool puglWaylandStatus(bool* supportsDecorations)
bool supportsWayland = false;
*supportsDecorations = false;

if (const char* const backend = std::getenv("DPF_BACKEND"))
{
if (std::strcmp(backend, "x11") == 0)
return false;

if (std::strcmp(backend, "wayland") != 0)
{
d_stderr2("Unknown DPF_BACKEND value, will use X11");
return false;
}
}

if (struct wl_display* const wl_display = wl_display_connect(nullptr))
{
if (struct wl_registry* const wl_registry = wl_display_get_registry(wl_display))


+ 7
- 0
dgl/src/pugl.hpp View File

@@ -118,6 +118,13 @@ void puglWin32ShowCentered(PuglView* view);

#define DGL_USING_X11_OR_WAYLAND

// custom flags for world creation
#define PUGL_WORLD_BACKEND_X11 0x1000
#define PUGL_WORLD_BACKEND_WAYLAND 0x2000

// X11 or Wayland specific, check if using wayland
bool puglUsingWayland(PuglWorld* world);

#ifdef HAVE_X11
#define DGL_USING_X11



Loading…
Cancel
Save