Unterschied zwischen GtkWindow und GdkWindow?

8

Am Anfang meiner App Gtk-Gdk-Cairo-Pango erstelle ich das Fenster:

%Vor%

Erstens gibt es GtkWindow , aber gtk_create_window gibt GtkWidget zurück, nicht GtkWindow , warum?

Dann benötigen einige Funktionen wie gdk_window_process_updates(..) GdkWindow* .

gtk_window_set_geometry_hints() erfordert andererseits GtkWindow* .

In der Dokumentation gibt es auch GdkWindow* gdk_window_new() , das GdkWindow zurückgibt.

Sicher gibt es eine Dokumentation, die sagt :

  

Ein GdkWindow ist eine rechteckige Region auf dem Bildschirm. Es ist ein Low-Level   Objekt, verwendet, um High-Level-Objekte wie GtkWidget und   GtkWindow auf der GTK + Ebene. Ein GtkWindow ist ein Toplevel-Fenster, das   etwas, was ein Benutzer sich als "Fenster" mit einer Titelleiste vorstellen könnte und so weiter; ein   GtkWindow kann viele GdkWindow enthalten.

Aber es sagt mir immer noch nicht, wann und warum Ich sollte Gtk- oder Gdk-Fenster erstellen? Was ist das Muster hier zu folgen?

Nun fragst du, welches spezielle Problem versuche ich zu lösen? Klar, ich versuche Text mit cairo + pango auf gtk + gdk zu zeichnen, direkt nach der Mausbewegung. Das Problem ist, dass, obwohl die tatsächliche Zeichnung scheint schnell zu sein, ich kann es nicht passieren, genau wie die Maus bewegt. In meinem motion_notify_event rufe ich einfach gtk_widget_queue_draw(GtkWidget) auf, aber es gibt offensichtlich eine Verzögerung hinter der eigentlichen Mausbewegung auf dem Bildschirm, selbst wenn ich ein einzelnes Zeichen zeichne, wird es während der Bewegungsphase nicht mit dem Mauszeiger ausgerichtet und fängt es nur nach der Maus ab gestoppt.

Was ich ausprobiert habe, ist, das Update zu beschleunigen, indem ich gdk_window_process_updates(GDK_WINDOW(window), false); aufruft, der Compiler isst es, aber ich habe Laufzeit-Assertion: Gdk-CRITICAL **: gdk_window_process_updates: assertion 'GDK_IS_WINDOW (window)' failed . Ich kann keine Informationen über dieses Makro finden und wie / wann es zu verwenden ist.

enthält

%Vor%     
exebook 16.12.2014, 22:22
quelle

2 Antworten

20

Fenstermanager (X11, Wayland, Windows user32.dll, und die in Mac OS X, deren Name ich nicht kenne) bieten nicht (unbedingt) viel Funktionalität für sich. Was sie dir geben, ist:

  • die Fähigkeit, Bildschirmbereiche zu erstellen, die windows genannt werden, auf denen Sie zeichnen, sich bewegen, Größe ändern, umformen, minimieren, hinter anderen Fenstern verstecken und auf andere einfache Weise steuern können - aber der wichtigste für unsere Diskussion ist "ziehe dich an"
  • Mausereignisbehandlung für Windows: Benachrichtigungen, wenn die Maus in ein Fenster oder aus einem Fenster heraus, innerhalb eines Fensters oder wenn die Mausschaltflächen angeklickt werden, wenn sich der Mauszeiger über einem Fenster befindet
  • das Konzept eines Fensters, das Tastatureingaben (das fokussierte Fenster ) und Tastaturereignisse für dieses Fenster erhält: wenn der Benutzer in ein Fenster tippt
  • verschiedene andere Funktionen (z. B. Mauszeiger zeichnen)

Kombiniert mit einer Möglichkeit, Vektorgrafiken und Text-Rendering in ein Fenster zu tun (das oft von anderen Bibliotheken wie Cairo und Pango bereitgestellt wird), kommt das GUI-Toolkit ins Spiel. Dadurch wird das Window-Manager-Fenster in alle kleinen Steuerelemente aufgeteilt, die Ihnen vertraut sind: Schaltflächen, Textfelder, Listen, Registerkarten, Webseiten-Renderer usw.

GTK + ist in diesem Fall das GUI-Toolkit. Es bietet eine Fülle von Steuerelementen, die Sie in Ihren Programmen verwenden.

Wenn Sie ein GUI-Toolkit verwenden, interagieren Sie normalerweise nicht direkt mit dem Fenstermanager. Stattdessen bietet das GUI-Toolkit ein eigenes Fenster. Wenn Sie ein GUI-Toolkit-Fenster erstellen, erstellt das GUI-Toolkit das zugrunde liegende Window-Manager-Fenster und übernimmt dann die Kontrolle über alle Zeichnungen und Ereignisse, so dass es die Aufgabe übernehmen kann, Ihnen alle Steuerelemente in diesem Fenster zur Verfügung zu stellen.

Für GTK + ist dies GtkWindow.

Die Designer von GTK + wollten nicht den gesamten Interaktionscode für den Fenstermanager für jede einzelne Plattform, die GTK + in GTK + selbst unterstützt, haben. Stattdessen erstellten sie eine separate Bibliothek (im Lieferumfang des GTK + Quellcodes enthalten), GDK genannt. GDK stellt eine konsistente portable API um die plattformspezifischen Low-Level-Fenstermanagerfunktionen bereit.

Also ist GdkWindow der Typ, der ein Fenstermanagerfenster umgibt und die portable Schnittstelle bereitstellt, die GTK + verwendet. Wenn Sie ein GdkWindow erstellen, erstellen Sie eines dieser Low-Level-Window-Manager-Fenster, nicht das umfangreichere GtkWindow, auf dem Sie die Steuerelemente platzieren.

X11 war historisch sehr restriktiv. GTK + erstellt kein Fenstermanagerfenster für jedes Steuerelement; Es erstellt nur diese für GtkWindow, GtkPopover und andere ähnliche Steuerelemente, die als das fungieren, was wir als Benutzer für Windows halten.

Mit all dem Wissen können Sie nun die Antwort auf Ihre Frage herausfinden: Sie wollen fast immer GtkWindow benutzen und fast nie GdkWindow benutzen. GdkWindow ist nur für die Implementierung bestimmter GTK + Steuerelemente wirklich nützlich.

Und GdkWindow und GtkWindow sind NICHT austauschbar.

(Dies ist eine immer noch ziemlich genaue Vereinfachung der Vorgänge. Dies gilt nicht für alle Umgebungen. Wer beispielsweise native Windows-Programme schreibt, erstellt im Allgemeinen do Fenstermanager-Fenster für jedes Steuerelement, und der Fenster-Manager bietet einige grundlegende Steuerelemente, wie zum Beispiel Schaltflächen. Ich habe auch einige Details in der obigen Erklärung falsch erhalten.)

Die Trennung zwischen GDK und GTK + hat auch einige andere Vorteile. Das Hinzufügen von Wayland-Unterstützung zum Beispiel hat nicht (soweit ich weiß; da könnte ich mich irren) viele Änderungen an GTK + selbst erfordern, und es gibt eine GDK-Schicht namens broadway , mit dem normale GTK + -Programme in einem Webbrowser gerendert werden können.

Updates, da ich das anscheinend sehr verlinke:

  • Es gab eine Zeit, in der die meisten GtkWidgets ihre eigenen GdkWindows hatten; hier ist was passiert . Nun, die Situation, die ich beschrieben habe, ist der Fall.
andlabs 16.12.2014 23:19
quelle
0

Es gibt so viele Fragen, die ich nicht beantworten werde.

Über die Latenz des Zeichnens: Die wahrscheinlichste Option ist, dass es einen Fehler oder nicht optimierten Code in Ihrer Implementierung gibt: Der Zeichenzyklus ist im Anwendungscode ziemlich einzigartig, da er wirklich, wirklich schnell sein muss ...

Zu beachten:

  • Sie rufen gtk_widget_queue_draw(window) von Ihrem Draw-Event-Handler auf: das scheint unnötig zu sein
  • Sie zeichnen immer ein Mausereignis neu, ohne zu prüfen, ob es wirklich notwendig ist (möglicherweise möchten Sie die Maus für alle Bewegungsereignisse in die Warteschlange stellen: Bitte stellen Sie dies jedoch sicher)
  • Sie zeichnen immer das gesamte Widget neu: Dies kann sehr teuer sein und Sie sollten es nicht tun, wenn Sie nur einen kleinen Bereich auf einmal ändern müssen und häufige Neuzeichnungen durchführen, wie Sie es sind. Siehe gtk_widget_queue_draw_region () .
  • Zeichnungs-Text kann teuer sein: Ich bin nicht vertraut mit den Funktionen, die Sie verwenden, aber Sie möchten vielleicht damit beginnen, nur eine Box oder etwas zu zeichnen, um zu sehen, wo das Problem ist
jku 17.12.2014 07:48
quelle

Tags und Links