@@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
43
43
#ifdef XORG_USED
44
44
#include < X11/Xlib.h>
45
45
#include < X11/Xutil.h>
46
+ #include < X11/Xatom.h>
46
47
#endif
47
48
48
49
#ifdef __ANDROID__
@@ -186,23 +187,119 @@ bool RenderingEngine::print_video_modes()
186
187
return videomode_list != NULL ;
187
188
}
188
189
189
- void RenderingEngine::setXorgClassHint (
190
- const video::SExposedVideoData &video_data, const std::string &name)
190
+ bool RenderingEngine::setupTopLevelWindow (const std::string &name)
191
+ {
192
+ // FIXME: It would make more sense for there to be a switch of some
193
+ // sort here that would call the correct toplevel setup methods for
194
+ // the environment Minetest is running in but for now not deviating
195
+ // from the original pattern.
196
+
197
+ /* Setting Xorg properties for the top level window */
198
+ setupTopLevelXorgWindow (name);
199
+ /* Done with Xorg properties */
200
+
201
+ /* Setting general properties for the top level window */
202
+ verbosestream << " Client: Configuring general top level"
203
+ << " window properties"
204
+ << std::endl;
205
+
206
+ bool result = setWindowIcon ();
207
+
208
+ verbosestream << " Client: Finished configuring general top level"
209
+ << " window properties"
210
+ << std::endl;
211
+ /* Done with general properties */
212
+
213
+ // FIXME: setWindowIcon returns a bool result but it is unused.
214
+ // For now continue to return this result.
215
+ return result;
216
+ }
217
+
218
+ void RenderingEngine::setupTopLevelXorgWindow (const std::string &name)
191
219
{
192
220
#ifdef XORG_USED
193
- if (video_data.OpenGLLinux .X11Display == NULL )
221
+ const video::SExposedVideoData exposedData = driver->getExposedVideoData ();
222
+
223
+ Display *x11_dpl = reinterpret_cast <Display *>(exposedData.OpenGLLinux .X11Display );
224
+ if (x11_dpl == NULL ) {
225
+ warningstream << " Client: Could not find X11 Display in ExposedVideoData"
226
+ << std::endl;
194
227
return ;
228
+ }
229
+
230
+ verbosestream << " Client: Configuring Xorg specific top level"
231
+ << " window properties"
232
+ << std::endl;
233
+
195
234
235
+ Window x11_win = reinterpret_cast <Window>(exposedData.OpenGLLinux .X11Window );
236
+
237
+ // Set application name and class hints. For now name and class are the same.
196
238
XClassHint *classhint = XAllocClassHint ();
197
- classhint->res_name = ( char *) name.c_str ();
198
- classhint->res_class = ( char *) name.c_str ();
239
+ classhint->res_name = const_cast < char *>( name.c_str () );
240
+ classhint->res_class = const_cast < char *>( name.c_str () );
199
241
200
- XSetClassHint ((Display *)video_data.OpenGLLinux .X11Display ,
201
- video_data.OpenGLLinux .X11Window , classhint);
242
+ XSetClassHint (x11_dpl, x11_win, classhint);
202
243
XFree (classhint);
244
+
245
+ // FIXME: In the future WMNormalHints should be set ... e.g see the
246
+ // gtk/gdk code (gdk/x11/gdksurface-x11.c) for the setup_top_level
247
+ // method. But for now (as it would require some significant changes)
248
+ // leave the code as is.
249
+
250
+ // The following is borrowed from the above gdk source for setting top
251
+ // level windows. The source indicates and the Xlib docs suggest that
252
+ // this will set the WM_CLIENT_MACHINE and WM_LOCAL_NAME. This will not
253
+ // set the WM_CLIENT_MACHINE to a Fully Qualified Domain Name (FQDN) which is
254
+ // required by the Extended Window Manager Hints (EWMH) spec when setting
255
+ // the _NET_WM_PID (see further down) but running Minetest in an env
256
+ // where the window manager is on another machine from Minetest (therefore
257
+ // making the PID useless) is not expected to be a problem. Further
258
+ // more, using gtk/gdk as the model it would seem that not using a FQDN is
259
+ // not an issue for modern Xorg window managers.
260
+
261
+ verbosestream << " Client: Setting Xorg window manager Properties"
262
+ << std::endl;
263
+
264
+ XSetWMProperties (x11_dpl, x11_win, NULL , NULL , NULL , 0 , NULL , NULL , NULL );
265
+
266
+ // Set the _NET_WM_PID window property according to the EWMH spec. _NET_WM_PID
267
+ // (in conjunction with WM_CLIENT_MACHINE) can be used by window managers to
268
+ // force a shutdown of an application if it doesn't respond to the destroy
269
+ // window message.
270
+
271
+ verbosestream << " Client: Setting Xorg _NET_WM_PID extened window manager property"
272
+ << std::endl;
273
+
274
+ Atom NET_WM_PID = XInternAtom (x11_dpl, " _NET_WM_PID" , false );
275
+
276
+ pid_t pid = getpid ();
277
+ infostream << " Client: PID is '" << static_cast <long >(pid) << " '"
278
+ << std::endl;
279
+
280
+ XChangeProperty (x11_dpl, x11_win, NET_WM_PID,
281
+ XA_CARDINAL, 32 , PropModeReplace,
282
+ reinterpret_cast <unsigned char *>(&pid),1 );
283
+
284
+ // Set the WM_CLIENT_LEADER window property here. Minetest has only one
285
+ // window and that window will always be the leader.
286
+
287
+ verbosestream << " Client: Setting Xorg WM_CLIENT_LEADER property"
288
+ << std::endl;
289
+
290
+ Atom WM_CLIENT_LEADER = XInternAtom (x11_dpl, " WM_CLIENT_LEADER" , false );
291
+
292
+ XChangeProperty (x11_dpl, x11_win, WM_CLIENT_LEADER,
293
+ XA_WINDOW, 32 , PropModeReplace,
294
+ reinterpret_cast <unsigned char *>(&x11_win), 1 );
295
+
296
+ verbosestream << " Client: Finished configuring Xorg specific top level"
297
+ << " window properties"
298
+ << std::endl;
203
299
#endif
204
300
}
205
301
302
+
206
303
bool RenderingEngine::setWindowIcon ()
207
304
{
208
305
#if defined(XORG_USED)
0 commit comments