if (win->m_hasScrolling)
{
- GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
+ GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
- GtkRequisition vscroll_req;
- vscroll_req.width = 2;
- vscroll_req.height = 2;
- (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request )
- (scroll_window->vscrollbar, &vscroll_req );
+ GtkRequisition vscroll_req;
+ vscroll_req.width = 2;
+ vscroll_req.height = 2;
+ (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request )
+ (scroll_window->vscrollbar, &vscroll_req );
- GtkRequisition hscroll_req;
- hscroll_req.width = 2;
- hscroll_req.height = 2;
- (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request )
- (scroll_window->hscrollbar, &hscroll_req );
+ GtkRequisition hscroll_req;
+ hscroll_req.width = 2;
+ hscroll_req.height = 2;
+ (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request )
+ (scroll_window->hscrollbar, &hscroll_req );
- GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(widget) );
+ GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(widget) );
- if (scroll_window->vscrollbar_visible)
- {
- dw += vscroll_req.width;
- dw += scroll_class->scrollbar_spacing;
- }
+ if (scroll_window->vscrollbar_visible)
+ {
+ dw += vscroll_req.width;
+ dw += scroll_class->scrollbar_spacing;
+ }
- if (scroll_window->hscrollbar_visible)
- {
- dh += hscroll_req.height;
- dh += scroll_class->scrollbar_spacing;
- }
- }
+ if (scroll_window->hscrollbar_visible)
+ {
+ dh += hscroll_req.height;
+ dh += scroll_class->scrollbar_spacing;
+ }
+}
int dx = 0;
int dy = 0;
}
*/
+#ifndef __WXUNIVERSAL__
GtkPizza *pizza = GTK_PIZZA (widget);
if (win->GetThemeEnabled())
(char *)"base",
0, 0, -1, -1);
}
+#endif
win->GetUpdateRegion().Union( gdk_event->area.x,
gdk_event->area.y,
gdk_event->area.width,
gdk_event->area.height );
- if (gdk_event->count == 0)
- {
- win->m_clipPaintRegion = TRUE;
-
- wxWindowDC dc(win);
- dc.SetClippingRegion(win->GetUpdateRegion());
- wxEraseEvent eevent( win->GetId(), &dc );
- eevent.SetEventObject( win );
-#if 1
- (void)win->GetEventHandler()->ProcessEvent(eevent);
-#else // 0
- if (!win->GetEventHandler()->ProcessEvent(eevent))
- {
- wxClientDC dc( win );
- dc.SetBrush( wxBrush( win->GetBackgroundColour(), wxSOLID ) );
- dc.SetPen( *wxTRANSPARENT_PEN );
-
- wxRegionIterator upd( win->GetUpdateRegion() );
- while (upd)
- {
- dc.DrawRectangle( upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
- upd ++;
- }
- }
-#endif // 1/0
-
- wxNcPaintEvent eventNc( win->GetId() );
- eventNc.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( eventNc );
-
- wxPaintEvent event( win->GetId() );
- event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
-
- win->GetUpdateRegion().Clear();
-
- win->m_clipPaintRegion = FALSE;
- }
-
- /* 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 */
- 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) /* &&
- gtk_widget_intersect (child->widget, &gdk_event->area, &child_event.area)*/ )
- {
- 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);
- }
- }
+ // Actual redrawing takes place in idle time.
+ win->Update();
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.
- There, we look for expose events ourselves whereas all other events are
- handled normally. */
+// 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.
+// There, we look for expose events ourselves whereas all other events are
+// handled normally.
gint gtk_window_event_event_callback( GtkWidget *widget,
GdkEventExpose *event,
// "draw" of m_wxwindow
//-----------------------------------------------------------------------------
-/* This callback is a complete replacement of the gtk_pizza_draw() function,
- which disabled. */
+// This callback is a complete replacement of the gtk_pizza_draw() function,
+// which disabled.
static void gtk_window_draw_callback( GtkWidget *widget,
GdkRectangle *rect,
if (g_isIdle)
wxapp_install_idle_handler();
+ // The wxNO_FULL_REPAINT_ON_RESIZE flag only works if
+ // there are no child windows.
if ((win->HasFlag(wxNO_FULL_REPAINT_ON_RESIZE)) &&
(win->GetChildren().GetCount() == 0))
{
}
*/
+#ifndef __WXUNIVERSAL__
GtkPizza *pizza = GTK_PIZZA (widget);
if (win->GetThemeEnabled())
gdk_window_clear_area( pizza->bin_window,
rect->x, rect->y, rect->width, rect->height);
}
-
- win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
-
- win->m_clipPaintRegion = TRUE;
-
- wxWindowDC dc(win);
- dc.SetClippingRegion(win->GetUpdateRegion());
- wxEraseEvent eevent( win->GetId(), &dc );
- eevent.SetEventObject( win );
-
-#if 1
- (void)win->GetEventHandler()->ProcessEvent(eevent);
-#else
- if (!win->GetEventHandler()->ProcessEvent(eevent))
- {
- if (!win->GetEventHandler()->ProcessEvent(eevent))
- {
- wxClientDC dc( win );
- dc.SetBrush( wxBrush( win->GetBackgroundColour(), wxSOLID ) );
- dc.SetPen( *wxTRANSPARENT_PEN );
-
- wxRegionIterator upd( win->GetUpdateRegion() );
- while (upd)
- {
- dc.DrawRectangle( upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
- upd ++;
- }
- }
- }
#endif
- wxNcPaintEvent eventNc( win->GetId() );
- eventNc.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( eventNc );
-
- wxPaintEvent event( win->GetId() );
- event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
-
- win->GetUpdateRegion().Clear();
-
- win->m_clipPaintRegion = FALSE;
+ win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
+ // Actual redrawing takes place in idle time.
+
+ win->Update();
+#ifndef __WXUNIVERSAL__
+ // Redraw child widgets
GList *children = pizza->children;
while (children)
{
- GtkPizzaChild *child = (GtkPizzaChild*) children->data;
- children = children->next;
+ 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, &child_area /* (GdkRectangle*) NULL*/ );
- }
+ GdkRectangle child_area;
+ if (gtk_widget_intersect (child->widget, rect, &child_area))
+ {
+ gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
+ }
}
+#endif
}
//-----------------------------------------------------------------------------
if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
- if (win->m_wxwindow)
+ if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
{
- if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
- {
- gtk_widget_grab_focus (win->m_wxwindow);
-
+ gtk_widget_grab_focus( win->m_wxwindow );
/*
- wxPrintf( wxT("GrabFocus from ") );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( wxT(".\n") );
+ wxPrintf( wxT("GrabFocus from ") );
+ if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+ wxPrintf( win->GetClassInfo()->GetClassName() );
+ wxPrintf( wxT(".\n") );
*/
-
- }
}
wxEventType event_type = wxEVT_NULL;
InitMouseEvent( win, event, gdk_event );
AdjustEventButtonState(event);
-
+
// wxListBox actually get mouse events from the item
-
+
if (win->m_isListBox)
{
event.m_x += widget->allocation.x;
AdjustEventButtonState(event);
// wxListBox actually get mouse events from the item
-
+
if (win->m_isListBox)
{
event.m_x += widget->allocation.x;
g_focusWindow = win;
#if 0
- wxPrintf( "OnSetFocus from " );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( ".\n" );
+ wxLogDebug( wxT("OnSetFocus from %s\n"), win->GetName().c_str() );
#endif
// notify the parent keeping track of focus for the kbd navigation
// "focus_out_event"
//-----------------------------------------------------------------------------
-static GtkWidget *gs_widgetLastFocus = NULL;
-
-static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindowGTK *win )
+static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
if (!win->m_hasVMT) return FALSE;
if (g_blockEventsOnDrag) return FALSE;
- // VZ: this is really weird but GTK+ seems to call us from inside
- // gtk_widget_grab_focus(), i.e. it first sends "focus_out" signal to
- // this widget and then "focus_in". This is totally unexpected and
- // completely breaks wxUniv code so ignore this dummy event (we can't
- // be losing focus if we're about to acquire it!)
- if ( widget == gs_widgetLastFocus )
- {
- gs_widgetLastFocus = NULL;
-
- return FALSE;
- }
+#if 0
+ wxLogDebug( wxT("OnKillFocus from %s"), win->GetName().c_str() );
+#endif
if ( !g_activeFrameLostFocus && g_activeFrame )
{
g_focusWindow = (wxWindowGTK *)NULL;
-#if 0
- wxPrintf( "OnKillFocus from " );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( ".\n" );
-#endif
-
#ifdef HAVE_XIM
if (win->m_ic)
gdk_im_end();
m_noExpose = FALSE;
m_nativeSizeEvent = FALSE;
-
+
m_hasScrolling = FALSE;
m_isScrolling = FALSE;
if (m_parent)
m_parent->DoAddChild( this );
-
+
m_focusWidget = m_wxwindow;
PostCreation();
void wxWindowGTK::PostCreation()
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
-
+
if (m_wxwindow)
{
if (!m_noExpose)
if (height == -1) m_height = 26;
}
- if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
- if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
- if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
- if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+ int minWidth = GetMinWidth(),
+ minHeight = GetMinHeight(),
+ maxWidth = GetMaxWidth(),
+ maxHeight = GetMaxHeight();
+
+ if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
+ if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
+ if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
+ if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
int border = 0;
int bottom_border = 0;
void wxWindowGTK::OnInternalIdle()
{
+ // Update invalidated regions.
+ Update();
+
+ // Synthetize activate events.
if ( g_sendActivateEvent != -1 )
{
bool activate = g_sendActivateEvent != 0;
dx = pizza->xoffset;
dy = pizza->yoffset;
}
-
+
if (x) (*x) = m_x - dx;
if (y) (*y) = m_y - dy;
}
{
if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow))
{
- // see comment in gtk_window_focus_out_callback()
- gs_widgetLastFocus = m_wxwindow;
gtk_widget_grab_focus (m_wxwindow);
}
}
// ?
}
}
-
-#if 0
- wxPrintf( "SetFocus finished in " );
- if (GetClassInfo() && GetClassInfo()->GetClassName())
- wxPrintf( GetClassInfo()->GetClassName() );
- wxPrintf( ".\n" );
-#endif
-
}
bool wxWindowGTK::AcceptsFocus() const
{
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
- /* we provide this function ourselves as it is
- missing in GDK (top of this file) */
+ // We provide this function ourselves as it is
+ // missing in GDK (top of this file).
GdkWindow *window = (GdkWindow*) NULL;
if (m_wxwindow)
{
if (rect)
{
- gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
- rect->x, rect->y,
- rect->width, rect->height );
+ // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+ m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height );
}
else
{
- gdk_window_clear( GTK_PIZZA(m_wxwindow)->bin_window );
+ // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+ m_clearRegion.Clear();
+ m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
}
}
- /* there is no GTK equivalent of "draw only, don't clear" so we
- invent our own in the GtkPizza widget */
-
- if (!rect)
+ if (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.type = GDK_EXPOSE;
- gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window;
- 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, (wxWindow *)this );
+ // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+ m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
}
else
{
- gtk_widget_draw( m_widget, (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_widget, &gdk_rect );
}
}
else
{
-
if (m_wxwindow)
{
-/*
- GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
- gboolean old_clear = pizza->clear_on_draw;
- gtk_pizza_set_clear( pizza, FALSE );
+ // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+ m_updateRegion.Clear();
+ m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
+ }
+ else
+ {
+ gtk_widget_draw( m_widget, (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 );
+void wxWindowGTK::Update()
+{
+ if (!m_updateRegion.IsEmpty())
+ {
+ GtkSendPaintEvents();
+ }
+}
- gtk_pizza_set_clear( pizza, old_clear );
-*/
+void wxWindowGTK::GtkSendPaintEvents()
+{
+ if (!m_wxwindow)
+ {
+ m_clearRegion.Clear();
+ m_updateRegion.Clear();
+ return;
+ }
+
+ m_clipPaintRegion = TRUE;
+
+ // if (!m_clearRegion.IsEmpty()) // always send an erase event
+ {
+ wxWindowDC dc( (wxWindow*)this );
+ dc.SetClippingRegion( m_clearRegion );
+
+ wxEraseEvent erase_event( GetId(), &dc );
+ erase_event.SetEventObject( this );
+
+ if (!GetEventHandler()->ProcessEvent(erase_event))
+ {
+ wxRegionIterator upd( m_clearRegion );
+ while (upd)
+ {
+ gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
+ upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
+ upd ++;
+ }
+ }
+ m_clearRegion.Clear();
+ }
+
+ wxNcPaintEvent nc_paint_event( GetId() );
+ nc_paint_event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( nc_paint_event );
+
+ wxPaintEvent paint_event( GetId() );
+ paint_event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( paint_event );
+
+ m_clipPaintRegion = FALSE;
+
+#ifndef __WXUNIVERSAL__
+ // The following code will result in all window-less widgets
+ // being redrawn because the wxWindows class is allowed to
+ // paint over the window-less widgets.
+
+ GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
+
+ GList *children = pizza->children;
+ while (children)
+ {
+ GtkPizzaChild *child = (GtkPizzaChild*) children->data;
+ children = children->next;
+
+ if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+ GTK_WIDGET_DRAWABLE (child->widget))
+ {
+ // Get intersection of widget area and update region
+ wxRegion region( m_updateRegion );
+
GdkEventExpose gdk_event;
gdk_event.type = GDK_EXPOSE;
- gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window;
+ gdk_event.window = pizza->bin_window;
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, (wxWindow *)this );
- }
- else
- {
- 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_widget, &gdk_rect );
+
+ wxRegionIterator upd( m_updateRegion );
+ while (upd)
+ {
+ GdkRectangle rect;
+ rect.x = upd.GetX();
+ rect.y = upd.GetY();
+ rect.width = upd.GetWidth();
+ rect.height = upd.GetHeight();
+
+ if (gtk_widget_intersect (child->widget, &rect, &gdk_event.area))
+ {
+ gtk_widget_event (child->widget, (GdkEvent*) &gdk_event);
+ }
+
+ upd ++;
+ }
}
}
+#endif
+
+ m_updateRegion.Clear();
}
void wxWindowGTK::Clear()
void wxWindowGTK::SetWidgetStyle()
{
-#if DISABLE_STYLE_IF_BROKEN_THEM
+#if DISABLE_STYLE_IF_BROKEN_THEME
if (m_widget->style->engine_data)
{
static bool s_warningPrinted = FALSE;
return TRUE;
}
-void wxWindowGTK::CaptureMouse()
+void wxWindowGTK::DoCaptureMouse()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
g_captureWindowHasMouse = TRUE;
}
-void wxWindowGTK::ReleaseMouse()
+void wxWindowGTK::DoReleaseMouse()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
wxCHECK_RET( g_captureWindow, wxT("can't release mouse - not captured") );
+ g_captureWindow = (wxWindowGTK*) NULL;
+
GdkWindow *window = (GdkWindow*) NULL;
if (m_wxwindow)
window = GTK_PIZZA(m_wxwindow)->bin_window;
return;
gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME );
- g_captureWindow = (wxWindowGTK*) NULL;
}
/* static */
wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
+ // No scrolling requested.
if ((dx == 0) && (dy == 0)) return;
+
+ if (!m_updateRegion.IsEmpty())
+ {
+ m_updateRegion.Offset( dx, dy );
+
+ int cw = 0;
+ int ch = 0;
+ GetClientSize( &cw, &ch );
+ m_updateRegion.Intersect( 0, 0, cw, ch );
+ }
+
+ if (!m_clearRegion.IsEmpty())
+ {
+ m_clearRegion.Offset( dx, dy );
+
+ int cw = 0;
+ int ch = 0;
+ GetClientSize( &cw, &ch );
+ m_clearRegion.Intersect( 0, 0, cw, ch );
+ }
+
+#if 1
m_clipPaintRegion = TRUE;
+
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
+
m_clipPaintRegion = FALSE;
-/*
+#else
+
if (m_children.GetCount() > 0)
{
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
gdk_gc_unref( m_scrollGC );
}
-*/
+#endif
}
// Find the wxWindow at the current mouse position, also returning the mouse