-void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *win )
-{
-/*
- printf( "OnScroll from " );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- printf( win->GetClassInfo()->GetClassName() );
- printf( ".\n" );
-*/
-
- if (!win->HasVMT()) return;
-
- float diff = win->m_adjust->value - win->m_oldPos;
- if (fabs(diff) < 0.2) return;
-
- wxEventType command = wxEVT_NULL;
-
- float line_step = win->m_adjust->step_increment;
- float page_step = win->m_adjust->page_increment;
-
- if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
- else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
- else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
- else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
- else command = wxEVT_SCROLL_THUMBTRACK;
-
- int value = (int)(win->m_adjust->value+0.5);
-
- int orient = wxHORIZONTAL;
- if (win->GetWindowStyleFlag() & wxSB_VERTICAL == wxSB_VERTICAL) orient = wxHORIZONTAL;
-
- wxScrollEvent event( command, win->GetId(), value, orient );
- event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
-
-/*
- wxCommandEvent cevent( wxEVT_COMMAND_SCROLLBAR_UPDATED, win->GetId() );
- cevent.SetEventObject( win );
- win->ProcessEvent( cevent );
-*/
-};
+extern "C" {
+static void
+gtk_value_changed(GtkRange* range, wxScrollBar* win)
+{
+ wxEventType eventType = win->GetScrollEventType(range);
+ if (eventType != wxEVT_NULL)
+ {
+ const int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
+ const int i = orient == wxVERTICAL;
+ const int value = win->GetThumbPosition();
+ wxScrollEvent event(eventType, win->GetId(), value, orient);
+ event.SetEventObject(win);
+ win->m_blockValueChanged[i] = true;
+ win->GetEventHandler()->ProcessEvent(event);
+ if (!win->m_isScrolling)
+ {
+ wxScrollEvent event(wxEVT_SCROLL_CHANGED, win->GetId(), value, orient);
+ event.SetEventObject(win);
+ win->GetEventHandler()->ProcessEvent(event);
+ }
+ win->m_blockValueChanged[i] = false;
+ }
+}
+}
+
+//-----------------------------------------------------------------------------
+// "button_press_event" from scrollbar
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static gboolean
+gtk_button_press_event(GtkRange*, GdkEventButton*, wxScrollBar* win)
+{
+ // don't need to install idle handler, its done from "event" signal
+
+ win->m_mouseButtonDown = true;
+ return false;
+}
+}
+
+//-----------------------------------------------------------------------------
+// "event_after" from scrollbar
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static void
+gtk_event_after(GtkRange* range, GdkEvent* event, wxScrollBar* win)
+{
+ if (event->type == GDK_BUTTON_RELEASE)
+ {
+ g_signal_handlers_block_by_func(range, (void*)gtk_event_after, win);
+
+ const int value = win->GetThumbPosition();
+ const int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
+
+ wxScrollEvent event(wxEVT_SCROLL_THUMBRELEASE, win->GetId(), value, orient);
+ event.SetEventObject(win);
+ win->GetEventHandler()->ProcessEvent(event);
+
+ wxScrollEvent event2(wxEVT_SCROLL_CHANGED, win->GetId(), value, orient);
+ event2.SetEventObject(win);
+ win->GetEventHandler()->ProcessEvent(event2);
+ }
+}
+}
+
+//-----------------------------------------------------------------------------
+// "button_release_event" from scrollbar
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static gboolean
+gtk_button_release_event(GtkRange* range, GdkEventButton*, wxScrollBar* win)
+{
+ // don't need to install idle handler, its done from "event" signal
+
+ win->m_mouseButtonDown = false;
+ // If thumb tracking
+ if (win->m_isScrolling)
+ {
+ win->m_isScrolling = false;
+ // Hook up handler to send thumb release event after this emission is finished.
+ // To allow setting scroll position from event handler, sending event must
+ // be deferred until after the GtkRange handler for this signal has run
+ g_signal_handlers_unblock_by_func(range, (void*)gtk_event_after, win);
+ }
+
+ return false;
+}
+}
+
+//-----------------------------------------------------------------------------
+// wxScrollBar
+//-----------------------------------------------------------------------------