mirror of https://github.com/encounter/SDL.git
Add back X11 legacy WM_NAME encodings
Closes #4924.
Based on patches of the past, such as this work by James Cloos in July
2010:
d7d98751b7
,
as well as code comments in the Perl module X11::Protocol::WM
(https://metacpan.org/pod/X11::Protocol::WM) and even the code to Xlib
itself, which taught me that we should never have been using
`XStoreName`, all it does is call `XChangeProperty`, hardcoded to
`XA_STRING`!
What can I say, when the task is old school, the sources are too 😂
This commit is contained in:
parent
72e53e4b87
commit
9c03d25543
|
@ -404,11 +404,10 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
|
||||||
int x, y;
|
int x, y;
|
||||||
XSizeHints *sizehints;
|
XSizeHints *sizehints;
|
||||||
XSetWindowAttributes wnd_attr;
|
XSetWindowAttributes wnd_attr;
|
||||||
Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_NAME;
|
Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG;
|
||||||
Display *display = data->display;
|
Display *display = data->display;
|
||||||
SDL_WindowData *windowdata = NULL;
|
SDL_WindowData *windowdata = NULL;
|
||||||
const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
|
const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
|
||||||
char *title_locale = NULL;
|
|
||||||
|
|
||||||
if ( messageboxdata->window ) {
|
if ( messageboxdata->window ) {
|
||||||
SDL_DisplayData *displaydata =
|
SDL_DisplayData *displaydata =
|
||||||
|
@ -452,32 +451,7 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
|
||||||
X11_XSetTransientForHint( display, data->window, windowdata->xwindow );
|
X11_XSetTransientForHint( display, data->window, windowdata->xwindow );
|
||||||
}
|
}
|
||||||
|
|
||||||
X11_XStoreName( display, data->window, messageboxdata->title );
|
SDL_X11_SetWindowTitle(display, data->window, (char*)messageboxdata->title);
|
||||||
_NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False);
|
|
||||||
|
|
||||||
title_locale = SDL_iconv_utf8_locale(messageboxdata->title);
|
|
||||||
if (title_locale) {
|
|
||||||
XTextProperty titleprop;
|
|
||||||
Status status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
|
|
||||||
SDL_free(title_locale);
|
|
||||||
if (status) {
|
|
||||||
X11_XSetTextProperty(display, data->window, &titleprop, XA_WM_NAME);
|
|
||||||
X11_XFree(titleprop.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef X_HAVE_UTF8_STRING
|
|
||||||
if (SDL_X11_HAVE_UTF8) {
|
|
||||||
XTextProperty titleprop;
|
|
||||||
Status status = X11_Xutf8TextListToTextProperty(display, (char **) &messageboxdata->title, 1,
|
|
||||||
XUTF8StringStyle, &titleprop);
|
|
||||||
if (status == Success) {
|
|
||||||
X11_XSetTextProperty(display, data->window, &titleprop,
|
|
||||||
_NET_WM_NAME);
|
|
||||||
X11_XFree(titleprop.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Let the window manager know this is a dialog box */
|
/* Let the window manager know this is a dialog box */
|
||||||
_NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
|
_NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
|
||||||
|
|
|
@ -156,6 +156,9 @@ SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,S
|
||||||
SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
|
SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
|
||||||
SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),)
|
SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),)
|
||||||
SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return)
|
SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return)
|
||||||
|
SDL_X11_SYM(Bool,XSupportsLocale,(void),(),return)
|
||||||
|
SDL_X11_SYM(void,XSetWMName,(Display* a,Window b,XTextProperty* c),(a,b,c),return)
|
||||||
|
SDL_X11_SYM(Status,XmbTextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return)
|
||||||
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_XFIXES
|
#if SDL_VIDEO_DRIVER_X11_XFIXES
|
||||||
SDL_X11_MODULE(XFIXES)
|
SDL_X11_MODULE(XFIXES)
|
||||||
|
|
|
@ -460,6 +460,14 @@ X11_VideoInit(_THIS)
|
||||||
X11_InitXfixes(_this);
|
X11_InitXfixes(_this);
|
||||||
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
|
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
|
||||||
|
|
||||||
|
#ifndef X_HAVE_UTF8_STRING
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "X server doesn't support UTF8_STRING, a feature introduced in 2000! This is likely to become a hard error in a future libSDL2.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (X11_XSupportsLocale() != True) {
|
||||||
|
return SDL_SetError("Current locale not supported by X server, cannot continue.");
|
||||||
|
}
|
||||||
|
|
||||||
if (X11_InitKeyboard(_this) != 0) {
|
if (X11_InitKeyboard(_this) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -716,9 +716,11 @@ X11_GetWindowTitle(_THIS, Window xwindow)
|
||||||
0L, 8192L, False, XA_STRING, &real_type, &real_format,
|
0L, 8192L, False, XA_STRING, &real_type, &real_format,
|
||||||
&items_read, &items_left, &propdata);
|
&items_read, &items_left, &propdata);
|
||||||
if (status == Success && propdata) {
|
if (status == Success && propdata) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to convert _WM_NAME title expecting UTF8! Title: %s", title);
|
||||||
title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
|
title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
|
||||||
X11_XFree(propdata);
|
X11_XFree(propdata);
|
||||||
} else {
|
} else {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not get any window title response from Xorg, returning empty string!");
|
||||||
title = SDL_strdup("");
|
title = SDL_strdup("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -729,30 +731,11 @@ void
|
||||||
X11_SetWindowTitle(_THIS, SDL_Window * window)
|
X11_SetWindowTitle(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
|
Window xwindow = data->xwindow;
|
||||||
Display *display = data->videodata->display;
|
Display *display = data->videodata->display;
|
||||||
Status status;
|
char *title = window->title ? window->title : "";
|
||||||
const char *title = window->title ? window->title : "";
|
|
||||||
|
|
||||||
Atom UTF8_STRING = data->videodata->UTF8_STRING;
|
SDL_X11_SetWindowTitle(display, xwindow, title);
|
||||||
Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
|
|
||||||
Atom WM_NAME = data->videodata->WM_NAME;
|
|
||||||
|
|
||||||
X11_XChangeProperty(display, data->xwindow, WM_NAME, UTF8_STRING, 8, 0, (const unsigned char *) title, SDL_strlen(title));
|
|
||||||
|
|
||||||
status = X11_XChangeProperty(display, data->xwindow, _NET_WM_NAME, UTF8_STRING, 8, 0, (const unsigned char *) title, SDL_strlen(title));
|
|
||||||
|
|
||||||
if (status != 1) {
|
|
||||||
char *x11_error = NULL;
|
|
||||||
char x11_error_locale[256];
|
|
||||||
if (X11_XGetErrorText(display, status, x11_error_locale, sizeof(x11_error_locale)) == Success)
|
|
||||||
{
|
|
||||||
x11_error = SDL_iconv_string("UTF-8", "", x11_error_locale, SDL_strlen(x11_error_locale)+1);
|
|
||||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Error when setting X11 window title to %s: %s\n", title, x11_error);
|
|
||||||
SDL_free(x11_error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
X11_XFlush(display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1888,6 +1871,39 @@ X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* title) {
|
||||||
|
Atom _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False);
|
||||||
|
XTextProperty titleprop;
|
||||||
|
int conv = X11_XmbTextListToTextProperty(display, (char**) &title, 1, XStdICCTextStyle, &titleprop);
|
||||||
|
Status status;
|
||||||
|
|
||||||
|
if (conv == 0) {
|
||||||
|
X11_XSetTextProperty(display, xwindow, &titleprop, XA_WM_NAME);
|
||||||
|
X11_XFree(titleprop.value);
|
||||||
|
// we know this can't be a locale error as we checked X locale validity in X11_VideoInit
|
||||||
|
} else if (conv <= 0) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "X11 reporting it's out of memory");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else { // conv >= 0
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "%d characters were not convertable to the current locale!", conv);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
|
status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, XUTF8StringStyle, &titleprop);
|
||||||
|
if (status == Success) {
|
||||||
|
X11_XSetTextProperty(display, xwindow, &titleprop, _NET_WM_NAME);
|
||||||
|
X11_XFree(titleprop.value);
|
||||||
|
} else {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to convert title to UTF8! Bad encoding, or bad Xorg encoding? Window title: «%s»", title);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
X11_XFlush(display);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_X11 */
|
#endif /* SDL_VIDEO_DRIVER_X11 */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -117,6 +117,8 @@ extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||||
extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
|
extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
|
||||||
extern int X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
|
extern int X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
|
||||||
|
|
||||||
|
bool SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* string);
|
||||||
|
|
||||||
#endif /* SDL_x11window_h_ */
|
#endif /* SDL_x11window_h_ */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
Loading…
Reference in New Issue