|
23 | 23 | #include <unistd.h> |
24 | 24 | #include <sys/types.h> |
25 | 25 |
|
| 26 | +#include <X11/Xlib.h> |
| 27 | +#include <X11/Xatom.h> |
| 28 | + |
26 | 29 | #include <glib.h> |
27 | 30 | #include <glib/gi18n.h> |
28 | 31 | #include <glib/gstdio.h> |
29 | 32 | #include <gio/gio.h> |
30 | 33 | #include <gdk-pixbuf/gdk-pixbuf.h> |
| 34 | +#include <gdk/gdkx.h> |
31 | 35 |
|
32 | 36 | #define MATE_DESKTOP_USE_UNSTABLE_API |
33 | 37 | #include <libmate-desktop/mate-desktop-utils.h> |
|
47 | 51 | #include "panel-icon-names.h" |
48 | 52 | #include "panel-lockdown.h" |
49 | 53 |
|
| 54 | +static Atom _net_active_window = None; |
| 55 | + |
50 | 56 | char * |
51 | 57 | panel_util_make_exec_uri_for_desktop (const char *exec) |
52 | 58 | { |
@@ -1241,3 +1247,89 @@ panel_util_get_file_optional_homedir (const char *location) |
1241 | 1247 |
|
1242 | 1248 | return file; |
1243 | 1249 | } |
| 1250 | + |
| 1251 | +static void panel_menu_bar_get_net_active_window(Display *xdisplay) |
| 1252 | +{ |
| 1253 | + if (_net_active_window == None) |
| 1254 | + _net_active_window = XInternAtom (xdisplay, |
| 1255 | + "_NET_ACTIVE_WINDOW", |
| 1256 | + False); |
| 1257 | +} |
| 1258 | + |
| 1259 | +Window panel_util_get_current_active_window (GtkWidget *toplevel) |
| 1260 | +{ |
| 1261 | + GdkScreen *screen; |
| 1262 | + GdkDisplay *display; |
| 1263 | + GdkWindow *root; |
| 1264 | + Display *xdisplay; |
| 1265 | + Window xroot; |
| 1266 | + |
| 1267 | + Window res = None; |
| 1268 | + |
| 1269 | + Atom return_type; |
| 1270 | + int return_format; |
| 1271 | + unsigned long n; |
| 1272 | + unsigned long bytes; |
| 1273 | + unsigned char *prop = NULL; |
| 1274 | + |
| 1275 | + screen = gtk_window_get_screen (GTK_WINDOW(toplevel)); |
| 1276 | + display = gdk_screen_get_display (screen); |
| 1277 | + root = gdk_screen_get_root_window (screen); |
| 1278 | + |
| 1279 | + xdisplay = GDK_DISPLAY_XDISPLAY (display); |
| 1280 | + xroot = GDK_WINDOW_XID (root); |
| 1281 | + |
| 1282 | + panel_menu_bar_get_net_active_window (xdisplay); |
| 1283 | + if (_net_active_window != None |
| 1284 | + && XGetWindowProperty (xdisplay, xroot, _net_active_window, 0, 1, |
| 1285 | + False, XA_WINDOW, &return_type, &return_format, |
| 1286 | + &n, &bytes, &prop) == Success) |
| 1287 | + { |
| 1288 | + if ((return_type == XA_WINDOW) && (return_format == 32) && |
| 1289 | + (n == 1) && (prop)) { |
| 1290 | + res = *(Window *)prop; |
| 1291 | + } |
| 1292 | + |
| 1293 | + if (prop) |
| 1294 | + XFree (prop); |
| 1295 | + |
| 1296 | + } |
| 1297 | + return res; |
| 1298 | +} |
| 1299 | + |
| 1300 | +void panel_util_set_current_active_window (GtkWidget *toplevel, Window window) |
| 1301 | +{ |
| 1302 | + GdkScreen *screen; |
| 1303 | + GdkDisplay *display; |
| 1304 | + GdkWindow *root; |
| 1305 | + Display *xdisplay; |
| 1306 | + Window xroot; |
| 1307 | + XEvent xev; |
| 1308 | + |
| 1309 | + screen = gtk_window_get_screen (GTK_WINDOW(toplevel)); |
| 1310 | + display = gdk_screen_get_display (screen); |
| 1311 | + root = gdk_screen_get_root_window (screen); |
| 1312 | + |
| 1313 | + xdisplay = GDK_DISPLAY_XDISPLAY (display); |
| 1314 | + xroot = GDK_WINDOW_XID (root); |
| 1315 | + |
| 1316 | + panel_menu_bar_get_net_active_window (xdisplay); |
| 1317 | + if (_net_active_window == None) |
| 1318 | + return; |
| 1319 | + |
| 1320 | + xev.xclient.type = ClientMessage; |
| 1321 | + xev.xclient.serial = 0; |
| 1322 | + xev.xclient.send_event = True; |
| 1323 | + xev.xclient.window = window; |
| 1324 | + xev.xclient.message_type = _net_active_window; |
| 1325 | + xev.xclient.format = 32; |
| 1326 | + xev.xclient.data.l[0] = 2; /* requestor type; we're not an app */ |
| 1327 | + xev.xclient.data.l[1] = CurrentTime; |
| 1328 | + xev.xclient.data.l[2] = None; /* our currently active window */ |
| 1329 | + xev.xclient.data.l[3] = 0; |
| 1330 | + xev.xclient.data.l[4] = 0; |
| 1331 | + |
| 1332 | + XSendEvent (xdisplay, xroot, False, |
| 1333 | + SubstructureRedirectMask | SubstructureNotifyMask, |
| 1334 | + &xev); |
| 1335 | +} |
0 commit comments