X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f8f7cff4368ee960f63f61d0dd32eacdd471800b..9581362b151a80bc62bf3ed6f9fae70481ea7723:/src/gtk/window.cpp?ds=inline diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index af7af1f127..b72018c1df 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: src/gtk/window.cpp -// Purpose: +// Purpose: wxWindowGTK implementation // Author: Robert Roebling // Id: $Id$ // Copyright: (c) 1998 Robert Roebling, Julian Smart @@ -1074,15 +1074,15 @@ template void InitMouseEvent(wxWindowGTK *win, T *gdk_event) { event.SetTimestamp( gdk_event->time ); - event.m_shiftDown = gdk_event->state & GDK_SHIFT_MASK; - event.m_controlDown = gdk_event->state & GDK_CONTROL_MASK; - event.m_altDown = gdk_event->state & GDK_MOD1_MASK; - event.m_metaDown = gdk_event->state & GDK_META_MASK; - event.m_leftDown = gdk_event->state & GDK_BUTTON1_MASK; - event.m_middleDown = gdk_event->state & GDK_BUTTON2_MASK; - event.m_rightDown = gdk_event->state & GDK_BUTTON3_MASK; - event.m_aux1Down = gdk_event->state & GDK_BUTTON4_MASK; - event.m_aux2Down = gdk_event->state & GDK_BUTTON5_MASK; + event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0; + event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0; + event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0; + event.m_metaDown = (gdk_event->state & GDK_META_MASK) != 0; + event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK) != 0; + event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK) != 0; + event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK) != 0; + event.m_aux1Down = (gdk_event->state & GDK_BUTTON4_MASK) != 0; + event.m_aux2Down = (gdk_event->state & GDK_BUTTON5_MASK) != 0; wxPoint pt = win->GetClientAreaOrigin(); event.m_x = (wxCoord)gdk_event->x - pt.x; @@ -1208,6 +1208,11 @@ bool wxWindowGTK::GTKProcessEvent(wxEvent& event) const return HandleWindowEvent(event); } +bool wxWindowGTK::GTKShouldIgnoreEvent() const +{ + return !m_hasVMT || g_blockEventsOnDrag; +} + int wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const { if (!m_hasVMT) @@ -1828,7 +1833,7 @@ gtk_window_realized_callback(GtkWidget* widget, wxWindow* win) gtk_im_context_set_client_window( win->m_imData->context, widget->window); } - + // We cannot set colours and fonts before the widget // been realized, so we do this directly after realization // or otherwise in idle time @@ -1958,8 +1963,10 @@ wxWindow *wxWindowBase::DoFindFocus() void wxWindowGTK::AddChildGTK(wxWindowGTK* child) { - /* the window might have been scrolled already, do we - have to adapt the position */ + wxASSERT_MSG(m_wxwindow, "Cannot add a child to a window without a client area"); + + // the window might have been scrolled already, we + // have to adapt the position wxPizza* pizza = WX_PIZZA(m_wxwindow); child->m_x += pizza->m_scroll_x; child->m_y += pizza->m_scroll_y; @@ -1992,16 +1999,16 @@ wxMouseState wxGetMouseState() ms.SetX(x); ms.SetY(y); - ms.SetLeftDown(mask & GDK_BUTTON1_MASK); - ms.SetMiddleDown(mask & GDK_BUTTON2_MASK); - ms.SetRightDown(mask & GDK_BUTTON3_MASK); - ms.SetAux1Down(mask & GDK_BUTTON4_MASK); - ms.SetAux2Down(mask & GDK_BUTTON5_MASK); + ms.SetLeftDown((mask & GDK_BUTTON1_MASK) != 0); + ms.SetMiddleDown((mask & GDK_BUTTON2_MASK) != 0); + ms.SetRightDown((mask & GDK_BUTTON3_MASK) != 0); + ms.SetAux1Down((mask & GDK_BUTTON4_MASK) != 0); + ms.SetAux2Down((mask & GDK_BUTTON5_MASK) != 0); - ms.SetControlDown(mask & GDK_CONTROL_MASK); - ms.SetShiftDown(mask & GDK_SHIFT_MASK); - ms.SetAltDown(mask & GDK_MOD1_MASK); - ms.SetMetaDown(mask & GDK_META_MASK); + ms.SetControlDown((mask & GDK_CONTROL_MASK) != 0); + ms.SetShiftDown((mask & GDK_SHIFT_MASK) != 0); + ms.SetAltDown((mask & GDK_MOD1_MASK) != 0); + ms.SetMetaDown((mask & GDK_META_MASK) != 0); return ms; } @@ -2436,7 +2443,10 @@ bool wxWindowGTK::Destroy() void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height) { gtk_widget_set_size_request(m_widget, width, height); + // inform the parent to perform the move + wxASSERT_MSG(m_parent && m_parent->m_wxwindow, + "the parent window has no client area?"); WX_PIZZA(m_parent->m_wxwindow)->move(m_widget, x, y); } @@ -2576,8 +2586,8 @@ void wxWindowGTK::OnInternalIdle() RealizeTabOrder(); } - // Update style if the window was not yet realized - // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called + // Update style if the window was not yet realized when + // SetBackgroundStyle() was called if (m_needsStyleChange) { SetBackgroundStyle(GetBackgroundStyle()); @@ -2819,28 +2829,39 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const bool wxWindowGTK::Show( bool show ) { - wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") ); - - if (!wxWindowBase::Show(show)) + if ( !wxWindowBase::Show(show) ) { // nothing to do return false; } - if (show && m_showOnIdle) + // notice that we may call Hide() before the window is created and this is + // actually useful to create it hidden initially -- but we can't call + // Show() before it is created + if ( !m_widget ) { - // deferred + wxASSERT_MSG( !show, "can't show invalid window" ); + return true; } - else + + if ( show ) { - if (show) - gtk_widget_show(m_widget); - else - gtk_widget_hide(m_widget); - wxShowEvent eventShow(GetId(), show); - eventShow.SetEventObject(this); - HandleWindowEvent(eventShow); + if ( m_showOnIdle ) + { + // defer until later + return true; + } + + gtk_widget_show(m_widget); } + else // hide + { + gtk_widget_hide(m_widget); + } + + wxShowEvent eventShow(GetId(), show); + eventShow.SetEventObject(this); + HandleWindowEvent(eventShow); return true; } @@ -2906,12 +2927,12 @@ int wxWindowGTK::GetCharWidth() const return (int) PANGO_PIXELS(rect.width); } -void wxWindowGTK::GetTextExtent( const wxString& string, - int *x, - int *y, - int *descent, - int *externalLeading, - const wxFont *theFont ) const +void wxWindowGTK::DoGetTextExtent( const wxString& string, + int *x, + int *y, + int *descent, + int *externalLeading, + const wxFont *theFont ) const { wxFont fontToUse = theFont ? *theFont : GetFont(); @@ -3529,35 +3550,42 @@ bool wxWindowGTK::ScrollPages(int pages) void wxWindowGTK::Refresh(bool WXUNUSED(eraseBackground), const wxRect *rect) { - GtkWidget* widget; - if (m_wxwindow) - widget = m_wxwindow; - else if (m_widget) - widget = m_widget; - else - return; - - if (!widget->window) + if ( !m_widget ) + { + // it is valid to call Refresh() for a window which hasn't been created + // yet, it simply doesn't do anything in this case return; + } - if (rect == NULL) - gtk_widget_queue_draw(widget); + if (!m_wxwindow) + { + if (rect) + gtk_widget_queue_draw_area( m_widget, rect->x, rect->y, rect->width, rect->height ); + else + gtk_widget_queue_draw( m_widget ); + } else { - int x = rect->x; - if (GetLayoutDirection() == wxLayout_RightToLeft) - x = GetClientSize().x - x - rect->width; + // Just return if the widget or one of its ancestors isn't mapped + GtkWidget *w; + for (w = m_wxwindow; w != NULL; w = w->parent) + if (!GTK_WIDGET_MAPPED (w)) + return; -#if 0 - gtk_widget_queue_draw_area(widget, x, rect->y, rect->width, rect->height); -#else - GdkRectangle r; - r.x = rect->x; - r.y = rect->y; - r.width = rect->width; - r.height = rect->height; - gdk_window_invalidate_rect( m_wxwindow->window, &r, TRUE ); -#endif + if (rect) + { + int x = rect->x; + if (GetLayoutDirection() == wxLayout_RightToLeft) + x = GetClientSize().x - x - rect->width; + GdkRectangle r; + r.x = rect->x; + r.y = rect->y; + r.width = rect->width; + r.height = rect->height; + gdk_window_invalidate_rect( m_wxwindow->window, &r, TRUE ); + } + else + gdk_window_invalidate_rect( m_wxwindow->window, NULL, TRUE ); } } @@ -3570,8 +3598,8 @@ void wxWindowGTK::Update() // This ensures nothing will overwrite the drawing we are about to do. gdk_display_sync(display); - gdk_window_process_updates(m_widget->window, true); - + gdk_window_process_updates(m_widget->window, TRUE); + // Flush again, but no need to wait for it to finish gdk_display_flush(display); } @@ -3627,54 +3655,74 @@ void wxWindowGTK::GtkSendPaintEvents() } } - if (GetThemeEnabled() && (GetBackgroundStyle() == wxBG_STYLE_SYSTEM)) + switch ( GetBackgroundStyle() ) { - // find ancestor from which to steal background - wxWindow *parent = wxGetTopLevelParent((wxWindow *)this); - if (!parent) - parent = (wxWindow*)this; - - if (GTK_WIDGET_MAPPED(parent->m_widget)) - { - wxRegionIterator upd( m_nativeUpdateRegion ); - while (upd) + case wxBG_STYLE_ERASE: { - GdkRectangle rect; - rect.x = upd.GetX(); - rect.y = upd.GetY(); - rect.width = upd.GetWidth(); - rect.height = upd.GetHeight(); - - gtk_paint_flat_box( parent->m_widget->style, - m_wxwindow->window, - (GtkStateType)GTK_WIDGET_STATE(m_wxwindow), - GTK_SHADOW_NONE, - &rect, - parent->m_widget, - (char *)"base", - 0, 0, -1, -1 ); - - ++upd; + wxWindowDC dc( (wxWindow*)this ); + dc.SetDeviceClippingRegion( m_updateRegion ); + + // Work around gtk-qt <= 0.60 bug whereby the window colour + // remains grey + if ( UseBgCol() && + wxSystemOptions:: + GetOptionInt("gtk.window.force-background-colour") ) + { + dc.SetBackground(GetBackgroundColour()); + dc.Clear(); + } + + wxEraseEvent erase_event( GetId(), &dc ); + erase_event.SetEventObject( this ); + + if ( HandleWindowEvent(erase_event) ) + { + // background erased, don't do it again + break; + } } - } - } - else - { - wxWindowDC dc( (wxWindow*)this ); - dc.SetDeviceClippingRegion( m_updateRegion ); + // fall through - // Work around gtk-qt <= 0.60 bug whereby the window colour - // remains grey - if (GetBackgroundStyle() == wxBG_STYLE_COLOUR && GetBackgroundColour().Ok() && wxSystemOptions::GetOptionInt(wxT("gtk.window.force-background-colour")) == 1) - { - dc.SetBackground(wxBrush(GetBackgroundColour())); - dc.Clear(); - } + case wxBG_STYLE_SYSTEM: + if ( GetThemeEnabled() ) + { + // find ancestor from which to steal background + wxWindow *parent = wxGetTopLevelParent((wxWindow *)this); + if (!parent) + parent = (wxWindow*)this; - wxEraseEvent erase_event( GetId(), &dc ); - erase_event.SetEventObject( this ); + if (GTK_WIDGET_MAPPED(parent->m_widget)) + { + wxRegionIterator upd( m_nativeUpdateRegion ); + while (upd) + { + GdkRectangle rect; + rect.x = upd.GetX(); + rect.y = upd.GetY(); + rect.width = upd.GetWidth(); + rect.height = upd.GetHeight(); + + gtk_paint_flat_box( parent->m_widget->style, + m_wxwindow->window, + (GtkStateType)GTK_WIDGET_STATE(m_wxwindow), + GTK_SHADOW_NONE, + &rect, + parent->m_widget, + (char *)"base", + 0, 0, -1, -1 ); + + ++upd; + } + } + } + break; + + case wxBG_STYLE_PAINT: + // nothing to do: window will be painted over in EVT_PAINT + break; - HandleWindowEvent(erase_event); + default: + wxFAIL_MSG( "unsupported background style" ); } wxNcPaintEvent nc_paint_event( GetId() ); @@ -3739,8 +3787,7 @@ bool wxWindowGTK::SetBackgroundColour( const wxColour &colour ) // apply style change (forceStyle=true so that new style is applied // even if the bg colour changed from valid to wxNullColour) - if (GetBackgroundStyle() != wxBG_STYLE_CUSTOM) - GTKApplyWidgetStyle(true); + GTKApplyWidgetStyle(true); return true; } @@ -3868,7 +3915,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style) { wxWindowBase::SetBackgroundStyle(style); - if (style == wxBG_STYLE_CUSTOM) + if ( style == wxBG_STYLE_PAINT ) { GdkWindow *window; if ( m_wxwindow ) @@ -3906,6 +3953,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style) // even if the bg colour changed from valid to wxNullColour): GTKApplyWidgetStyle(true); } + return true; }