Wayland: Set "class" for each window we create
authorBastien Nocera <hadess@hadess.net>
Thu, 01 Sep 2016 01:22:58 -0700
changeset 10302729eff9ee77a
parent 10301 a25d9c643cfb
child 10303 b326f93e1bc5
Wayland: Set "class" for each window we create
This will be used by Wayland compositors to match the application ID and
.desktop file to the SDL window(s).

Applications can set the SDL_VIDEO_WAYLAND_WMCLASS environemnt variable
early in the process to override using the binary name as a fallback.

Note that we also support the SDL_VIDEO_X11_WMCLASS in the Wayland
backend so that if a program correctly associated the desktop file with
the window under X11, only a newer SDL would be needed for it to work
under Wayland.

https://bugzilla.libsdl.org/show_bug.cgi?id=3376
src/video/wayland/SDL_waylandvideo.c
src/video/wayland/SDL_waylandvideo.h
src/video/wayland/SDL_waylandwindow.c
     1.1 --- a/src/video/wayland/SDL_waylandvideo.c	Wed Aug 31 16:10:04 2016 -0400
     1.2 +++ b/src/video/wayland/SDL_waylandvideo.c	Thu Sep 01 01:22:58 2016 -0700
     1.3 @@ -35,6 +35,8 @@
     1.4  #include "SDL_waylandmouse.h"
     1.5  #include "SDL_waylandtouch.h"
     1.6  
     1.7 +#include <sys/types.h>
     1.8 +#include <unistd.h>
     1.9  #include <fcntl.h>
    1.10  #include <xkbcommon/xkbcommon.h>
    1.11  
    1.12 @@ -55,6 +57,56 @@
    1.13  static void
    1.14  Wayland_VideoQuit(_THIS);
    1.15  
    1.16 +/* Find out what class name we should use
    1.17 + * Based on src/video/x11/SDL_x11video.c */
    1.18 +static char *
    1.19 +get_classname()
    1.20 +{
    1.21 +    char *spot;
    1.22 +#if defined(__LINUX__) || defined(__FREEBSD__)
    1.23 +    char procfile[1024];
    1.24 +    char linkfile[1024];
    1.25 +    int linksize;
    1.26 +#endif
    1.27 +
    1.28 +    /* First allow environment variable override */
    1.29 +    spot = SDL_getenv("SDL_VIDEO_WAYLAND_WMCLASS");
    1.30 +    if (spot) {
    1.31 +        return SDL_strdup(spot);
    1.32 +    } else {
    1.33 +        /* Fallback to the "old" envvar */
    1.34 +        spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
    1.35 +        if (spot) {
    1.36 +            return SDL_strdup(spot);
    1.37 +        }
    1.38 +    }
    1.39 +
    1.40 +    /* Next look at the application's executable name */
    1.41 +#if defined(__LINUX__) || defined(__FREEBSD__)
    1.42 +#if defined(__LINUX__)
    1.43 +    SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
    1.44 +#elif defined(__FREEBSD__)
    1.45 +    SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
    1.46 +                 getpid());
    1.47 +#else
    1.48 +#error Where can we find the executable name?
    1.49 +#endif
    1.50 +    linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
    1.51 +    if (linksize > 0) {
    1.52 +        linkfile[linksize] = '\0';
    1.53 +        spot = SDL_strrchr(linkfile, '/');
    1.54 +        if (spot) {
    1.55 +            return SDL_strdup(spot + 1);
    1.56 +        } else {
    1.57 +            return SDL_strdup(linkfile);
    1.58 +        }
    1.59 +    }
    1.60 +#endif /* __LINUX__ || __FREEBSD__ */
    1.61 +
    1.62 +    /* Finally use the default we've used forever */
    1.63 +    return SDL_strdup("SDL_App");
    1.64 +}
    1.65 +
    1.66  /* Wayland driver bootstrap functions */
    1.67  static int
    1.68  Wayland_Available(void)
    1.69 @@ -307,6 +359,9 @@
    1.70  
    1.71      Wayland_InitMouse();
    1.72  
    1.73 +    /* Get the surface class name, usually the name of the application */
    1.74 +    data->classname = get_classname();
    1.75 +
    1.76      WAYLAND_wl_display_flush(data->display);
    1.77  
    1.78      return 0;
    1.79 @@ -375,6 +430,7 @@
    1.80          WAYLAND_wl_display_disconnect(data->display);
    1.81      }
    1.82  
    1.83 +    SDL_free(data->classname);
    1.84      free(data);
    1.85      _this->driverdata = NULL;
    1.86  }
     2.1 --- a/src/video/wayland/SDL_waylandvideo.h	Wed Aug 31 16:10:04 2016 -0400
     2.2 +++ b/src/video/wayland/SDL_waylandvideo.h	Thu Sep 01 01:22:58 2016 -0700
     2.3 @@ -57,6 +57,8 @@
     2.4      struct qt_surface_extension *surface_extension;
     2.5      struct qt_windowmanager *windowmanager;
     2.6  #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
     2.7 +
     2.8 +    char *classname;
     2.9  } SDL_VideoData;
    2.10  
    2.11  #endif /* _SDL_waylandvideo_h */
     3.1 --- a/src/video/wayland/SDL_waylandwindow.c	Wed Aug 31 16:10:04 2016 -0400
     3.2 +++ b/src/video/wayland/SDL_waylandwindow.c	Thu Sep 01 01:22:58 2016 -0700
     3.3 @@ -178,6 +178,7 @@
     3.4      wl_surface_set_user_data(data->surface, data);
     3.5      data->shell_surface = wl_shell_get_shell_surface(c->shell,
     3.6                                                       data->surface);
     3.7 +    wl_shell_surface_set_class (data->shell_surface, c->classname);
     3.8  #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH    
     3.9      if (c->surface_extension) {
    3.10          data->extended_surface = qt_surface_extension_get_extended_surface(