So bin ich in einer Situation, wo ich wissen muss, wenn ein Top-Level-Fenster erstellt wird. Ich arbeite auf der Xlib/Xt-Ebene und in einem Window Manager, der die EWMH-Spezifikation nicht unterstützt. Meine Idee ist es, sich in die SubstructionNotify-Events des Root-Fensters einzuklinken. Aber die Dinge sind nicht so einfach wie nur das.Handle "neue Top-Level-Fenster" Ereignisse in Xlib/Xt
Das Problem ist, dass nicht jedes CreateNotify -Ereignis der Erstellung eines [b] Top-Level [/ b] -Fensters entspricht. Also denke ich, dass ich das Fenster, das ich vom Event bekomme, irgendwie testen muss, um zu bestätigen, dass es ein Top-Level-Fenster ist. Ich bin nahe dran, aber ein paar falsche Fenster schaffen es immer noch durch mein Netz. Wenn Sie zum Beispiel in einer GTK-Anwendung eine Dropdown-Box haben und darauf klicken, wird ein neues Fenster erstellt, in dem ich nicht herausfinden kann, wie man fängt und ignoriert. Ein solches Fenster ist von einem typischen Anwendungsfenster der obersten Ebene nicht zu unterscheiden.
Hier ist, was ich bisher:
// I am omiting (tons of) cleanup code and where I set the display and toplevel variables.
Display* display;
Widget toplevel;
bool has_name(Window window)
{
XTextProperty data = XTextProperty();
return (!XGetWMName (display, window, &data));
}
bool has_client_leader(Window window)
{
unsigned long nitems = 0;
unsigned char* data = 0;
Atom actual_type;
int actual_format;
unsigned long bytes;
// WM_CLIENT_LEADER is an interned Atom for the WM_CLIENT_LEADER property
int status = XGetWindowProperty (display, window, WM_CLIENT_LEADER, 0L, (~0L), False,
AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes, &data);
if (status != Success || acutal_type == None) return false;
Window* leader = reinterpret_cast<Window*> (data);
return (*leader != 0);
}
bool has_class(Window window)
{
XClassHint data = XClassHint();
return (!GetClassHint (display, window, &data));
}
void handle_event(Widget widget, XtPointer, XEvent* event, Boolean*)
{
if (event->type != CreateNotify) return;
Window w = event->xcreatewindow.window;
// confirm window has a name
if (!has_name (w)) return;
// confirm window is a client window
Window client = XmuClientWindow (display, w);
if (!client || client != w) return;
// confirm window has a client leader that is not 0x0
if (!has_client_leader (client)) return;
// confirm window has a class
if (!has_class (client)) return;
// The window has passed all our checks!
// Go on to do stuff with the window ...
}
int main(int argc, char* argv[])
{
// ...
// Setting up the event handler for SubstructureNotify on root window
Window root_window = XDefaultRootWindow (display);
Widget dummy = XtCreateWidget ("dummy", coreWidgetClass, toplevel, 0, 0);
XtRegisterDrawable (display, root_window, dummy);
XSelectInput (display, root_window, SubstructureNotifyMask);
XtAddRawEventHandler (dummy, SubstructureNotifyMask, False, handle_event, 0);
// ...
}
Ein langer Schuss, aber hat jemand irgendwelche Ideen, die ich versuchen könnte? Ich kann mir nicht viel mehr vorstellen, was ich hier wirklich tun kann.
An welchem Fenstermanager arbeiten Sie? Warum implementierst du EWMH nicht? – Zifre