Some make corrections for HP and related,

Changed refresh order so that window-less widgets
    don't get overdrawn anymore,
  Prevent GTK from filtering our supposedly unneeded
    expose events,
  Block all expose calls if a resize is requested and
    do a full redraw then, thus removing flicker and
    behaving like wxMSW,
  Moved some doubled expose and draw code from GtkPizza
    to the respective callbacks in window.cpp,
  Set idle priority to a higher value (which should
    indicate a lower priority if I interpret glib.h
    correctly) but the desired side-effect didn't
    really show up.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6533 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2000-03-09 13:24:34 +00:00
parent 6da3a3ef1f
commit b6fa52db66
21 changed files with 557 additions and 350 deletions

View File

@@ -751,6 +751,7 @@ SAMPLES_DIST: ALL_GUI_DIST
cp $(SAMPDIR)/drawing/makefile.unx $(DISTDIR)/samples/drawing
cp $(SAMPDIR)/drawing/*.cpp $(DISTDIR)/samples/drawing
cp $(SAMPDIR)/drawing/*.xpm $(DISTDIR)/samples/drawing
cp $(SAMPDIR)/drawing/*.bmp $(DISTDIR)/samples/drawing
mkdir $(DISTDIR)/samples/dynamic
cp $(SAMPDIR)/dynamic/Makefile.in $(DISTDIR)/samples/dynamic
@@ -806,6 +807,7 @@ SAMPLES_DIST: ALL_GUI_DIST
cp $(SAMPDIR)/html/test/*.cpp $(DISTDIR)/samples/html/test
cp $(SAMPDIR)/html/test/*.bmp $(DISTDIR)/samples/html/test
cp $(SAMPDIR)/html/test/*.png $(DISTDIR)/samples/html/test
cp $(SAMPDIR)/html/test/*.gif $(DISTDIR)/samples/html/test
cp $(SAMPDIR)/html/test/*.htm $(DISTDIR)/samples/html/test
cp $(SAMPDIR)/html/test/*.html $(DISTDIR)/samples/html/test
mkdir $(DISTDIR)/samples/html/virtual
@@ -839,10 +841,10 @@ SAMPLES_DIST: ALL_GUI_DIST
cp $(SAMPDIR)/internat/*.xpm $(DISTDIR)/samples/internat
cp $(SAMPDIR)/internat/*.txt $(DISTDIR)/samples/internat
cp $(SAMPDIR)/internat/*.po $(DISTDIR)/samples/internat
cp $(SAMPDIR)/internat/fr/*.po $(DISTDIR)/samples/internat/fr
cp $(SAMPDIR)/internat/fr/*.mo $(DISTDIR)/samples/internat/fr
cp $(SAMPDIR)/internat/de/*.mo $(DISTDIR)/samples/internat/de
cp $(SAMPDIR)/internat/fr/*.po $(DISTDIR)/samples/internat/fr
cp $(SAMPDIR)/internat/de/*.mo $(DISTDIR)/samples/internat/de
cp $(SAMPDIR)/internat/de/*.po $(DISTDIR)/samples/internat/de
mkdir $(DISTDIR)/samples/ipc
cp $(SAMPDIR)/ipc/Makefile.in $(DISTDIR)/samples/ipc

View File

@@ -51,6 +51,7 @@ dnl
#include <gtk/gtk.h>
#include <gtk/gtkfeatures.h>
#include <stdio.h>
#include <stdlib.h>
int
main ()

View File

@@ -33,9 +33,19 @@ typedef enum
GTK_MYSHADOW_OUT
} GtkMyShadowType;
typedef struct _GtkPizzaChild GtkPizzaChild;
typedef struct _GtkPizza GtkPizza;
typedef struct _GtkPizzaClass GtkPizzaClass;
struct _GtkPizzaChild
{
GtkWidget *widget;
gint x;
gint y;
gint width;
gint height;
};
struct _GtkPizza
{
GtkContainer container;

View File

@@ -186,6 +186,8 @@ public:
bool m_isFrame:1; /* faster than IS_KIND_OF */
bool m_acceptsFocus:1; /* not wxStaticBox, not wxStaticBitmap etc. */
bool m_isScrolling;
bool m_clipPaintRegion; /* TRUE after ScrollWindow() */
bool m_queuedFullRedraw; /* TRUE after DoMoveWindow */
// these are true if the style were set before the widget was realized
// (typcally in the constructor) but the actual GTK style must not be set

View File

@@ -33,9 +33,19 @@ typedef enum
GTK_MYSHADOW_OUT
} GtkMyShadowType;
typedef struct _GtkPizzaChild GtkPizzaChild;
typedef struct _GtkPizza GtkPizza;
typedef struct _GtkPizzaClass GtkPizzaClass;
struct _GtkPizzaChild
{
GtkWidget *widget;
gint x;
gint y;
gint width;
gint height;
};
struct _GtkPizza
{
GtkContainer container;

View File

@@ -186,6 +186,8 @@ public:
bool m_isFrame:1; /* faster than IS_KIND_OF */
bool m_acceptsFocus:1; /* not wxStaticBox, not wxStaticBitmap etc. */
bool m_isScrolling;
bool m_clipPaintRegion; /* TRUE after ScrollWindow() */
bool m_queuedFullRedraw; /* TRUE after DoMoveWindow */
// these are true if the style were set before the widget was realized
// (typcally in the constructor) but the actual GTK style must not be set

View File

@@ -128,7 +128,7 @@ enum
Minimal_Test2,
// controls start here (the numbers are, of course, arbitrary)
Minimal_Text = 1000,
Minimal_Text = 1000
};
// ----------------------------------------------------------------------------

View File

@@ -127,7 +127,7 @@ enum
HelpDemo_Help_GNOME,
HelpDemo_Help_Netscape,
// controls start here (the numbers are, of course, arbitrary)
HelpDemo_Text = 1000,
HelpDemo_Text = 1000
};
// ----------------------------------------------------------------------------

View File

@@ -74,7 +74,7 @@
Minimal_Forward,
// controls start here (the numbers are, of course, arbitrary)
Minimal_Text = 1000,
Minimal_Text = 1000
};
// ----------------------------------------------------------------------------

View File

@@ -75,7 +75,7 @@
Minimal_Forward,
// controls start here (the numbers are, of course, arbitrary)
Minimal_Text = 1000,
Minimal_Text = 1000
};
// ----------------------------------------------------------------------------

View File

@@ -928,9 +928,11 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
Centre( wxBOTH );
/*
if (m_fileName.IsEmpty())
m_list->SetFocus();
else
*/
m_text->SetFocus();
wxEndBusyCursor();

View File

@@ -95,8 +95,8 @@ bool wxYield()
if (has_idle)
{
/* re-add idle handler */
wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
/* re-add idle handler (very low priority) */
wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL );
}
// disable log flushing from here because a call to wxYield() shouldn't
@@ -177,9 +177,9 @@ void wxapp_install_idle_handler()
indicating that the idle is over. It may also
get called from other thread for sending events
to the main thread (and processing these in
idle time). */
idle time). Very low priority. */
wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL );
g_isIdle = FALSE;
}

View File

@@ -2020,6 +2020,9 @@ wxPaintDC::wxPaintDC( wxWindow *win )
: wxWindowDC( win )
{
#if USE_PAINT_REGION
if (!win->m_clipPaintRegion)
return;
m_paintClippingRegion = win->GetUpdateRegion();
m_currentClippingRegion.Union( m_paintClippingRegion );

View File

@@ -834,6 +834,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
gtk_pizza_set_size( GTK_PIZZA(m_wxwindow),
m_frameStatusBar->m_widget,
xx, yy, ww, hh );
gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL );
}
#endif

View File

@@ -30,7 +30,6 @@ extern "C" {
(y >= G_MINSHORT) && (y <= G_MAXSHORT))
typedef struct _GtkPizzaAdjData GtkPizzaAdjData;
typedef struct _GtkPizzaChild GtkPizzaChild;
struct _GtkPizzaAdjData
{
@@ -38,15 +37,6 @@ struct _GtkPizzaAdjData
gint dy;
};
struct _GtkPizzaChild
{
GtkWidget *widget;
gint x;
gint y;
gint width;
gint height;
};
static void gtk_pizza_class_init (GtkPizzaClass *klass);
static void gtk_pizza_init (GtkPizza *pizza);
@@ -200,7 +190,7 @@ gtk_pizza_init (GtkPizza *pizza)
pizza->visibility = GDK_VISIBILITY_PARTIAL;
pizza->clear_on_draw = TRUE;
pizza->use_filter = FALSE;
pizza->use_filter = TRUE;
}
GtkWidget*
@@ -662,68 +652,15 @@ static void
gtk_pizza_draw (GtkWidget *widget,
GdkRectangle *area)
{
GtkPizza *pizza;
GtkPizzaChild *child;
GdkRectangle child_area;
GList *children;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_PIZZA (widget));
pizza = GTK_PIZZA (widget);
children = pizza->children;
if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) &&
(pizza->clear_on_draw))
{
gdk_window_clear_area( pizza->bin_window,
area->x, area->y, area->width, area->height);
}
while (children)
{
child = children->data;
children = children->next;
if (gtk_widget_intersect (child->widget, area, &child_area))
gtk_widget_draw (child->widget, &child_area);
}
/* We handle all draws events in window.cpp now. */
return;
}
static gint
gtk_pizza_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GtkPizza *pizza;
GtkPizzaChild *child;
GdkEventExpose child_event;
GList *children;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
pizza = GTK_PIZZA (widget);
if (event->window != pizza->bin_window)
return FALSE;
children = pizza->children;
while (children)
{
child = children->data;
children = children->next;
child_event = *event;
if (GTK_WIDGET_NO_WINDOW (child->widget) &&
GTK_WIDGET_DRAWABLE (child->widget) &&
gtk_widget_intersect (child->widget, &event->area, &child_event.area))
{
gtk_widget_event (child->widget, (GdkEvent*) &child_event);
}
}
/* We handle all expose events in window.cpp now. */
return FALSE;
}
@@ -1166,6 +1103,9 @@ gtk_pizza_filter (GdkXEvent *gdk_xevent,
pizza = GTK_PIZZA (data);
if (!pizza->use_filter)
return GDK_FILTER_CONTINUE;
switch (xevent->type)
{
case Expose:
@@ -1211,6 +1151,9 @@ gtk_pizza_main_filter (GdkXEvent *gdk_xevent,
xevent = (XEvent *)gdk_xevent;
pizza = GTK_PIZZA (data);
if (!pizza->use_filter)
return GDK_FILTER_CONTINUE;
if (xevent->type == VisibilityNotify)
{
switch (xevent->xvisibility.state)

View File

@@ -381,10 +381,13 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
// "expose_event" of m_widget
//-----------------------------------------------------------------------------
static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
{
if (gdk_event->count > 0) return;
if (gdk_event->count > 0) return FALSE;
draw_frame( widget, win );
return TRUE;
}
//-----------------------------------------------------------------------------
@@ -610,12 +613,18 @@ static long map_to_wx_keysym( KeySym keysym )
// "expose_event" of m_wxwindow
//-----------------------------------------------------------------------------
static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
if (win->m_queuedFullRedraw)
return TRUE;
/*
if (win->GetName() == wxT("grid window"))
if (win->GetName() == wxT("htmlWindow"))
{
wxPrintf( wxT("OnExpose from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
@@ -634,10 +643,7 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
if (gdk_event->count > 0)
return;
if (!win->m_hasVMT)
return;
return TRUE;
wxEraseEvent eevent( win->GetId() );
eevent.SetEventObject( win );
@@ -648,25 +654,85 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
/* The following code will result in all window-less widgets
being redrawn if the wxWindows class is given a chance to
paint *anything* because it will then be allowed to paint
over the window-less widgets */
GtkPizza *pizza = GTK_PIZZA (widget);
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkEventExpose child_event = *gdk_event;
if (GTK_WIDGET_NO_WINDOW (child->widget) &&
GTK_WIDGET_DRAWABLE (child->widget))
{
child_event.area.x = child->widget->allocation.x;
child_event.area.y = child->widget->allocation.y;
child_event.area.width = child->widget->allocation.width;
child_event.area.height = child->widget->allocation.height;
gtk_widget_event (child->widget, (GdkEvent*) &child_event);
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
// "event" of m_wxwindow
//-----------------------------------------------------------------------------
/* GTK thinks it is clever and filters out a certain amount of "unneeded"
expose events. We need them, of course, so we override the main event
procedure in GtkWidget by giving our own handler for all system events,
looking for the expose events and then we can always send them. */
gint gtk_window_event_event_callback( GtkWidget *widget, GdkEventExpose *event, wxWindow *win )
{
if (event->type == GDK_EXPOSE)
{
gint ret = gtk_window_expose_callback( widget, event, win );
return ret;
}
return FALSE;
}
//-----------------------------------------------------------------------------
// "draw" of m_wxwindow
//-----------------------------------------------------------------------------
static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
GdkRectangle *rect, wxWindow *win )
/* This callback is a complete replacement of the gtk_pizza_draw() function,
which disabled. */
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
if ((rect->x == 0) && (rect->y == 0) && (rect->width <= 1) && (rect->height <= 1))
if (win->m_queuedFullRedraw)
return;
GtkPizza *pizza = GTK_PIZZA (widget);
if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) &&
(pizza->clear_on_draw))
{
gdk_window_clear_area( pizza->bin_window,
rect->x, rect->y, rect->width, rect->height);
}
/*
if (win->GetName() == wxT("grid window"))
if (win->GetName() == wxT("htmlWindow"))
{
wxPrintf( wxT("OnDraw from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
@@ -681,9 +747,6 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
win->GetUpdateRegion().Union( rect->x, rect->y,
rect->width, rect->height );
if (!win->m_hasVMT)
return;
wxEraseEvent eevent( win->GetId() );
eevent.SetEventObject( win );
win->GetEventHandler()->ProcessEvent(eevent);
@@ -693,6 +756,17 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkRectangle child_area;
if (gtk_widget_intersect (child->widget, rect, &child_area))
gtk_widget_draw (child->widget, (GdkRectangle*) NULL );
}
}
//-----------------------------------------------------------------------------
@@ -1974,6 +2048,9 @@ void wxWindow::Init()
m_isFrame = FALSE;
m_acceptsFocus = FALSE;
m_clipPaintRegion = FALSE;
m_queuedFullRedraw = FALSE;
m_cursor = *wxSTANDARD_CURSOR;
#ifdef HAVE_XIM
@@ -2012,17 +2089,8 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
#ifdef __WXDEBUG__
debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name );
#endif
GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
#ifdef __WXDEBUG__
debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name );
debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name );
#endif
GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
scroll_class->scrollbar_spacing = 0;
@@ -2033,10 +2101,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
m_wxwindow = gtk_pizza_new();
#ifdef __WXDEBUG__
debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name );
#endif
gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
#if (GTK_MINOR_VERSION > 0)
@@ -2221,6 +2285,9 @@ void wxWindow::PostCreation()
if (!m_noExpose)
{
/* these get reported to wxWindows -> wxPaintEvent */
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event",
GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this );
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
@@ -2320,6 +2387,24 @@ bool wxWindow::Destroy()
void wxWindow::DoMoveWindow(int x, int y, int width, int height)
{
if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window)
{
/* Normally, GTK will send expose events only for the regions
which actually got exposed. Sadly, wxMSW invalidates
the whole window so we have to do that, too. We could
simply add a complete refresh, but we would then get
the normal GTK expose events in surplus, so we shut
off the expose events and schedule a full redraw to
be done in OnInternalIdle, where we restore the handling
of expose events. */
m_queuedFullRedraw = TRUE;
GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window );
mask = (GdkEventMask)(mask & ~GDK_EXPOSURE_MASK);
gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask );
}
gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height );
}
@@ -2391,6 +2476,12 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
if (m_hasScrolling)
{
/* Sometimes the client area changes size without the
whole windows's size changing, but if the whole
windows's size doesn't change, no wxSizeEvent will
normally be sent. Here we add an extra test if
the client test has been changed and this will
be used then. */
GetClientSize( &m_oldClientWidth, &m_oldClientHeight );
}
@@ -2461,6 +2552,27 @@ void wxWindow::OnInternalIdle()
}
UpdateWindowUI();
if (m_queuedFullRedraw)
{
/* See also wxWindow::DoMoveWindow for explanation of this code. What
we test here is if the requested size of the window is the same as
the actual size of window, in which case all expose events that resulted
from resizing the window have been sent (and discarded) and we can
now do our full redraw and switch on expose event handling again. */
if ((m_width == m_widget->allocation.width) && (m_height == m_widget->allocation.height))
{
m_queuedFullRedraw = FALSE;
m_updateRegion.Clear();
m_updateRegion.Union( 0,0,m_width,m_height );
gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window );
mask = (GdkEventMask)(mask | GDK_EXPOSURE_MASK);
gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask );
}
}
}
void wxWindow::DoGetSize( int *width, int *height ) const
@@ -2898,16 +3010,55 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
{
if (m_wxwindow)
{
/*
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
gboolean old_clear = pizza->clear_on_draw;
gtk_pizza_set_clear( pizza, FALSE );
gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
gtk_pizza_set_clear( pizza, old_clear );
*/
GdkEventExpose gdk_event;
gdk_event.count = 0;
gdk_event.area.x = 0;
gdk_event.area.y = 0;
gdk_event.area.width = m_wxwindow->allocation.width;
gdk_event.area.height = m_wxwindow->allocation.height;
gtk_window_expose_callback( m_wxwindow, &gdk_event, this );
}
else
{
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
}
}
else
{
if (m_wxwindow)
{
/*
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
gboolean old_clear = pizza->clear_on_draw;
gtk_pizza_set_clear( pizza, FALSE );
gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
GdkRectangle gdk_rect;
gdk_rect.x = rect->x;
gdk_rect.y = rect->y;
gdk_rect.width = rect->width;
gdk_rect.height = rect->height;
gtk_widget_draw( m_wxwindow, &gdk_rect );
gtk_window_draw_callback( m_wxwindow, &gdk_rect, this );
gtk_pizza_set_clear( pizza, old_clear );
}
else
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
*/
GdkEventExpose gdk_event;
gdk_event.count = 0;
gdk_event.area.x = rect->x;
gdk_event.area.y = rect->y;
gdk_event.area.width = rect->width;
gdk_event.area.height = rect->height;
gtk_window_expose_callback( m_wxwindow, &gdk_event, this );
}
else
{
@@ -2916,21 +3067,10 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
gdk_rect.y = rect->y;
gdk_rect.width = rect->width;
gdk_rect.height = rect->height;
if (m_wxwindow)
{
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
gboolean old_clear = pizza->clear_on_draw;
gtk_pizza_set_clear( pizza, FALSE );
gtk_widget_draw( m_wxwindow, &gdk_rect );
gtk_pizza_set_clear( pizza, old_clear );
}
else
gtk_widget_draw( m_widget, &gdk_rect );
}
}
}
void wxWindow::Clear()
{
@@ -3452,7 +3592,9 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
if ((dx == 0) && (dy == 0)) return;
m_clipPaintRegion = TRUE;
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
m_clipPaintRegion = FALSE;
/*
if (m_children.GetCount() > 0)

View File

@@ -95,8 +95,8 @@ bool wxYield()
if (has_idle)
{
/* re-add idle handler */
wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
/* re-add idle handler (very low priority) */
wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL );
}
// disable log flushing from here because a call to wxYield() shouldn't
@@ -177,9 +177,9 @@ void wxapp_install_idle_handler()
indicating that the idle is over. It may also
get called from other thread for sending events
to the main thread (and processing these in
idle time). */
idle time). Very low priority. */
wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL );
g_isIdle = FALSE;
}

View File

@@ -2020,6 +2020,9 @@ wxPaintDC::wxPaintDC( wxWindow *win )
: wxWindowDC( win )
{
#if USE_PAINT_REGION
if (!win->m_clipPaintRegion)
return;
m_paintClippingRegion = win->GetUpdateRegion();
m_currentClippingRegion.Union( m_paintClippingRegion );

View File

@@ -834,6 +834,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
gtk_pizza_set_size( GTK_PIZZA(m_wxwindow),
m_frameStatusBar->m_widget,
xx, yy, ww, hh );
gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL );
}
#endif

View File

@@ -30,7 +30,6 @@ extern "C" {
(y >= G_MINSHORT) && (y <= G_MAXSHORT))
typedef struct _GtkPizzaAdjData GtkPizzaAdjData;
typedef struct _GtkPizzaChild GtkPizzaChild;
struct _GtkPizzaAdjData
{
@@ -38,15 +37,6 @@ struct _GtkPizzaAdjData
gint dy;
};
struct _GtkPizzaChild
{
GtkWidget *widget;
gint x;
gint y;
gint width;
gint height;
};
static void gtk_pizza_class_init (GtkPizzaClass *klass);
static void gtk_pizza_init (GtkPizza *pizza);
@@ -200,7 +190,7 @@ gtk_pizza_init (GtkPizza *pizza)
pizza->visibility = GDK_VISIBILITY_PARTIAL;
pizza->clear_on_draw = TRUE;
pizza->use_filter = FALSE;
pizza->use_filter = TRUE;
}
GtkWidget*
@@ -662,68 +652,15 @@ static void
gtk_pizza_draw (GtkWidget *widget,
GdkRectangle *area)
{
GtkPizza *pizza;
GtkPizzaChild *child;
GdkRectangle child_area;
GList *children;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_PIZZA (widget));
pizza = GTK_PIZZA (widget);
children = pizza->children;
if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) &&
(pizza->clear_on_draw))
{
gdk_window_clear_area( pizza->bin_window,
area->x, area->y, area->width, area->height);
}
while (children)
{
child = children->data;
children = children->next;
if (gtk_widget_intersect (child->widget, area, &child_area))
gtk_widget_draw (child->widget, &child_area);
}
/* We handle all draws events in window.cpp now. */
return;
}
static gint
gtk_pizza_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GtkPizza *pizza;
GtkPizzaChild *child;
GdkEventExpose child_event;
GList *children;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
pizza = GTK_PIZZA (widget);
if (event->window != pizza->bin_window)
return FALSE;
children = pizza->children;
while (children)
{
child = children->data;
children = children->next;
child_event = *event;
if (GTK_WIDGET_NO_WINDOW (child->widget) &&
GTK_WIDGET_DRAWABLE (child->widget) &&
gtk_widget_intersect (child->widget, &event->area, &child_event.area))
{
gtk_widget_event (child->widget, (GdkEvent*) &child_event);
}
}
/* We handle all expose events in window.cpp now. */
return FALSE;
}
@@ -1166,6 +1103,9 @@ gtk_pizza_filter (GdkXEvent *gdk_xevent,
pizza = GTK_PIZZA (data);
if (!pizza->use_filter)
return GDK_FILTER_CONTINUE;
switch (xevent->type)
{
case Expose:
@@ -1211,6 +1151,9 @@ gtk_pizza_main_filter (GdkXEvent *gdk_xevent,
xevent = (XEvent *)gdk_xevent;
pizza = GTK_PIZZA (data);
if (!pizza->use_filter)
return GDK_FILTER_CONTINUE;
if (xevent->type == VisibilityNotify)
{
switch (xevent->xvisibility.state)

View File

@@ -381,10 +381,13 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
// "expose_event" of m_widget
//-----------------------------------------------------------------------------
static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
{
if (gdk_event->count > 0) return;
if (gdk_event->count > 0) return FALSE;
draw_frame( widget, win );
return TRUE;
}
//-----------------------------------------------------------------------------
@@ -610,12 +613,18 @@ static long map_to_wx_keysym( KeySym keysym )
// "expose_event" of m_wxwindow
//-----------------------------------------------------------------------------
static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
if (win->m_queuedFullRedraw)
return TRUE;
/*
if (win->GetName() == wxT("grid window"))
if (win->GetName() == wxT("htmlWindow"))
{
wxPrintf( wxT("OnExpose from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
@@ -634,10 +643,7 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
if (gdk_event->count > 0)
return;
if (!win->m_hasVMT)
return;
return TRUE;
wxEraseEvent eevent( win->GetId() );
eevent.SetEventObject( win );
@@ -648,25 +654,85 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
/* The following code will result in all window-less widgets
being redrawn if the wxWindows class is given a chance to
paint *anything* because it will then be allowed to paint
over the window-less widgets */
GtkPizza *pizza = GTK_PIZZA (widget);
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkEventExpose child_event = *gdk_event;
if (GTK_WIDGET_NO_WINDOW (child->widget) &&
GTK_WIDGET_DRAWABLE (child->widget))
{
child_event.area.x = child->widget->allocation.x;
child_event.area.y = child->widget->allocation.y;
child_event.area.width = child->widget->allocation.width;
child_event.area.height = child->widget->allocation.height;
gtk_widget_event (child->widget, (GdkEvent*) &child_event);
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
// "event" of m_wxwindow
//-----------------------------------------------------------------------------
/* GTK thinks it is clever and filters out a certain amount of "unneeded"
expose events. We need them, of course, so we override the main event
procedure in GtkWidget by giving our own handler for all system events,
looking for the expose events and then we can always send them. */
gint gtk_window_event_event_callback( GtkWidget *widget, GdkEventExpose *event, wxWindow *win )
{
if (event->type == GDK_EXPOSE)
{
gint ret = gtk_window_expose_callback( widget, event, win );
return ret;
}
return FALSE;
}
//-----------------------------------------------------------------------------
// "draw" of m_wxwindow
//-----------------------------------------------------------------------------
static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
GdkRectangle *rect, wxWindow *win )
/* This callback is a complete replacement of the gtk_pizza_draw() function,
which disabled. */
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
if ((rect->x == 0) && (rect->y == 0) && (rect->width <= 1) && (rect->height <= 1))
if (win->m_queuedFullRedraw)
return;
GtkPizza *pizza = GTK_PIZZA (widget);
if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) &&
(pizza->clear_on_draw))
{
gdk_window_clear_area( pizza->bin_window,
rect->x, rect->y, rect->width, rect->height);
}
/*
if (win->GetName() == wxT("grid window"))
if (win->GetName() == wxT("htmlWindow"))
{
wxPrintf( wxT("OnDraw from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
@@ -681,9 +747,6 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
win->GetUpdateRegion().Union( rect->x, rect->y,
rect->width, rect->height );
if (!win->m_hasVMT)
return;
wxEraseEvent eevent( win->GetId() );
eevent.SetEventObject( win );
win->GetEventHandler()->ProcessEvent(eevent);
@@ -693,6 +756,17 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkRectangle child_area;
if (gtk_widget_intersect (child->widget, rect, &child_area))
gtk_widget_draw (child->widget, (GdkRectangle*) NULL );
}
}
//-----------------------------------------------------------------------------
@@ -1974,6 +2048,9 @@ void wxWindow::Init()
m_isFrame = FALSE;
m_acceptsFocus = FALSE;
m_clipPaintRegion = FALSE;
m_queuedFullRedraw = FALSE;
m_cursor = *wxSTANDARD_CURSOR;
#ifdef HAVE_XIM
@@ -2012,17 +2089,8 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
#ifdef __WXDEBUG__
debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name );
#endif
GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
#ifdef __WXDEBUG__
debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name );
debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name );
#endif
GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
scroll_class->scrollbar_spacing = 0;
@@ -2033,10 +2101,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
m_wxwindow = gtk_pizza_new();
#ifdef __WXDEBUG__
debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name );
#endif
gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
#if (GTK_MINOR_VERSION > 0)
@@ -2221,6 +2285,9 @@ void wxWindow::PostCreation()
if (!m_noExpose)
{
/* these get reported to wxWindows -> wxPaintEvent */
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event",
GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this );
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
@@ -2320,6 +2387,24 @@ bool wxWindow::Destroy()
void wxWindow::DoMoveWindow(int x, int y, int width, int height)
{
if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window)
{
/* Normally, GTK will send expose events only for the regions
which actually got exposed. Sadly, wxMSW invalidates
the whole window so we have to do that, too. We could
simply add a complete refresh, but we would then get
the normal GTK expose events in surplus, so we shut
off the expose events and schedule a full redraw to
be done in OnInternalIdle, where we restore the handling
of expose events. */
m_queuedFullRedraw = TRUE;
GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window );
mask = (GdkEventMask)(mask & ~GDK_EXPOSURE_MASK);
gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask );
}
gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height );
}
@@ -2391,6 +2476,12 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
if (m_hasScrolling)
{
/* Sometimes the client area changes size without the
whole windows's size changing, but if the whole
windows's size doesn't change, no wxSizeEvent will
normally be sent. Here we add an extra test if
the client test has been changed and this will
be used then. */
GetClientSize( &m_oldClientWidth, &m_oldClientHeight );
}
@@ -2461,6 +2552,27 @@ void wxWindow::OnInternalIdle()
}
UpdateWindowUI();
if (m_queuedFullRedraw)
{
/* See also wxWindow::DoMoveWindow for explanation of this code. What
we test here is if the requested size of the window is the same as
the actual size of window, in which case all expose events that resulted
from resizing the window have been sent (and discarded) and we can
now do our full redraw and switch on expose event handling again. */
if ((m_width == m_widget->allocation.width) && (m_height == m_widget->allocation.height))
{
m_queuedFullRedraw = FALSE;
m_updateRegion.Clear();
m_updateRegion.Union( 0,0,m_width,m_height );
gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window );
mask = (GdkEventMask)(mask | GDK_EXPOSURE_MASK);
gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask );
}
}
}
void wxWindow::DoGetSize( int *width, int *height ) const
@@ -2898,16 +3010,55 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
{
if (m_wxwindow)
{
/*
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
gboolean old_clear = pizza->clear_on_draw;
gtk_pizza_set_clear( pizza, FALSE );
gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
gtk_pizza_set_clear( pizza, old_clear );
*/
GdkEventExpose gdk_event;
gdk_event.count = 0;
gdk_event.area.x = 0;
gdk_event.area.y = 0;
gdk_event.area.width = m_wxwindow->allocation.width;
gdk_event.area.height = m_wxwindow->allocation.height;
gtk_window_expose_callback( m_wxwindow, &gdk_event, this );
}
else
{
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
}
}
else
{
if (m_wxwindow)
{
/*
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
gboolean old_clear = pizza->clear_on_draw;
gtk_pizza_set_clear( pizza, FALSE );
gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
GdkRectangle gdk_rect;
gdk_rect.x = rect->x;
gdk_rect.y = rect->y;
gdk_rect.width = rect->width;
gdk_rect.height = rect->height;
gtk_widget_draw( m_wxwindow, &gdk_rect );
gtk_window_draw_callback( m_wxwindow, &gdk_rect, this );
gtk_pizza_set_clear( pizza, old_clear );
}
else
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
*/
GdkEventExpose gdk_event;
gdk_event.count = 0;
gdk_event.area.x = rect->x;
gdk_event.area.y = rect->y;
gdk_event.area.width = rect->width;
gdk_event.area.height = rect->height;
gtk_window_expose_callback( m_wxwindow, &gdk_event, this );
}
else
{
@@ -2916,21 +3067,10 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
gdk_rect.y = rect->y;
gdk_rect.width = rect->width;
gdk_rect.height = rect->height;
if (m_wxwindow)
{
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
gboolean old_clear = pizza->clear_on_draw;
gtk_pizza_set_clear( pizza, FALSE );
gtk_widget_draw( m_wxwindow, &gdk_rect );
gtk_pizza_set_clear( pizza, old_clear );
}
else
gtk_widget_draw( m_widget, &gdk_rect );
}
}
}
void wxWindow::Clear()
{
@@ -3452,7 +3592,9 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
if ((dx == 0) && (dy == 0)) return;
m_clipPaintRegion = TRUE;
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
m_clipPaintRegion = FALSE;
/*
if (m_children.GetCount() > 0)