112112#define GLFW_EXPOSE_NATIVE_WIN32
113113#endif
114114#include < GLFW/glfw3native.h> // for glfwGetWin32Window()
115- #endif
116- #ifdef __APPLE__
115+ #elif defined(__APPLE__)
117116#ifndef GLFW_EXPOSE_NATIVE_COCOA
118117#define GLFW_EXPOSE_NATIVE_COCOA
119118#endif
120119#include < GLFW/glfw3native.h> // for glfwGetCocoaWindow()
120+ #elif !defined(__EMSCRIPTEN__)
121+ // Freedesktop(Linux, BSD, etc)
122+ #ifndef GLFW_EXPOSE_NATIVE_X11
123+ #define GLFW_EXPOSE_NATIVE_X11
124+ #include < X11/Xatom.h>
125+ #endif
126+ #ifndef GLFW_EXPOSE_NATIVE_WAYLAND
127+ #define GLFW_EXPOSE_NATIVE_WAYLAND
128+ #endif
129+ #include < GLFW/glfw3native.h> // For getting the X11/Wayland window
121130#endif
122131#ifndef _WIN32
123132#include < unistd.h> // for usleep()
@@ -1114,6 +1123,60 @@ static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
11141123 }
11151124}
11161125
1126+ #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && (GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4))
1127+ static void ImGui_ImplGlfw_SetWindowIDFreedesktop (GLFWwindow* root)
1128+ {
1129+ // Should resolve issues where applications that utilise the viewports that have not set a WM_CLASS/WM_INSTANCE/xdg_toplevel
1130+ // application ID are shown incorrectly in desktop menus on freedesktop systems.
1131+ //
1132+ // CAUTION: Only really supports X11 right now!
1133+ //
1134+ // Gets the WM_CLASS and WM_INSTANCE properties from the root application X11 window and sets them for every viewport window.
1135+ //
1136+ // The major issue with this implementation is that as of now it's X11-specific. Scroll to the next comment to learn
1137+ // more about this.
1138+ #ifdef GLFW_EXPOSE_NATIVE_X11
1139+ if (glfwGetPlatform () == GLFW_PLATFORM_X11)
1140+ {
1141+ const auto display = glfwGetX11Display ();
1142+ const auto window = glfwGetX11Window (root);
1143+
1144+ const Atom wmClassAtom = XInternAtom (display, " WM_CLASS" , False);
1145+ Atom actualAtom;
1146+ int format;
1147+ unsigned long n, bytesAfter;
1148+ unsigned char * prop = NULL ;
1149+
1150+ if (XGetWindowProperty (display, window, wmClassAtom, 0 , 1024 , False, XA_STRING, &actualAtom, &format, &n, &bytesAfter, &prop) == Success && prop)
1151+ {
1152+ // These 2 strings are packed into 1 string with 2 null terminators. Weird, I know
1153+ const char * instance = (char *)prop;
1154+ const char * className = instance + strlen (instance) + 1 ;
1155+
1156+ glfwWindowHintString (GLFW_X11_CLASS_NAME, className);
1157+ glfwWindowHintString (GLFW_X11_INSTANCE_NAME, instance);
1158+
1159+ XFree (prop);
1160+ }
1161+ }
1162+ #endif
1163+
1164+ #ifdef GLFW_EXPOSE_NATIVE_WAYLAND
1165+ // TODO: HELP NEEDED! NOT IMPLEMENTED! Periodically check if the statements below are true
1166+ // Explanation: GLFW always sets some type of WM_CLASS or WM_INSTANCE on X11, however on Wayland it seems that it
1167+ // does not set any value, unless we tell it to. Given that child windows inherit window hints of parent windows,
1168+ // this means that parents and any subsequent windows have the same app ID of "". This means that they(should) be
1169+ // grouped correctly, however applications which do not set the app ID manually for their root window will not be
1170+ // able to take advantage of features of their desktop that require app IDs, including users being able to
1171+ // configure their behaviour in the window manager settings!
1172+ //
1173+ // And why is this not implemented? It might be impossible in the scope of dear imgui, or at least I do not know
1174+ // how to implement it. From what I found, the current xdg_toplevel interface does not support a way to get the app
1175+ // ID of a window in a non-compositor-specific manner
1176+ #endif
1177+ }
1178+ #endif
1179+
11171180static void ImGui_ImplGlfw_CreateWindow (ImGuiViewport* viewport)
11181181{
11191182 ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData ();
@@ -1137,6 +1200,9 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
11371200 glfwWindowHint (GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false );
11381201#endif
11391202 GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : nullptr ;
1203+ #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && (GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4))
1204+ ImGui_ImplGlfw_SetWindowIDFreedesktop (bd->Window );
1205+ #endif
11401206 vd->Window = glfwCreateWindow ((int )viewport->Size .x , (int )viewport->Size .y , " No Title Yet" , nullptr , share_window);
11411207 vd->WindowOwned = true ;
11421208 viewport->PlatformHandle = (void *)vd->Window ;
0 commit comments