Add animation of activation by, on activate, pressing the button, and

Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtkbutton.c: Add animation of activation by, on
	activate, pressing the button, and adding a timeout that
	releases the button after 250ms	or on key release and
	emits ::clicked. (#51501)

	* gtk/gtkdialog.c: Bit of a hack - for buttons in the
	action area, we connect to ::clicked instead of ::activate
	so the dialog stays up through the animation.

Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
	check the ignore_enter flag for the menu shell that
	the item is actually a child of, not for attached
	submenus. (#51536)
This commit is contained in:
Owen Taylor 2001-03-06 15:51:10 +00:00 committed by Owen Taylor
parent 96f9c875ee
commit 71aa1161b3
11 changed files with 371 additions and 8 deletions

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -1,3 +1,36 @@
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)
* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.
Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
2001-03-06 James Henstridge <james@daa.com.au> 2001-03-06 James Henstridge <james@daa.com.au>
* gtk/gtkwidget.c (gtk_widget_class_init): set the class closure * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@ -55,6 +88,7 @@ Mon Mar 5 14:38:54 2001 Jonathan Blandford <jrb@redhat.com>
parent_class pointer in pixbuf_style_class_init(). parent_class pointer in pixbuf_style_class_init().
(Will commit the fix to the pixbuf-engine too). (Will commit the fix to the pixbuf-engine too).
>>>>>>> 1.1779
2001-03-05 Alexander Larsson <alexl@redhat.com> 2001-03-05 Alexander Larsson <alexl@redhat.com>
* gdk/gdkwindow.h: * gdk/gdkwindow.h:

View File

@ -39,6 +39,10 @@
#define DEFAULT_TOP_POS 4 #define DEFAULT_TOP_POS 4
#define DEFAULT_SPACING 7 #define DEFAULT_SPACING 7
/* Time out before giving up on getting a key release when animatng
* the close button.
*/
#define ACTIVATE_TIMEOUT 250
enum { enum {
PRESSED, PRESSED,
@ -46,6 +50,7 @@ enum {
CLICKED, CLICKED,
ENTER, ENTER,
LEAVE, LEAVE,
ACTIVATE,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -55,8 +60,6 @@ enum {
ARG_RELIEF ARG_RELIEF
}; };
static void gtk_button_class_init (GtkButtonClass *klass); static void gtk_button_class_init (GtkButtonClass *klass);
static void gtk_button_init (GtkButton *button); static void gtk_button_init (GtkButton *button);
static void gtk_button_set_arg (GtkObject *object, static void gtk_button_set_arg (GtkObject *object,
@ -66,6 +69,7 @@ static void gtk_button_get_arg (GtkObject *object,
GtkArg *arg, GtkArg *arg,
guint arg_id); guint arg_id);
static void gtk_button_realize (GtkWidget *widget); static void gtk_button_realize (GtkWidget *widget);
static void gtk_button_unrealize (GtkWidget *widget);
static void gtk_button_size_request (GtkWidget *widget, static void gtk_button_size_request (GtkWidget *widget,
GtkRequisition *requisition); GtkRequisition *requisition);
static void gtk_button_size_allocate (GtkWidget *widget, static void gtk_button_size_allocate (GtkWidget *widget,
@ -78,6 +82,8 @@ static gint gtk_button_button_press (GtkWidget *widget,
GdkEventButton *event); GdkEventButton *event);
static gint gtk_button_button_release (GtkWidget *widget, static gint gtk_button_button_release (GtkWidget *widget,
GdkEventButton *event); GdkEventButton *event);
static gint gtk_button_key_release (GtkWidget *widget,
GdkEventKey *event);
static gint gtk_button_enter_notify (GtkWidget *widget, static gint gtk_button_enter_notify (GtkWidget *widget,
GdkEventCrossing *event); GdkEventCrossing *event);
static gint gtk_button_leave_notify (GtkWidget *widget, static gint gtk_button_leave_notify (GtkWidget *widget,
@ -90,8 +96,11 @@ static void gtk_real_button_pressed (GtkButton *button);
static void gtk_real_button_released (GtkButton *button); static void gtk_real_button_released (GtkButton *button);
static void gtk_real_button_enter (GtkButton *button); static void gtk_real_button_enter (GtkButton *button);
static void gtk_real_button_leave (GtkButton *button); static void gtk_real_button_leave (GtkButton *button);
static void gtk_real_button_activate (GtkButton *button);
static GtkType gtk_button_child_type (GtkContainer *container); static GtkType gtk_button_child_type (GtkContainer *container);
static void gtk_button_finish_activate (GtkButton *button,
gboolean do_it);
static GtkBinClass *parent_class = NULL; static GtkBinClass *parent_class = NULL;
static guint button_signals[LAST_SIGNAL] = { 0 }; static guint button_signals[LAST_SIGNAL] = { 0 };
@ -141,11 +150,13 @@ gtk_button_class_init (GtkButtonClass *klass)
object_class->get_arg = gtk_button_get_arg; object_class->get_arg = gtk_button_get_arg;
widget_class->realize = gtk_button_realize; widget_class->realize = gtk_button_realize;
widget_class->unrealize = gtk_button_unrealize;
widget_class->size_request = gtk_button_size_request; widget_class->size_request = gtk_button_size_request;
widget_class->size_allocate = gtk_button_size_allocate; widget_class->size_allocate = gtk_button_size_allocate;
widget_class->expose_event = gtk_button_expose; widget_class->expose_event = gtk_button_expose;
widget_class->button_press_event = gtk_button_button_press; widget_class->button_press_event = gtk_button_button_press;
widget_class->button_release_event = gtk_button_button_release; widget_class->button_release_event = gtk_button_button_release;
widget_class->key_release_event = gtk_button_key_release;
widget_class->enter_notify_event = gtk_button_enter_notify; widget_class->enter_notify_event = gtk_button_enter_notify;
widget_class->leave_notify_event = gtk_button_leave_notify; widget_class->leave_notify_event = gtk_button_leave_notify;
@ -158,6 +169,7 @@ gtk_button_class_init (GtkButtonClass *klass)
klass->clicked = NULL; klass->clicked = NULL;
klass->enter = gtk_real_button_enter; klass->enter = gtk_real_button_enter;
klass->leave = gtk_real_button_leave; klass->leave = gtk_real_button_leave;
klass->activate = gtk_real_button_activate;
gtk_object_add_arg_type ("GtkButton::label", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_LABEL); gtk_object_add_arg_type ("GtkButton::label", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_LABEL);
gtk_object_add_arg_type ("GtkButton::relief", GTK_TYPE_RELIEF_STYLE, GTK_ARG_READWRITE, ARG_RELIEF); gtk_object_add_arg_type ("GtkButton::relief", GTK_TYPE_RELIEF_STYLE, GTK_ARG_READWRITE, ARG_RELIEF);
@ -183,7 +195,6 @@ gtk_button_class_init (GtkButtonClass *klass)
GTK_SIGNAL_OFFSET (GtkButtonClass, clicked), GTK_SIGNAL_OFFSET (GtkButtonClass, clicked),
gtk_marshal_VOID__VOID, gtk_marshal_VOID__VOID,
GTK_TYPE_NONE, 0); GTK_TYPE_NONE, 0);
widget_class->activate_signal = button_signals[CLICKED];
button_signals[ENTER] = button_signals[ENTER] =
gtk_signal_new ("enter", gtk_signal_new ("enter",
GTK_RUN_FIRST, GTK_RUN_FIRST,
@ -198,6 +209,14 @@ gtk_button_class_init (GtkButtonClass *klass)
GTK_SIGNAL_OFFSET (GtkButtonClass, leave), GTK_SIGNAL_OFFSET (GtkButtonClass, leave),
gtk_marshal_VOID__VOID, gtk_marshal_VOID__VOID,
GTK_TYPE_NONE, 0); GTK_TYPE_NONE, 0);
button_signals[ACTIVATE] =
gtk_signal_new ("activate",
GTK_RUN_FIRST,
GTK_CLASS_TYPE (object_class),
GTK_SIGNAL_OFFSET (GtkButtonClass, activate),
gtk_marshal_VOID__VOID,
GTK_TYPE_NONE, 0);
widget_class->activate_signal = button_signals[ACTIVATE];
} }
static void static void
@ -493,6 +512,17 @@ gtk_button_realize (GtkWidget *widget)
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
} }
static void
gtk_button_unrealize (GtkWidget *widget)
{
GtkButton *button = GTK_BUTTON (widget);
if (button->activate_timeout)
gtk_button_finish_activate (button, FALSE);
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
}
static void static void
gtk_button_size_request (GtkWidget *widget, gtk_button_size_request (GtkWidget *widget,
GtkRequisition *requisition) GtkRequisition *requisition)
@ -749,6 +779,23 @@ gtk_button_button_release (GtkWidget *widget,
return TRUE; return TRUE;
} }
static gboolean
gtk_button_key_release (GtkWidget *widget,
GdkEventKey *event)
{
GtkButton *button = GTK_BUTTON (widget);
if (button->activate_timeout)
{
gtk_button_finish_activate (button, TRUE);
return TRUE;
}
else if (GTK_WIDGET_CLASS (parent_class)->key_release_event)
return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
else
return FALSE;
}
static gint static gint
gtk_button_enter_notify (GtkWidget *widget, gtk_button_enter_notify (GtkWidget *widget,
GdkEventCrossing *event) GdkEventCrossing *event)
@ -831,6 +878,9 @@ gtk_real_button_pressed (GtkButton *button)
g_return_if_fail (button != NULL); g_return_if_fail (button != NULL);
g_return_if_fail (GTK_IS_BUTTON (button)); g_return_if_fail (GTK_IS_BUTTON (button));
if (button->activate_timeout)
return;
button->button_down = TRUE; button->button_down = TRUE;
new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL); new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
@ -854,6 +904,9 @@ gtk_real_button_released (GtkButton *button)
{ {
button->button_down = FALSE; button->button_down = FALSE;
if (button->activate_timeout)
return;
if (button->in_button) if (button->in_button)
gtk_button_clicked (button); gtk_button_clicked (button);
@ -880,6 +933,9 @@ gtk_real_button_enter (GtkButton *button)
new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT); new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
if (button->activate_timeout)
return;
if (GTK_WIDGET_STATE (button) != new_state) if (GTK_WIDGET_STATE (button) != new_state)
{ {
gtk_widget_set_state (GTK_WIDGET (button), new_state); gtk_widget_set_state (GTK_WIDGET (button), new_state);
@ -892,10 +948,66 @@ gtk_real_button_leave (GtkButton *button)
{ {
g_return_if_fail (button != NULL); g_return_if_fail (button != NULL);
g_return_if_fail (GTK_IS_BUTTON (button)); g_return_if_fail (GTK_IS_BUTTON (button));
if (button->activate_timeout)
return;
if (GTK_WIDGET_STATE (button) != GTK_STATE_NORMAL) if (GTK_WIDGET_STATE (button) != GTK_STATE_NORMAL)
{ {
gtk_widget_set_state (GTK_WIDGET (button), GTK_STATE_NORMAL); gtk_widget_set_state (GTK_WIDGET (button), GTK_STATE_NORMAL);
gtk_widget_queue_draw (GTK_WIDGET (button)); gtk_widget_queue_draw (GTK_WIDGET (button));
} }
} }
static gboolean
button_activate_timeout (gpointer data)
{
gtk_button_finish_activate (data, TRUE);
return FALSE;
}
static void
gtk_real_button_activate (GtkButton *button)
{
GtkWidget *widget = GTK_WIDGET (button);
g_return_if_fail (button != NULL);
g_return_if_fail (GTK_IS_BUTTON (button));
if (GTK_WIDGET_REALIZED (button) && !button->activate_timeout)
{
if (gdk_keyboard_grab (widget->window, TRUE,
gtk_get_current_event_time ()) == 0)
{
gtk_grab_add (widget);
button->activate_timeout = g_timeout_add (ACTIVATE_TIMEOUT,
button_activate_timeout,
button);
button->button_down = TRUE;
gtk_widget_set_state (widget, GTK_STATE_ACTIVE);
}
}
}
static void
gtk_button_finish_activate (GtkButton *button,
gboolean do_it)
{
GtkWidget *widget = GTK_WIDGET (button);
g_source_remove (button->activate_timeout);
button->activate_timeout = 0;
gdk_keyboard_ungrab (gtk_get_current_event_time ());
gtk_grab_remove (widget);
button->button_down = FALSE;
gtk_widget_set_state (GTK_WIDGET (button),
button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
if (do_it)
gtk_button_clicked (button);
}

View File

@ -56,6 +56,8 @@ struct _GtkButton
* use GTK_BIN (button)->child instead * use GTK_BIN (button)->child instead
*/; */;
guint activate_timeout;
guint in_button : 1; guint in_button : 1;
guint button_down : 1; guint button_down : 1;
guint relief : 2; guint relief : 2;
@ -70,6 +72,7 @@ struct _GtkButtonClass
void (* clicked) (GtkButton *button); void (* clicked) (GtkButton *button);
void (* enter) (GtkButton *button); void (* enter) (GtkButton *button);
void (* leave) (GtkButton *button); void (* leave) (GtkButton *button);
void (* activate) (GtkButton *button);
}; };

View File

@ -340,6 +340,7 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
gint response_id) gint response_id)
{ {
ResponseData *ad; ResponseData *ad;
gint signal_id = 0;
g_return_if_fail (GTK_IS_DIALOG (dialog)); g_return_if_fail (GTK_IS_DIALOG (dialog));
g_return_if_fail (GTK_IS_WIDGET (child)); g_return_if_fail (GTK_IS_WIDGET (child));
@ -348,10 +349,16 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
ad->response_id = response_id; ad->response_id = response_id;
if (GTK_WIDGET_GET_CLASS (child)->activate_signal != 0) if (GTK_IS_BUTTON (child))
{ {
const gchar* name = signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
gtk_signal_name (GTK_WIDGET_GET_CLASS (child)->activate_signal); }
else
signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal != 0;
if (signal_id)
{
const gchar* name = gtk_signal_name (signal_id);
gtk_signal_connect_while_alive (GTK_OBJECT (child), gtk_signal_connect_while_alive (GTK_OBJECT (child),
name, name,

View File

@ -585,7 +585,7 @@ gtk_menu_shell_enter_notify (GtkWidget *widget,
menu_shell = GTK_MENU_SHELL (widget); menu_shell = GTK_MENU_SHELL (widget);
if (menu_shell->active && !menu_shell->ignore_enter) if (menu_shell->active)
{ {
menu_item = gtk_get_event_widget ((GdkEvent*) event); menu_item = gtk_get_event_widget ((GdkEvent*) event);
@ -596,6 +596,9 @@ gtk_menu_shell_enter_notify (GtkWidget *widget,
(menu_shell->active_menu_item != menu_item) && (menu_shell->active_menu_item != menu_item) &&
GTK_IS_MENU_ITEM (menu_item)) GTK_IS_MENU_ITEM (menu_item))
{ {
if (menu_shell->ignore_enter)
return TRUE;
if ((event->detail != GDK_NOTIFY_INFERIOR) && if ((event->detail != GDK_NOTIFY_INFERIOR) &&
(GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT)) (GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT))
{ {