wxGTK:
- Automatically use stock items for the menu items with standard ids
+- Setting cursor now works for all controls
2.7.0
// implementation
// --------------
- bool IsOwnGtkWindow( GdkWindow *window );
-
// Since this wxButton doesn't derive from wxButtonBase (why?) we need
// to override this here too...
virtual bool ShouldInheritColours() const { return false; }
protected:
virtual wxSize DoGetBestSize() const;
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
private:
DECLARE_DYNAMIC_CLASS(wxButton)
// implementation
// --------------
- bool IsOwnGtkWindow( GdkWindow *window );
- void OnInternalIdle();
-
GtkWidget *m_widgetCheckbox;
GtkWidget *m_widgetLabel;
protected:
virtual wxSize DoGetBestSize() const;
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
void DoSet3StateValue(wxCheckBoxState state);
wxCheckBoxState DoGet3StateValue() const;
static wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
- virtual bool IsOwnGtkWindow( GdkWindow *window );
-
protected:
wxList m_clientList; // contains the client data for the items
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual wxSize DoGetBestSize() const;
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
virtual int DoAppend(const wxString& item);
virtual int DoInsert(const wxString& item, unsigned int pos);
virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData);
virtual wxClientData* DoGetItemClientObject(unsigned int n) const;
- virtual wxSize DoGetBestSize() const;
-
private:
// common part of Create() and DoAppend()
int GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& item);
void DisableEvents();
void EnableEvents();
GtkWidget* GetConnectWidget();
- bool IsOwnGtkWindow( GdkWindow *window );
wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST
protected:
// From wxWindowGTK:
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
// From wxItemContainer:
virtual int DoAppend(const wxString& item);
virtual wxVisualAttributes GetDefaultAttributes() const;
+ virtual void OnInternalIdle();
+
protected:
virtual wxSize DoGetBestSize() const;
void PostCreation(const wxSize& size);
// implementation from now on
GtkWidget *GetConnectWidget();
- bool IsOwnGtkWindow( GdkWindow *window );
- void OnInternalIdle();
#if wxUSE_TOOLTIPS
void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
protected:
virtual wxSize DoGetBestSize() const;
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
virtual void DoSetSelection(int n, bool select);
virtual int DoAppend(const wxString& item);
virtual void DoInsertItems(const wxArrayString& items, unsigned int pos);
virtual wxClientData* DoGetItemClientObject(unsigned int n) const;
virtual int DoListHitTest(const wxPoint& point) const;
- void DoApplyWidgetStyle(GtkRcStyle *style);
-
private:
void Init(); //common construction
void SetConstraintSizes(bool recurse);
bool DoPhase(int phase);
#endif
- // report if window belongs to notebook
- bool IsOwnGtkWindow( GdkWindow *window );
// common part of all ctors
void Init();
protected:
// set all page's attributes
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
// remove one page from the notebook but do not destroy it
virtual wxNotebookPage *DoRemovePage(size_t nPage);
void SetFocus();
void GtkDisableEvents();
void GtkEnableEvents();
- bool IsOwnGtkWindow( GdkWindow *window );
#if wxUSE_TOOLTIPS
void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
#endif // wxUSE_TOOLTIPS
virtual void DoSetItemToolTip(unsigned int n, wxToolTip *tooltip);
#endif
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
virtual bool GTKWidgetNeedsMnemonic() const;
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifndef __GTKRADIOBUTTONH__
-#define __GTKRADIOBUTTONH__
+#ifndef _WX_GTK_RADIOBUT_H_
+#define _WX_GTK_RADIOBUT_H_
//-----------------------------------------------------------------------------
// wxRadioButton
virtual bool IsRadioButton() const { return TRUE; }
- bool IsOwnGtkWindow( GdkWindow *window );
- void OnInternalIdle();
-
bool m_blockEvent;
protected:
- void DoApplyWidgetStyle(GtkRcStyle *style);
virtual wxSize DoGetBestSize() const;
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
private:
DECLARE_DYNAMIC_CLASS(wxRadioButton)
};
-#endif // __GTKRADIOBUTTONH__
+#endif // _WX_GTK_RADIOBUT_H_
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifndef __GTKSCROLLBARH__
-#define __GTKSCROLLBARH__
+#ifndef _WX_GTK_SCROLLBAR_H_
+#define _WX_GTK_SCROLLBAR_H_
#include "wx/defs.h"
static wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
- // implementation
- // --------------
-
- bool IsOwnGtkWindow( GdkWindow *window );
+protected:
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
private:
DECLARE_DYNAMIC_CLASS(wxScrollBar)
};
-#endif
- // __GTKSCROLLBARH__
+#endif // _WX_GTK_SCROLLBAR_H_
GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
// implementation
- bool IsOwnGtkWindow( GdkWindow *window );
-
double m_pos;
int m_scrollEventType;
bool m_needThumbRelease;
+protected:
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
private:
DECLARE_DYNAMIC_CLASS(wxSlider)
};
// implementation
void OnSize( wxSizeEvent &event );
- bool IsOwnGtkWindow( GdkWindow *window );
-
int m_pos;
protected:
virtual wxSize DoGetBestSize() const;
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
private:
DECLARE_EVENT_TABLE()
// implementation
void OnChar( wxKeyEvent &event );
- bool IsOwnGtkWindow( GdkWindow *window );
void GtkDisableEvents();
void GtkEnableEvents();
protected:
virtual wxSize DoGetBestSize() const;
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
// Widgets that use the style->base colour for the BG colour should
// override this and return true.
bool SetBackgroundColour(const wxColour& colour);
GtkWidget* GetConnectWidget();
- bool IsOwnGtkWindow( GdkWindow *window );
void CalculateScrollbar();
- void OnInternalIdle();
void SetUpdateFont(bool WXUNUSED(update)) { }
protected:
virtual wxSize DoGetBestSize() const;
- void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
// common part of all ctors
void Init();
wxBitmap m_bitmap;
void OnSetBitmap();
- bool IsOwnGtkWindow(GdkWindow *window);
-
- virtual void OnInternalIdle();
protected:
- void DoApplyWidgetStyle(GtkRcStyle *style);
virtual wxSize DoGetBestSize() const;
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
private:
DECLARE_DYNAMIC_CLASS(wxToggleBitmapButton)
// implementation
bool m_blockEvent;
- bool IsOwnGtkWindow(GdkWindow *window);
-
- virtual void OnInternalIdle();
-
protected:
- void DoApplyWidgetStyle(GtkRcStyle *style);
virtual wxSize DoGetBestSize() const;
+ virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
private:
DECLARE_DYNAMIC_CLASS(wxToggleButton)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifndef __GTKWINDOWH__
-#define __GTKWINDOWH__
+#ifndef _WX_GTK_WINDOW_H_
+#define _WX_GTK_WINDOW_H_
+
+#include "wx/dynarray.h"
// helper structure that holds class that holds GtkIMContext object and
// some additional data needed for key events processing
struct wxGtkIMData;
+WX_DEFINE_EXPORTED_ARRAY_PTR(GdkWindow *, wxArrayGdkWindows);
+
//-----------------------------------------------------------------------------
// callback definition for inserting a window (internal)
//-----------------------------------------------------------------------------
virtual WXWidget GetHandle() const { return m_widget; }
+ // many important things are done here, this function must be called
+ // regularly
virtual void OnInternalIdle();
// Internal represention of Update()
// widget where (most of) the input goes. even tooltips have
// to be applied to all subwidgets.
virtual GtkWidget* GetConnectWidget();
- virtual bool IsOwnGtkWindow( GdkWindow *window );
void ConnectWidget( GtkWidget *widget );
+ // Called from several event handlers
+ bool GTKCallbackCommonPrologue(struct _GdkEventAny *event) const;
+
protected:
// Override GTKWidgetNeedsMnemonic and return true if your
// needs to set its mnemonic widget, such as for a
virtual bool GTKWidgetNeedsMnemonic() const;
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
+ // Get the GdkWindows making part of this window: usually there will be
+ // only one of them in which case it should be returned directly by this
+ // function. If there is more than one GdkWindow (can be the case for
+ // composite widgets), return NULL and fill in the provided array
+ //
+ // This is not pure virtual for backwards compatibility but almost
+ // certainly must be overridden in any wxControl-derived class!
+ virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
+ // Check if the given window makes part of this widget
+ bool GTKIsOwnWindow(GdkWindow *window) const;
+
+ // Set the focus to this window if its setting was delayed because the
+ // widget hadn't been realized when SetFocus() was called
+ //
+ // Return true if focus was set to us, false if nothing was done
+ bool GTKSetDelayedFocusIfNeeded();
+
public:
// Returns the default context which usually is anti-aliased
PangoContext *GtkGetPangoDefaultContext();
// sets the border of a given GtkScrolledWindow from a wx style
static void GtkScrolledWindowSetBorder(GtkWidget* w, int style);
+ // set the current cursor for all GdkWindows making part of this widget
+ // (see GTKGetWindow)
+ //
+ // should be called from OnInternalIdle() if it's overridden
+ void GTKUpdateCursor();
+
private:
enum ScrollUnit { ScrollUnit_Line, ScrollUnit_Page, ScrollUnit_Max };
extern WXDLLIMPEXP_CORE wxWindow *wxFindFocusedChild(wxWindowGTK *win);
-#endif // __GTKWINDOWH__
+#endif // _WX_GTK_WINDOW_H_
return true;
}
-bool wxButton::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
return GTK_BUTTON(m_widget)->event_window;
}
//-----------------------------------------------------------------------------
extern bool g_blockEventsOnDrag;
-extern wxCursor g_globalCursor;
-extern wxWindowGTK *g_delayedFocus;
//-----------------------------------------------------------------------------
// "clicked"
gtk_widget_modify_style(m_widgetLabel, style);
}
-bool wxCheckBox::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxCheckBox::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- return window == GTK_BUTTON(m_widget)->event_window;
-}
-
-void wxCheckBox::OnInternalIdle()
-{
- // Check if we have to show window now
- if (GtkShowFromOnIdle()) return;
-
- wxCursor cursor = m_cursor;
- if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
- GdkWindow *event_window = GTK_BUTTON(m_widgetCheckbox)->event_window;
- if ( event_window && cursor.Ok() )
- {
- /* I now set the cursor the anew in every OnInternalIdle call
- as setting the cursor in a parent window also effects the
- windows above so that checking for the current cursor is
- not possible. */
-
- gdk_window_set_cursor( event_window, cursor.GetCursor() );
- }
-
- if (g_delayedFocus == this)
- {
- if (GTK_WIDGET_REALIZED(m_widget))
- {
- gtk_widget_grab_focus( m_widget );
- g_delayedFocus = NULL;
- }
- }
-
- if (wxUpdateUIEvent::CanUpdate(this))
- UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+ return GTK_BUTTON(m_widgetCheckbox)->event_window;
}
wxSize wxCheckBox::DoGetBestSize() const
return ret;
}
-bool wxChoice::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxChoice::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
return GTK_BUTTON(m_widget)->event_window;
}
return GTK_WIDGET( entry );
}
-bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const
{
- GtkEntry *entry = NULL;
#ifdef __WXGTK24__
if (!gtk_check_version(2,4,0))
{
- entry = GTK_ENTRY( GTK_BIN(m_widget)->child );
- return (window == entry->text_area);
+ wxUnusedVar(windows);
+
+ return GTK_ENTRY(GTK_BIN(m_widget)->child)->text_area;
}
else
-#endif
+#endif // GTK+ 2.4
{
- entry = GTK_ENTRY( GTK_COMBO(m_widget)->entry );
- return ( (window == entry->text_area) ||
- (window == GTK_COMBO(m_widget)->button->window ) );
+ windows.push_back(GTK_ENTRY(GTK_COMBO(m_widget)->entry)->text_area);
+ windows.push_back(GTK_COMBO(m_widget)->button->window);
+
+ // indicate that we return multiple windows in the windows array
+ return NULL;
}
}
return attr;
}
+// ----------------------------------------------------------------------------
+// idle handling
+// ----------------------------------------------------------------------------
+
+void wxControl::OnInternalIdle()
+{
+ if ( GtkShowFromOnIdle() )
+ return;
+
+ GTKUpdateCursor();
+
+ if ( wxUpdateUIEvent::CanUpdate(this) )
+ UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+}
+
#endif // wxUSE_CONTROLS
gtk_widget_modify_style(GTK_WIDGET(GetNotebookPage(i)->m_label), style);
}
-bool wxNotebook::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const
{
- return ((m_widget->window == window) ||
- GTK_NOTEBOOK(m_widget)->event_window == window);
+ windows.push_back(m_widget->window);
+ windows.push_back(GTK_NOTEBOOK(m_widget)->event_window);
+
+ return NULL;
}
// static
WX_DEFINE_LIST( wxRadioBoxButtonsInfoList );
extern bool g_blockEventsOnDrag;
-extern wxWindowGTK *g_delayedFocus;
//-----------------------------------------------------------------------------
// "clicked"
#endif // wxUSE_TOOLTIPS
-bool wxRadioBox::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxRadioBox::GTKGetWindow(wxArrayGdkWindows& windows) const
{
- if (window == m_widget->window)
- return true;
+ windows.push_back(m_widget->window);
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
while (node)
{
GtkWidget *button = GTK_WIDGET( node->GetData()->button );
- if (window == button->window)
- return true;
+ windows.push_back(button->window);
node = node->GetNext();
}
- return false;
+ return NULL;
}
void wxRadioBox::OnInternalIdle()
{
- // Check if we have to show window now
- if (GtkShowFromOnIdle()) return;
-
+ wxControl::OnInternalIdle();
+
if ( m_lostFocus )
{
m_hasFocus = false;
(void)GetEventHandler()->ProcessEvent( event );
}
-
- if (g_delayedFocus == this)
- {
- if (GTK_WIDGET_REALIZED(m_widget))
- {
- g_delayedFocus = NULL;
- SetFocus();
- }
- }
-
- if (wxUpdateUIEvent::CanUpdate(this))
- UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
}
// static
//-----------------------------------------------------------------------------
extern bool g_blockEventsOnDrag;
-extern wxCursor g_globalCursor;
-extern wxWindowGTK *g_delayedFocus;
//-----------------------------------------------------------------------------
// "clicked"
gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
}
-bool wxRadioButton::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *
+wxRadioButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- return window == GTK_BUTTON(m_widget)->event_window;
-}
-
-void wxRadioButton::OnInternalIdle()
-{
- wxCursor cursor = m_cursor;
- if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
- GdkWindow *win = GTK_BUTTON(m_widget)->event_window;
- if ( win && cursor.Ok())
- {
- /* I now set the cursor the anew in every OnInternalIdle call
- as setting the cursor in a parent window also effects the
- windows above so that checking for the current cursor is
- not possible. */
-
- gdk_window_set_cursor( win, cursor.GetCursor() );
- }
-
- if (g_delayedFocus == this)
- {
- if (GTK_WIDGET_REALIZED(m_widget))
- {
- gtk_widget_grab_focus( m_widget );
- g_delayedFocus = NULL;
- }
- }
-
- if (wxUpdateUIEvent::CanUpdate(this))
- UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+ return GTK_BUTTON(m_widget)->event_window;
}
wxSize wxRadioButton::DoGetBestSize() const
SetScrollbar(GetThumbPosition(), GetThumbSize(), range, GetPageSize());
}
-bool wxScrollBar::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxScrollBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- GtkRange *range = GTK_RANGE(m_widget);
- return ( (window == GTK_WIDGET(range)->window) );
+ return GTK_WIDGET(GTK_RANGE(m_widget))->window;
}
// static
return int(gtk_range_get_adjustment (GTK_RANGE (m_widget))->step_increment);
}
-bool wxSlider::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxSlider::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- GtkRange *range = GTK_RANGE(m_widget);
- return (range->event_window == window);
+ return GTK_RANGE(m_widget)->event_window;
}
// static
gtk_widget_set_size_request( m_widget, m_width, m_height );
}
-bool wxSpinButton::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxSpinButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- return GTK_SPIN_BUTTON(m_widget)->panel == window;
+ return GTK_SPIN_BUTTON(m_widget)->panel;
}
wxSize wxSpinButton::DoGetBestSize() const
event.Skip();
}
-bool wxSpinCtrl::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxSpinCtrl::GTKGetWindow(wxArrayGdkWindows& windows) const
{
GtkSpinButton* spinbutton = GTK_SPIN_BUTTON(m_widget);
- return window == spinbutton->entry.text_area || window == spinbutton->panel;
+
+ windows.push_back(spinbutton->entry.text_area);
+ windows.push_back(spinbutton->panel);
+
+ return NULL;
}
wxSize wxSpinCtrl::DoGetBestSize() const
{
wxSize ret( wxControl::DoGetBestSize() );
- wxSize best(95, ret.y);
+ wxSize best(95, ret.y); // FIXME: 95?
CacheBestSize(best);
return best;
}
#include "wx/gtk/private.h"
#include <gdk/gdkkeysyms.h>
-//-----------------------------------------------------------------------------
-// data
-//-----------------------------------------------------------------------------
-
-extern wxWindowGTK *g_delayedFocus;
-
// ----------------------------------------------------------------------------
// helpers
// ----------------------------------------------------------------------------
return GTK_WIDGET(m_text);
}
-bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxTextCtrl::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
if ( IsMultiLine() )
{
- return window == gtk_text_view_get_window( GTK_TEXT_VIEW( m_text ), GTK_TEXT_WINDOW_TEXT ); // pure guesswork
+ return gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
+ GTK_TEXT_WINDOW_TEXT );
}
else
{
- return (window == GTK_ENTRY(m_text)->text_area);
+ return GTK_ENTRY(m_text)->text_area;
}
}
event.Enable( CanRedo() );
}
-void wxTextCtrl::OnInternalIdle()
-{
- // Check if we have to show window now
- if (GtkShowFromOnIdle()) return;
-
- if (g_delayedFocus == this)
- {
- if (GTK_WIDGET_REALIZED(m_widget))
- {
- gtk_widget_grab_focus( m_widget );
- g_delayedFocus = NULL;
- }
- }
-
- if (wxUpdateUIEvent::CanUpdate(this))
- UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
wxSize wxTextCtrl::DoGetBestSize() const
{
// FIXME should be different for multi-line controls...
#include "wx/gtk/private.h"
extern bool g_blockEventsOnDrag;
-extern wxCursor g_globalCursor;
extern "C" {
static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
}
-bool wxToggleBitmapButton::IsOwnGtkWindow(GdkWindow *window)
+GdkWindow *
+wxToggleBitmapButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- return window == GTK_BUTTON(m_widget)->event_window;
+ return GTK_BUTTON(m_widget)->event_window;
}
-void wxToggleBitmapButton::OnInternalIdle()
-{
- // Check if we have to show window now
- if (GtkShowFromOnIdle()) return;
-
- wxCursor cursor = m_cursor;
-
- if (g_globalCursor.Ok())
- cursor = g_globalCursor;
-
- GdkWindow *win = GTK_BUTTON(m_widget)->event_window;
- if ( win && cursor.Ok() )
- {
- /* I now set the cursor the anew in every OnInternalIdle call
- as setting the cursor in a parent window also effects the
- windows above so that checking for the current cursor is
- not possible. */
-
- gdk_window_set_cursor(win, cursor.GetCursor());
- }
-
- if (wxUpdateUIEvent::CanUpdate(this))
- UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
-
// Get the "best" size for this control.
wxSize wxToggleBitmapButton::DoGetBestSize() const
{
gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
}
-bool wxToggleButton::IsOwnGtkWindow(GdkWindow *window)
+GdkWindow *
+wxToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
{
- return window == GTK_BUTTON(m_widget)->event_window;
+ return GTK_BUTTON(m_widget)->event_window;
}
-void wxToggleButton::OnInternalIdle()
-{
- wxCursor cursor = m_cursor;
-
- if (g_globalCursor.Ok())
- cursor = g_globalCursor;
-
- GdkWindow *win = GTK_BUTTON(m_widget)->event_window;
- if ( win && cursor.Ok() )
- {
- /* I now set the cursor the anew in every OnInternalIdle call
- as setting the cursor in a parent window also effects the
- windows above so that checking for the current cursor is
- not possible. */
-
- gdk_window_set_cursor(win, cursor.GetCursor());
- }
-
- if (wxUpdateUIEvent::CanUpdate(this))
- UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
-
// Get the "best" size for this control.
wxSize wxToggleButton::DoGetBestSize() const
{
return win;
}
+// ----------------------------------------------------------------------------
+// common event handlers helpers
+// ----------------------------------------------------------------------------
+
+bool wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const
+{
+ DEBUG_MAIN_THREAD
+
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+
+ if (!m_hasVMT)
+ return false;
+ if (g_blockEventsOnDrag)
+ return true;
+ if (g_blockEventsOnScroll)
+ return true;
+
+ if (!GTKIsOwnWindow(event->window))
+ return false;
+
+ return true;
+}
+
+// overloads for all GDK event types we use here: we need to have this as
+// GdkEventXXX can't be implicitly cast to GdkEventAny even if it, in fact,
+// derives from it in the sense that the structs have the same layout
+#define wxDEFINE_COMMON_PROLOGUE_OVERLOAD(T) \
+ static bool wxGtkCallbackCommonPrologue(T *event, wxWindowGTK *win) \
+ { \
+ return win->GTKCallbackCommonPrologue((GdkEventAny *)event); \
+ }
+
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventButton)
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventMotion)
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventCrossing)
+
+#undef wxDEFINE_COMMON_PROLOGUE_OVERLOAD
+
+// send the wxChildFocusEvent and wxFocusEvent, common code of
+// gtk_window_focus_in_callback() and SetFocus()
+static bool DoSendFocusEvents(wxWindow *win)
+{
+ // Notify the parent keeping track of focus for the kbd navigation
+ // purposes that we got it.
+ wxChildFocusEvent eventChildFocus(win);
+ (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
+
+ wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
+ eventFocus.SetEventObject(win);
+
+ return win->GetEventHandler()->ProcessEvent(eventFocus);
+}
+
+// all event handlers must have C linkage as they're called from GTK+ C code
+extern "C"
+{
+
//-----------------------------------------------------------------------------
// "button_press_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_button_press_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
-/*
- wxPrintf( wxT("1) OnButtonPress from ") );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( wxT(".\n") );
-*/
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return TRUE;
- if (g_blockEventsOnScroll) return TRUE;
-
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+ if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+ return FALSE;
if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
{
gtk_widget_grab_focus( win->m_wxwindow );
-/*
- wxPrintf( wxT("GrabFocus from ") );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( wxT(".\n") );
-*/
}
// GDK sends surplus button down events
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "button_release_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_button_release_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
- if (g_blockEventsOnScroll) return FALSE;
-
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+ if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+ return FALSE;
wxEventType event_type = wxEVT_NULL;
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "motion_notify_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_motion_notify_callback( GtkWidget *widget,
GdkEventMotion *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
- if (g_blockEventsOnScroll) return FALSE;
-
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+ if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+ return FALSE;
if (gdk_event->is_hint)
{
gdk_event->y = y;
}
-/*
- printf( "OnMotion from " );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- printf( win->GetClassInfo()->GetClassName() );
- printf( ".\n" );
-*/
-
wxMouseEvent event( wxEVT_MOTION );
InitMouseEvent(win, event, gdk_event);
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "scroll_event", (mouse wheel event)
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
{
return win->GetEventHandler()->ProcessEvent(event);
}
-}
//-----------------------------------------------------------------------------
// "popup-menu"
//-----------------------------------------------------------------------------
-extern "C" {
+
static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
{
- wxContextMenuEvent event(
- wxEVT_CONTEXT_MENU,
- win->GetId(),
- wxPoint(-1, -1));
+ wxContextMenuEvent event(wxEVT_CONTEXT_MENU, win->GetId(), wxPoint(-1, -1));
event.SetEventObject(win);
return win->GetEventHandler()->ProcessEvent(event);
}
-}
//-----------------------------------------------------------------------------
// "focus_in_event"
//-----------------------------------------------------------------------------
-// send the wxChildFocusEvent and wxFocusEvent, common code of
-// gtk_window_focus_in_callback() and SetFocus()
-static bool DoSendFocusEvents(wxWindow *win)
-{
- // Notify the parent keeping track of focus for the kbd navigation
- // purposes that we got it.
- wxChildFocusEvent eventChildFocus(win);
- (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
-
- wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
- eventFocus.SetEventObject(win);
-
- return win->GetEventHandler()->ProcessEvent(eventFocus);
-}
-
-extern "C" {
static gboolean
gtk_window_focus_in_callback( GtkWidget *widget,
GdkEventFocus *WXUNUSED(event),
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "focus_out_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_focus_out_callback( GtkWidget *widget,
GdkEventFocus *gdk_event,
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "enter_notify_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_enter_callback( GtkWidget *widget,
GdkEventCrossing *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
+ if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+ return FALSE;
// Event was emitted after a grab
if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
-
int x = 0;
int y = 0;
GdkModifierType state = (GdkModifierType)0;
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "leave_notify_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_leave_callback( GtkWidget *widget,
GdkEventCrossing *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
+ if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+ return FALSE;
// Event was emitted after an ungrab
if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
-
wxMouseEvent event( wxEVT_LEAVE_WINDOW );
event.SetTimestamp( gdk_event->time );
event.SetEventObject( win );
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "value_changed" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static void
gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
{
win->m_blockValueChanged[dir] = false;
}
}
-}
//-----------------------------------------------------------------------------
// "button_press_event" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win)
{
return false;
}
-}
//-----------------------------------------------------------------------------
// "event_after" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static void
gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win)
{
win->GetEventHandler()->ProcessEvent(event);
}
}
-}
//-----------------------------------------------------------------------------
// "button_release_event" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* win)
{
return false;
}
-}
-
-// ----------------------------------------------------------------------------
-// this wxWindowBase function is implemented here (in platform-specific file)
-// because it is static and so couldn't be made virtual
-// ----------------------------------------------------------------------------
-
-wxWindow *wxWindowBase::DoFindFocus()
-{
- // the cast is necessary when we compile in wxUniversal mode
- return (wxWindow *)g_focusWindow;
-}
//-----------------------------------------------------------------------------
// "realize" from m_widget
/* We cannot set colours and fonts before the widget has
been realized, so we do this directly after realization. */
-extern "C" {
static void
gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
{
event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
}
-}
//-----------------------------------------------------------------------------
// "size_allocate"
//-----------------------------------------------------------------------------
-extern "C" {
static
void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
GtkAllocation *WXUNUSED(alloc),
win->GetEventHandler()->ProcessEvent( event );
}
}
-}
#ifdef HAVE_XIM
#endif
/* Resize XIM window */
-
-extern "C" {
static
void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
}
#endif // HAVE_XIM
}
-}
//-----------------------------------------------------------------------------
// "realize" from m_wxwindow
/* Initialize XIM support */
-extern "C" {
static void
gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
wxWindowGTK * WXUNUSED_UNLESS_XIM(win) )
}
#endif // HAVE_XIM
}
+
+} // extern "C"
+
+// ----------------------------------------------------------------------------
+// this wxWindowBase function is implemented here (in platform-specific file)
+// because it is static and so couldn't be made virtual
+// ----------------------------------------------------------------------------
+
+wxWindow *wxWindowBase::DoFindFocus()
+{
+ // the cast is necessary when we compile in wxUniversal mode
+ return (wxWindow *)g_focusWindow;
}
//-----------------------------------------------------------------------------
g_object_unref (layout);
}
+bool wxWindowGTK::GTKSetDelayedFocusIfNeeded()
+{
+ if ( g_delayedFocus == this )
+ {
+ if ( GTK_WIDGET_REALIZED(m_widget) )
+ {
+ gtk_widget_grab_focus(m_widget);
+ g_delayedFocus = NULL;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
void wxWindowGTK::SetFocus()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
if (g_isIdle)
wxapp_install_idle_handler();
- if (cursor == wxNullCursor)
- return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR );
- else
- return wxWindowBase::SetCursor( cursor );
+ return wxWindowBase::SetCursor( cursor.Ok() ? cursor : *wxSTANDARD_CURSOR );
+}
+
+void wxWindowGTK::GTKUpdateCursor()
+{
+ wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
+ if ( cursor.Ok() )
+ {
+ wxArrayGdkWindows windowsThis;
+ GdkWindow * const winThis = GTKGetWindow(windowsThis);
+ if ( winThis )
+ {
+ gdk_window_set_cursor(winThis, cursor.GetCursor());
+ }
+ else
+ {
+ const size_t count = windowsThis.size();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ gdk_window_set_cursor(windowsThis[n], cursor.GetCursor());
+ }
+ }
+ }
}
void wxWindowGTK::WarpPointer( int x, int y )
return connect_widget;
}
-bool wxWindowGTK::IsOwnGtkWindow( GdkWindow *window )
+bool wxWindowGTK::GTKIsOwnWindow(GdkWindow *window) const
{
- if (m_wxwindow)
- return (window == GTK_PIZZA(m_wxwindow)->bin_window);
+ wxArrayGdkWindows windowsThis;
+ GdkWindow * const winThis = GTKGetWindow(windowsThis);
- return (window == m_widget->window);
+ return winThis ? window == winThis
+ : windowsThis.Index(window) != wxNOT_FOUND;
+}
+
+GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
+{
+ return m_wxwindow ? GTK_PIZZA(m_wxwindow)->bin_window : m_widget->window;
}
bool wxWindowGTK::SetFont( const wxFont &font )