gtkwindow toplevel erase background event abfangen



  • Ich habe ein Fenster erstellt mit:

    GtkWidget *window;
    ...
    window = gtk_window_new( GTK_WINDOW_TOPLEVEL);
    

    Es gibt auch eine Funktion welche das expose_event abfängt. Das Fenster zeichnet davor immer seinen Hintergrund weiß. In Win32 kann ich das WM_ERASEBKGND event abfangen um das zu verhindern.

    Wie kann ich das Gleiche in Gtk erreichen.

    Danke

    Georg



  • Habt ihr wenigstens einen Tip?

    Ich habe gdk_window_set_back_pixmap (window->window, NULL, TRUE);
    versucht. Der einzige Unterschied ist jetzt, dass der Hintergrund schwarz gezeichnet wird.

    Bitte um Hilfe.

    Danke

    Georg



  • .. mehr schildern.
    Kannst Du vielleicht ein Code-Beispiel posten? Und vor allem was willst Du genau machen?
    Gruss



  • Das Projekt ist ein bestehendes Projekt und wurde von Windows auf Linux portiert.
    Auf der Linux Seite gibt es nur ein Widget ein GTK_WINDOW_TOPLEVEL Window.
    Es gibt eigene Screens und eigene Buttons nichts von GTK oder GDK.
    Man kann hier leider nichts verändern.
    Im Bild gibt es das Window mit einem Screen below. Dieser besitzt einen Button mit xxoo gekennzeichnet.
    Über diesem liegt ein weiterer Screen. Vom Button ist xx zu sehen und oo ist vom Darüberliegenden verdeckt.
    Es wird wenn man auf den Button klickt ein gtk_widget_queue_draw_area
    auf den Bereich des Button Rechtecks aufgerufen. Hier liegt nun das Problem, dass im expose_event der
    Hintergrund entweder weiß gezeichnet wird, oder wenn man gdk_window_set_back_pixmap (window->window, NULL, TRUE);
    die Pixmap auf NULL setzt der Hintergrund des Button schwarz gezeichnet wird. Richtig wäre es, den Hintergrund
    nicht zu übermalen.
    Ich habe herausgefunden, wenn ich das double buffering ausschaltet gtk_widget_set_double_buffered (window,FALSE);
    funktioniert es wie gewollt, aber das soll vermieden werden.

    Window
    -----------------------------------
    | Screen below |
    | --------------------- |
    | |Custom Screen | |
    | | | |
    | | | |
    | |xx|oo| | |
    | |xx|oo| | |
    | |____________________| |
    | |
    -----------------------------------

    Danke
    Georg



  • Window
    -----------------------------------
    | Screen below                    |
    |     ---------------------       |
    |     |Custom Screen       |      |
    |     |                    |      |
    |   __|__                  |      |
    |  |xx|oo|                 |      |
    |  |xx|oo|                 |      |
    |     |____________________|      |
    |                                 |
    -----------------------------------
    


  • Ich habe eigentlich mit eigenen Widgets wenig zu tun, aber hier vielleicht ein hilfreicher Link:
    http://people.gnome.org/~federico/misc/gtk-drawing-model/index.html
    Gruss



  • Danke, leider hilft das nicht weiter. 😞

    Georg



  • Um das Zeichnen des Hintergrunds zu umgehen, versuche ich die Callback Funktionen des Window und des Style umzubiegen.

    GtkWindowClass *klass = GTK_WINDOW_GET_CLASS (widget);
    GtkWidgetClass *widget_class;
    widget_class = (GtkWidgetClass*) klass;
    widget_class->expose_event = my_gtk_window_expose;
    
    GtkStyleClass *gtkStyle=NULL;
    gtkStyle = GTK_STYLE_GET_CLASS (gtk_widget_get_style(widget));
    gtkStyle->draw_focus = my_gtk_default_draw_focus;
    gtkStyle->draw_flat_box = my_gtk_default_draw_flat_box;
    gtkStyle->set_background = my_gtk_style_real_set_background;
    

    Leider werden meine Funktionen nicht aufgerufen. Kann mir hiebei jemand helfen.

    Danke

    Georg



  • Ich habe die Lösung gefunden.

    1. Double buffering ausschalten
    2. Eigenes double buffering im expose_event
    // 
    static gboolean expose_event( GtkWidget *widget, GdkEventExpose *event )
    {
    
    	LRect r( event->area.x, event->area.y,event->area.x + event->area.width, event->area.y + event->area.height);
    	LDC DevContext;
    
    	static cairo_surface_t *imagesurface=NULL; /* Puffer */
    	/* Den Hintergrund-Puffer einrichten mit der Größe des Fensters:  */
    	imagesurface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 480);
    	//imagesurface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, r.Width(), r.Height());
    	/* Drawing Context holen */
    
    	cairo_t* pCC = gdk_cairo_create(widget->window);
    	cairo_t *crimage = cairo_create(imagesurface);
    	DevContext.m_pCC= crimage;
    
    // hier kommt das eigene Zeichnen rein
    
    	/* Und das vorbereitete Image in das Fenster kopieren */
    	cairo_set_source_surface(pCC, imagesurface, 0, 0);
    	//cairo_set_source_surface(pCC, imagesurface, event->area.x, event->area.y);
    	cairo_paint(pCC);
    	/* Hintergrund-Puffer loeschen */
    	cairo_set_source_rgb(crimage, 1, 1, 1);
    	//cairo_rectangle(crimage, 0, 0, r.Width(), r.Height());
    	cairo_rectangle(crimage, 0, 0, 800, 480);
    	cairo_fill(crimage);
    	cairo_set_source_rgb(crimage, 0, 0, 0);
    
    	cairo_destroy(crimage);
    	cairo_destroy(pCC);
    	cairo_surface_destroy(imagesurface);
    
      return TRUE;
    }
    

Anmelden zum Antworten