|
64 | 64 | #include "trayicon.h"
|
65 | 65 | #include "shm-args.h"
|
66 | 66 | #include "util.h"
|
| 67 | +#include "unistd.h" |
67 | 68 | #include <qubes/pure.h>
|
68 | 69 |
|
69 | 70 | /* Supported protocol version */
|
@@ -385,7 +386,17 @@ static Window mkwindow(Ghandles * g, struct windowdata *vm_window)
|
385 | 386 | ButtonPressMask | ButtonReleaseMask |
|
386 | 387 | PointerMotionMask | EnterWindowMask | LeaveWindowMask |
|
387 | 388 | FocusChangeMask | StructureNotifyMask | PropertyChangeMask);
|
388 |
| - XSetWMProtocols(g->display, child_win, &g->wmDeleteMessage, 1); |
| 389 | + |
| 390 | + /* setting WM_CLIENT_MACHINE, _NET_WM_PID, _NET_WM_PING */ |
| 391 | + XSetWMClientMachine(g->display, child_win, &g->hostname); |
| 392 | + XChangeProperty(g->display, child_win, g->wm_pid, XA_CARDINAL, |
| 393 | + 32 /* bits */ , PropModeReplace, |
| 394 | + (unsigned char *) &g->pid, 1); |
| 395 | + Atom protocols[2]; |
| 396 | + protocols[0] = g->wmDeleteMessage; |
| 397 | + protocols[1] = g->wm_ping; |
| 398 | + XSetWMProtocols(g->display, child_win, protocols, 2); |
| 399 | + |
389 | 400 | if (g->icon_data) {
|
390 | 401 | XChangeProperty(g->display, child_win, g->net_wm_icon, XA_CARDINAL, 32,
|
391 | 402 | PropModeReplace, (unsigned char *) g->icon_data,
|
@@ -423,6 +434,7 @@ static Window mkwindow(Ghandles * g, struct windowdata *vm_window)
|
423 | 434 | 32, PropModeReplace,
|
424 | 435 | (const unsigned char *)&vm_window->remote_winid,
|
425 | 436 | 1);
|
| 437 | + |
426 | 438 | /* extra properties from command line */
|
427 | 439 | for (i = 0; i < MAX_EXTRA_PROPS; i++) {
|
428 | 440 | if (g->extra_props[i].prop) {
|
@@ -600,6 +612,8 @@ static void intern_global_atoms(Ghandles *const g) {
|
600 | 612 | { &g->wm_user_time, "_NET_WM_USER_TIME" },
|
601 | 613 | { &g->wmDeleteMessage, "WM_DELETE_WINDOW" },
|
602 | 614 | { &g->net_supported, "_NET_SUPPORTED" },
|
| 615 | + { &g->wm_pid, "_NET_WM_PID" }, |
| 616 | + { &g->wm_ping, "_NET_WM_PING" }, |
603 | 617 | };
|
604 | 618 | Atom labels[QUBES_ARRAY_SIZE(atoms_to_intern)];
|
605 | 619 | const char *names[QUBES_ARRAY_SIZE(atoms_to_intern)];
|
@@ -644,6 +658,14 @@ static bool qubes_get_all_atom_properties(Display *const display,
|
644 | 658 | * most of them are handles to local Xserver structures */
|
645 | 659 | static void mkghandles(Ghandles * g)
|
646 | 660 | {
|
| 661 | + char buf[256]; |
| 662 | + char *list[1] = { buf }; |
| 663 | + if (gethostname(buf, sizeof(buf)) == -1) { |
| 664 | + fprintf(stderr, "Cannot get GUIVM hostname!\n"); |
| 665 | + exit(1); |
| 666 | + } |
| 667 | + XStringListToTextProperty(list, 1, &g->hostname); |
| 668 | + g->pid = getpid(); |
647 | 669 | int ev_base, err_base; /* ignore */
|
648 | 670 | XWindowAttributes attr;
|
649 | 671 | int i;
|
@@ -2649,6 +2671,15 @@ static void process_xevent(Ghandles * g)
|
2649 | 2671 | (int) event_buffer.xclient.window);
|
2650 | 2672 | process_xevent_close(g,
|
2651 | 2673 | event_buffer.xclient.window);
|
| 2674 | + } else if ((Atom)event_buffer.xclient.data.l[0] == |
| 2675 | + g->wm_ping) { |
| 2676 | + XClientMessageEvent *ev = (XClientMessageEvent *) &event_buffer; |
| 2677 | + ev->window = g->root_win; |
| 2678 | + XSendEvent(g->display, g->root_win, False, |
| 2679 | + (SubstructureNotifyMask|SubstructureRedirectMask), |
| 2680 | + &event_buffer); |
| 2681 | + if (g->log_level > 1) |
| 2682 | + fprintf(stderr, "Received ping request from Window Manager\n"); |
2652 | 2683 | }
|
2653 | 2684 | break;
|
2654 | 2685 | default:;
|
@@ -4570,6 +4601,7 @@ static void get_boot_lock(int domid)
|
4570 | 4601 | }
|
4571 | 4602 |
|
4572 | 4603 | static void cleanup() {
|
| 4604 | + XFree(ghandles.hostname.value); |
4573 | 4605 | XCloseDisplay(ghandles.display);
|
4574 | 4606 | unset_alive_flag();
|
4575 | 4607 | close(ghandles.inter_appviewer_lock_fd);
|
|
0 commit comments