Xlib und Firefox Verhalten
Ich versuche, einen kleinen Fenstermanager zu erstellen (nur zum Spaß), aber ich habe Probleme beim Umgang mit von Firefox erstellten Fenstern (nur mit dieser Anwendung funktionieren andere Apps einwandfrei).
Das Problem ist, dass nach dem Starten von Firefox und dem Hinzufügen meiner Dekoration alles in Ordnung zu sein scheint. Wenn ich zum Beispiel versuche, auf die Menüschaltfläche zu klicken, wird das (Unter-) Fenster nicht angezeigt.
Was passiert, ist, dass nach dem Klicken ein ClientMessage-Ereignis mit den folgenden Werten ausgelöst wird:
Data: (null)
Data: _NET_WM_STATE_HIDDEN
Data: (null)
Data: (null)
Data: (null)
Nun, das Problem ist, dass ich nicht weiß, wie das Fenster angezeigt wird, welches Fenster. Ich habe versucht mit:
XRaiseWindow XMapWindow Ich habe versucht, das transiente Fenster abzurufen und es anzuzeigenAber ohne Erfolg. Was ich nicht verstehe, ist, ob diese Client-Nachricht vom Menü-Unterfenster generiert wird oder nicht.
Wie soll ich ein Fenster in _NET_WM_STATE_HIDDEN anzeigen?
Ein weiteres seltsames Problem ist, dass ich nach Erhalt der ClientMessage immer 2 UnMapNotify-Ereignisse erhalte.
Ich habe auch eine andere Frage, ob ich das Menü "Datei, Bearbeiten" anzeigen möchte (in Firefox wird es, wenn ich mich richtig erinnere, angezeigt, wenn Sie die Alt-Taste drücken.
Möglicherweise erstellt Firefox einen Baum von Fenstern?
Dies ist die Schleife, in der ich die Ereignisse behandle:
while(1){
XNextEvent(display, &local_event);
switch(local_event.type){
case ConfigureNotify:
configure_notify_handler(local_event, display);
break;
case MotionNotify:
motion_handler(local_event, display);
break;
case CreateNotify:
cur_win = local_event.xcreatewindow.window;
char *window_name;
XFetchName(display, cur_win, &window_name);
printf("Window name: %s\n", window_name);
if(window_name!=NULL){
if(!strcmp(window_name, "Parent")){
printf("Adding borders\n");
XSetWindowBorderWidth(display, cur_win, BORDER_WIDTH);
}
XFree(window_name);
}
break;
case MapNotify:
map_notify_handler(local_event,display, infos);
break;
case UnmapNotify:
printf("UnMapNotify\n");
break;
case DestroyNotify:
printf("Destroy Event\n");
destroy_notify_handler(local_event,display);
break;
case ButtonPress:
printf("Event button pressed\n");
button_handler(local_event, display, infos);
break;
case KeyPress:
printf("Keyboard key pressed\n");
keyboard_handler(local_event, display);
break;
case ClientMessage:
printf("------------ClientMessage\n");
printf("\tMessage: %s\n", XGetAtomName(display,local_event.xclient.message_type));
printf("\tFormat: %d\n", local_event.xclient.format);
Atom *atoms = (Atom *)local_event.xclient.data.l;
int i =0;
for(i=0; i<=5; i++){
printf("\t\tData %d: %s\n", i, XGetAtomName(display, atoms[i]));
}
int nchild;
Window *child_windows;
Window parent_window;
Window root_window;
XQueryTree(display, local_event.xclient.window, &root_window, &parent_window, &child_windows, &nchild);
printf("\tNumber of childs: %d\n", nchild);
break;
}
Jetzt in der Clientnachricht versuche ich nur, Informationen zu sammeln, um zu verstehen, was passiert. Und was ich aus dem obigen Code ersehen kann, ist, dass das Fenster, das das Ereignis ausgelöst hat, ein untergeordnetes Element enthält (wieder: ist das das Menü? Oder nicht?)
Der Code für das MapNotify-Ereignis, zu dem ich die Dekoration hinzufüge, lautet wie folgt:
void map_notify_handler(XEvent local_event, Display* display, ScreenInfos infos){
printf("----------Map Notify\n");
XWindowAttributes win_attr;
char *child_name;
XGetWindowAttributes(display, local_event.xmap.window, &win_attr);
XFetchName(display, local_event.xmap.window, &child_name);
printf("\tAttributes: W: %d - H: %d - Name: %s - ID %lu\n", win_attr.width, win_attr.height, child_name, local_event.xmap.window);
Window trans = None;
XGetTransientForHint(display, local_event.xmap.window, &trans);
printf("\tIs transient: %ld\n", trans);
if(child_name!=NULL){
if(strcmp(child_name, "Parent") && local_event.xmap.override_redirect == False){
Window new_win = draw_window_with_name(display, RootWindow(display, infos.screen_num), "Parent", infos.screen_num,
win_attr.x, win_attr.y, win_attr.width, win_attr.height+DECORATION_HEIGHT, 0,
BlackPixel(display, infos.screen_num));
XMapWindow(display, new_win);
XReparentWindow(display,local_event.xmap.window, new_win,0, DECORATION_HEIGHT);
set_window_item(local_event.xmap.window, new_win);
XSelectInput(display, local_event.xmap.window, StructureNotifyMask);
printf("\tParent window id: %lu\n", new_win);
put_text(display, new_win, child_name, "9x15", 10, 10, BlackPixel(display,infos.screen_num), WhitePixel(display, infos.screen_num));
}
}
XFree(child_name);
}
Jetzt kann mir jemand bei diesen Problemen helfen? Leider habe ich schon oft gegoogelt, aber ohne Erfolg.
usammenfassend sind meine Probleme zwei: 1. Anzeigen von Unterfenstern in Firefox 2. Anzeigen des Menüs "Datei", "Bearbeiten".
AKTUALISIERE
Ich habe etwas Merkwürdiges bemerkt, als ich Firefox mit xev getestet habe, um zu verstehen, welche Ereignisse ausgelöst wurden, um eine Anwendung anzuzeigen. Ich habe gesehen, dass Firefox in Unity und Firefox in einem anderen Fenster-Manager ganz andere Ereignisse auslösen. In Unity habe ich nur:
ClientMessage UnmapNotifyInstead mit Firefox, zum Beispiel mit xfce4, werden mehr xevents generiert:
VisiblityNotify (mehr als eine)Expose-Ereignis (mehr als eins)Aber wenn ich versuche, VisibilityChangeMask in meinem WM zu aktivieren, erhalte ich die folgenden Ereignisse:
ConfigureNotify ClientMessage MapNotify 2 UnMapNotifyUPDATE 2
Ich habe versucht, die XWMhints-Eigenschaften im ClientMessage-Fenster (wahrscheinlich im Menüfenster) zu lesen. Die Werte lauten:
Für die Flags 67 = InputHint, StateHint, WIndowGroupHint
Für den Ausgangszustand NormalState
UPDATE 3
Ich habe versucht herauszufinden, wie ein anderer Fenstermanager funktioniert, und habe mir den Quellcode von calmwm angesehen. Nach meinem Verständnis werden beim Eintreffen des ClientMessage-Ereignisses mit einer _NET_WM_STATE-Nachricht diese Eigenschaften aktualisiert, und im Fall von _NET_WM_STATE_HIDDEN wird diese Eigenschaft gelöscht, und die Eigenschaft wird gelöscht. Also habe ich versucht, meinen Code zu aktualisieren, um diese Eigenschaft zu löschen, aber es funktioniert immer noch nicht. Der relevante aktualisierte Code in client_message_handler sieht jetzt sowieso so aus:
Atom *atoms = (Atom *)local_event.xclient.data.l;
int i =0;
for(i=0; i<=5; i++){
printf("\t\tData %d: %s\n", i, XGetAtomName(display, atoms[i]));
if(i==1){
printf("\t Deleting Property: _NET_WM_STATE_HIDDEN \n");
XDeleteProperty(display, cur_window, atoms[i]);
}
}
Es ist nur ein Test und ich bin sicher, dass i = 1 in meinem Fall die Eigenschaft _NET_WM_STATE_HIDDEN ist.
Hier ein Link zum Quellcode von calmwm:https: //github.com/chneukirchen/cwm/blob/linux/xevents.
So bin ich noch an diesem Punkt fest.
UPDATE 4
Wirklich weiß ich nicht, ob es hilft, aber ich habe versucht, die Fensterattribute im MapNotify-Ereignis zu lesen, und das Fenster map_state ist IsViewable (2).
UPDATE 5
Ich habe hier in SO ein ähnliches Problem gefunden, bei Verwendung von xlib mit Python:Xlib Python: Firefox-Menüs können nicht zugeordnet werden
Die Lösung schlägt die Verwendung von XSetInputFocus vor. Ich habe Folgendes auf meinem XMapNotify-Handler versucht:
XSetInputFocus(display, local_event.xmap.window, RevertToParent, CurrentTime);
Aber es hilft immer noch nicht, das Firefox-Menü wird immer noch nicht angezeigt !! Und ich habe das gleiche Problem mit der rechten Maustaste.
UPDATE 6
Playing mit xconfigurenotify-Ereignis und Unmap-Ereignis fand ich, dass die: Xconfigure-Anforderung 2 Fensterfelder hat: Fenster und höher, und wenn der Wert xconfigurerequest.window der gleiche wie der Wert xunmap.window ist.
Und außerdem ändert sich die Datei xconfigurerequest.above ständig, aber xconfigurerequest.window ist bei allen Ereignissen immer gleich.
Es scheint, dass die xconfigurerequest.above mit dem Menü zusammenhängt, das ich öffnen möchte. Beispielsweise
wenn ich mit der rechten Maustaste auf eine Seite klicke, erhalte ich eine ID (immer die gleiche für jeden nachfolgenden Klick)wenn ich mit der rechten Maustaste auf einen Tab klicke, ist der obige Wert ein andererund das gleiche passiert, wenn ich mit der linken Maustaste auf das Firefox-Hauptmenü klickeNoch nicht, ob das hilft.
Wirklich nicht wissen, dass jemand eine Idee hat?