Add a "is_focus" property indicating whether a widget is the focus widget
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com> * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus" property indicating whether a widget is the focus widget within the toplevel. * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus" properties to indicate (separately) the idea of being the part of the toplevel with the input focus and being the active widget. (Needed for full XEMBED compliance.) * gtk/gtkplug.c gtk/gtksocket.c: Update to work in terms of is_active/has_toplevel_focus, and thus handle the active/focused XEMBED distinction correctly. * gtk/gtkplug.c (gtk_plug_realize): Remove FOCUS_CHANGE_MASK, since we don't need it. Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com> * gtk/gtksocket.c (gtk_socket_add_window): Send XEMBED_EMBEDDED_NOTIFY. * gtk/gtksocket.c: Assume windows without _XEMBED_INFO property want to be mapped, for better current-Qt compatibility.
This commit is contained in:
29
ChangeLog
29
ChangeLog
@ -1,3 +1,32 @@
|
||||
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
|
||||
property indicating whether a widget is the focus
|
||||
widget within the toplevel.
|
||||
|
||||
* gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
|
||||
properties to indicate (separately) the idea of
|
||||
being the part of the toplevel with the input focus
|
||||
and being the active widget. (Needed for full XEMBED
|
||||
compliance.)
|
||||
|
||||
* gtk/gtkplug.c gtk/gtksocket.c: Update to work
|
||||
in terms of is_active/has_toplevel_focus, and thus
|
||||
handle the active/focused XEMBED distinction
|
||||
correctly.
|
||||
|
||||
* gtk/gtkplug.c (gtk_plug_realize): Remove
|
||||
FOCUS_CHANGE_MASK, since we don't need it.
|
||||
|
||||
Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_add_window): Send
|
||||
XEMBED_EMBEDDED_NOTIFY.
|
||||
|
||||
* gtk/gtksocket.c: Assume windows without _XEMBED_INFO
|
||||
property want to be mapped, for better
|
||||
current-Qt compatibility.
|
||||
|
||||
Thu Jun 6 17:27:01 2002 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
* gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
|
||||
|
@ -1,3 +1,32 @@
|
||||
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
|
||||
property indicating whether a widget is the focus
|
||||
widget within the toplevel.
|
||||
|
||||
* gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
|
||||
properties to indicate (separately) the idea of
|
||||
being the part of the toplevel with the input focus
|
||||
and being the active widget. (Needed for full XEMBED
|
||||
compliance.)
|
||||
|
||||
* gtk/gtkplug.c gtk/gtksocket.c: Update to work
|
||||
in terms of is_active/has_toplevel_focus, and thus
|
||||
handle the active/focused XEMBED distinction
|
||||
correctly.
|
||||
|
||||
* gtk/gtkplug.c (gtk_plug_realize): Remove
|
||||
FOCUS_CHANGE_MASK, since we don't need it.
|
||||
|
||||
Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_add_window): Send
|
||||
XEMBED_EMBEDDED_NOTIFY.
|
||||
|
||||
* gtk/gtksocket.c: Assume windows without _XEMBED_INFO
|
||||
property want to be mapped, for better
|
||||
current-Qt compatibility.
|
||||
|
||||
Thu Jun 6 17:27:01 2002 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
* gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
|
||||
|
@ -1,3 +1,32 @@
|
||||
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
|
||||
property indicating whether a widget is the focus
|
||||
widget within the toplevel.
|
||||
|
||||
* gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
|
||||
properties to indicate (separately) the idea of
|
||||
being the part of the toplevel with the input focus
|
||||
and being the active widget. (Needed for full XEMBED
|
||||
compliance.)
|
||||
|
||||
* gtk/gtkplug.c gtk/gtksocket.c: Update to work
|
||||
in terms of is_active/has_toplevel_focus, and thus
|
||||
handle the active/focused XEMBED distinction
|
||||
correctly.
|
||||
|
||||
* gtk/gtkplug.c (gtk_plug_realize): Remove
|
||||
FOCUS_CHANGE_MASK, since we don't need it.
|
||||
|
||||
Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_add_window): Send
|
||||
XEMBED_EMBEDDED_NOTIFY.
|
||||
|
||||
* gtk/gtksocket.c: Assume windows without _XEMBED_INFO
|
||||
property want to be mapped, for better
|
||||
current-Qt compatibility.
|
||||
|
||||
Thu Jun 6 17:27:01 2002 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
* gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
|
||||
|
@ -1,3 +1,32 @@
|
||||
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
|
||||
property indicating whether a widget is the focus
|
||||
widget within the toplevel.
|
||||
|
||||
* gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
|
||||
properties to indicate (separately) the idea of
|
||||
being the part of the toplevel with the input focus
|
||||
and being the active widget. (Needed for full XEMBED
|
||||
compliance.)
|
||||
|
||||
* gtk/gtkplug.c gtk/gtksocket.c: Update to work
|
||||
in terms of is_active/has_toplevel_focus, and thus
|
||||
handle the active/focused XEMBED distinction
|
||||
correctly.
|
||||
|
||||
* gtk/gtkplug.c (gtk_plug_realize): Remove
|
||||
FOCUS_CHANGE_MASK, since we don't need it.
|
||||
|
||||
Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_add_window): Send
|
||||
XEMBED_EMBEDDED_NOTIFY.
|
||||
|
||||
* gtk/gtksocket.c: Assume windows without _XEMBED_INFO
|
||||
property want to be mapped, for better
|
||||
current-Qt compatibility.
|
||||
|
||||
Thu Jun 6 17:27:01 2002 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
* gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
|
||||
|
@ -1,3 +1,32 @@
|
||||
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
|
||||
property indicating whether a widget is the focus
|
||||
widget within the toplevel.
|
||||
|
||||
* gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
|
||||
properties to indicate (separately) the idea of
|
||||
being the part of the toplevel with the input focus
|
||||
and being the active widget. (Needed for full XEMBED
|
||||
compliance.)
|
||||
|
||||
* gtk/gtkplug.c gtk/gtksocket.c: Update to work
|
||||
in terms of is_active/has_toplevel_focus, and thus
|
||||
handle the active/focused XEMBED distinction
|
||||
correctly.
|
||||
|
||||
* gtk/gtkplug.c (gtk_plug_realize): Remove
|
||||
FOCUS_CHANGE_MASK, since we don't need it.
|
||||
|
||||
Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_add_window): Send
|
||||
XEMBED_EMBEDDED_NOTIFY.
|
||||
|
||||
* gtk/gtksocket.c: Assume windows without _XEMBED_INFO
|
||||
property want to be mapped, for better
|
||||
current-Qt compatibility.
|
||||
|
||||
Thu Jun 6 17:27:01 2002 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
* gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
|
||||
|
@ -1,3 +1,32 @@
|
||||
Fri May 17 17:27:21 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
|
||||
property indicating whether a widget is the focus
|
||||
widget within the toplevel.
|
||||
|
||||
* gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
|
||||
properties to indicate (separately) the idea of
|
||||
being the part of the toplevel with the input focus
|
||||
and being the active widget. (Needed for full XEMBED
|
||||
compliance.)
|
||||
|
||||
* gtk/gtkplug.c gtk/gtksocket.c: Update to work
|
||||
in terms of is_active/has_toplevel_focus, and thus
|
||||
handle the active/focused XEMBED distinction
|
||||
correctly.
|
||||
|
||||
* gtk/gtkplug.c (gtk_plug_realize): Remove
|
||||
FOCUS_CHANGE_MASK, since we don't need it.
|
||||
|
||||
Fri May 17 18:07:34 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_add_window): Send
|
||||
XEMBED_EMBEDDED_NOTIFY.
|
||||
|
||||
* gtk/gtksocket.c: Assume windows without _XEMBED_INFO
|
||||
property want to be mapped, for better
|
||||
current-Qt compatibility.
|
||||
|
||||
Thu Jun 6 17:27:01 2002 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
* gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
|
||||
|
@ -504,7 +504,6 @@ gtk_plug_realize (GtkWidget *widget)
|
||||
GDK_KEY_RELEASE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK |
|
||||
GDK_LEAVE_NOTIFY_MASK |
|
||||
GDK_FOCUS_CHANGE_MASK |
|
||||
GDK_STRUCTURE_MASK);
|
||||
|
||||
attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
|
||||
@ -681,7 +680,7 @@ gtk_plug_set_focus (GtkWindow *window,
|
||||
/* Ask for focus from embedder
|
||||
*/
|
||||
|
||||
if (focus && !window->has_focus)
|
||||
if (focus && !window->has_toplevel_focus)
|
||||
{
|
||||
send_xembed_message (plug, XEMBED_REQUEST_FOCUS, 0, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
@ -885,6 +884,9 @@ send_xembed_message (GtkPlug *plug,
|
||||
GdkDisplay *display = gdk_drawable_get_display (plug->socket_window);
|
||||
XEvent xevent;
|
||||
|
||||
GTK_NOTE(PLUGSOCKET,
|
||||
g_message ("GtkPlug: Sending XEMBED message of type %ld", message));
|
||||
|
||||
xevent.xclient.window = GDK_WINDOW_XWINDOW (plug->socket_window);
|
||||
xevent.xclient.type = ClientMessage;
|
||||
xevent.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED");
|
||||
@ -977,20 +979,20 @@ handle_xembed_message (GtkPlug *plug,
|
||||
glong data2,
|
||||
guint32 time)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (plug);
|
||||
|
||||
GTK_NOTE (PLUGSOCKET,
|
||||
g_message ("Message of type %ld received", message));
|
||||
g_message ("GtkPlug: Message of type %ld received", message));
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case XEMBED_EMBEDDED_NOTIFY:
|
||||
break;
|
||||
case XEMBED_WINDOW_ACTIVATE:
|
||||
GTK_NOTE(PLUGSOCKET,
|
||||
g_message ("GtkPlug: ACTIVATE received"));
|
||||
_gtk_window_set_is_active (window, TRUE);
|
||||
break;
|
||||
case XEMBED_WINDOW_DEACTIVATE:
|
||||
GTK_NOTE(PLUGSOCKET,
|
||||
g_message ("GtkPlug: DEACTIVATE received"));
|
||||
_gtk_window_set_is_active (window, FALSE);
|
||||
break;
|
||||
|
||||
case XEMBED_MODALITY_ON:
|
||||
@ -1001,6 +1003,7 @@ handle_xembed_message (GtkPlug *plug,
|
||||
break;
|
||||
|
||||
case XEMBED_FOCUS_IN:
|
||||
_gtk_window_set_has_toplevel_focus (window, TRUE);
|
||||
switch (detail)
|
||||
{
|
||||
case XEMBED_FOCUS_FIRST:
|
||||
@ -1010,31 +1013,13 @@ handle_xembed_message (GtkPlug *plug,
|
||||
focus_first_last (plug, GTK_DIR_TAB_BACKWARD);
|
||||
break;
|
||||
case XEMBED_FOCUS_CURRENT:
|
||||
/* fall through */;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case XEMBED_FOCUS_OUT:
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (plug);
|
||||
GdkEvent event;
|
||||
|
||||
event.focus_change.type = GDK_FOCUS_CHANGE;
|
||||
event.focus_change.window = widget->window;
|
||||
event.focus_change.send_event = TRUE;
|
||||
|
||||
if (message == XEMBED_FOCUS_IN)
|
||||
{
|
||||
event.focus_change.in = TRUE;
|
||||
GTK_WIDGET_CLASS (parent_class)->focus_in_event (widget, (GdkEventFocus *)&event);
|
||||
}
|
||||
else
|
||||
{
|
||||
event.focus_change.in = FALSE;
|
||||
GTK_WIDGET_CLASS (parent_class)->focus_out_event (widget, (GdkEventFocus *)&event);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
_gtk_window_set_has_toplevel_focus (window, FALSE);
|
||||
break;
|
||||
|
||||
case XEMBED_GRAB_KEY:
|
||||
case XEMBED_UNGRAB_KEY:
|
||||
|
156
gtk/gtksocket.c
156
gtk/gtksocket.c
@ -25,6 +25,8 @@
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gdk/gdkkeysyms.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmarshalers.h"
|
||||
@ -51,6 +53,8 @@ struct _GtkSocketPrivate
|
||||
static void gtk_socket_class_init (GtkSocketClass *klass);
|
||||
static void gtk_socket_init (GtkSocket *socket);
|
||||
static void gtk_socket_finalize (GObject *object);
|
||||
static void gtk_socket_notify (GObject *object,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_socket_realize (GtkWidget *widget);
|
||||
static void gtk_socket_unrealize (GtkWidget *widget);
|
||||
static void gtk_socket_size_request (GtkWidget *widget,
|
||||
@ -63,11 +67,8 @@ static void gtk_socket_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed);
|
||||
static gboolean gtk_socket_key_press_event (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static gboolean gtk_socket_focus_in_event (GtkWidget *widget,
|
||||
GdkEventFocus *event);
|
||||
static void gtk_socket_claim_focus (GtkSocket *socket);
|
||||
static gboolean gtk_socket_focus_out_event (GtkWidget *widget,
|
||||
GdkEventFocus *event);
|
||||
static void gtk_socket_claim_focus (GtkSocket *socket,
|
||||
gboolean send_event);
|
||||
static void gtk_socket_send_configure_event (GtkSocket *socket);
|
||||
static gboolean gtk_socket_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
@ -125,6 +126,8 @@ gtk_socket_get_private (GtkSocket *socket)
|
||||
if (!private)
|
||||
{
|
||||
private = g_new0 (GtkSocketPrivate, 1);
|
||||
private->resize_count = 0;
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (socket), private_quark,
|
||||
private, (GDestroyNotify) g_free);
|
||||
}
|
||||
@ -183,6 +186,7 @@ gtk_socket_class_init (GtkSocketClass *class)
|
||||
parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
|
||||
|
||||
gobject_class->finalize = gtk_socket_finalize;
|
||||
gobject_class->notify = gtk_socket_notify;
|
||||
|
||||
widget_class->realize = gtk_socket_realize;
|
||||
widget_class->unrealize = gtk_socket_unrealize;
|
||||
@ -191,8 +195,6 @@ gtk_socket_class_init (GtkSocketClass *class)
|
||||
widget_class->hierarchy_changed = gtk_socket_hierarchy_changed;
|
||||
widget_class->grab_notify = gtk_socket_grab_notify;
|
||||
widget_class->key_press_event = gtk_socket_key_press_event;
|
||||
widget_class->focus_in_event = gtk_socket_focus_in_event;
|
||||
widget_class->focus_out_event = gtk_socket_focus_out_event;
|
||||
widget_class->focus = gtk_socket_focus;
|
||||
|
||||
container_class->remove = gtk_socket_remove;
|
||||
@ -229,6 +231,7 @@ gtk_socket_init (GtkSocket *socket)
|
||||
socket->focus_in = FALSE;
|
||||
socket->have_size = FALSE;
|
||||
socket->need_map = FALSE;
|
||||
socket->active = FALSE;
|
||||
|
||||
socket->accel_group = gtk_accel_group_new ();
|
||||
g_object_set_data (G_OBJECT (socket->accel_group), "gtk-socket", socket);
|
||||
@ -660,32 +663,60 @@ remove_grabbed_key (GtkSocket *socket,
|
||||
keyval, modifiers);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toplevel_focus_in_handler (GtkWidget *toplevel,
|
||||
GdkEventFocus *event,
|
||||
GtkSocket *socket)
|
||||
static void
|
||||
socket_update_focus_in (GtkSocket *socket)
|
||||
{
|
||||
/* It appears spurious focus in events can occur when
|
||||
* the window is hidden. So we'll just check to see if
|
||||
* the window is visible before actually handling the
|
||||
* event. (Comment from gtkwindow.c)
|
||||
*/
|
||||
if (GTK_WIDGET_VISIBLE (toplevel))
|
||||
send_xembed_message (socket, XEMBED_WINDOW_ACTIVATE, 0, 0, 0,
|
||||
gtk_get_current_event_time ()); /* Will be GDK_CURRENT_TIME */
|
||||
gboolean focus_in = FALSE;
|
||||
|
||||
return FALSE;
|
||||
if (socket->plug_window)
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
|
||||
if (GTK_WIDGET_TOPLEVEL (toplevel) &&
|
||||
GTK_WINDOW (toplevel)->has_toplevel_focus &&
|
||||
gtk_widget_is_focus (GTK_WIDGET (socket)))
|
||||
focus_in = TRUE;
|
||||
}
|
||||
|
||||
if (focus_in != socket->focus_in)
|
||||
{
|
||||
socket->focus_in = focus_in;
|
||||
|
||||
if (focus_in)
|
||||
{
|
||||
send_xembed_message (socket, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
}
|
||||
else
|
||||
{
|
||||
send_xembed_message (socket, XEMBED_FOCUS_OUT, 0, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toplevel_focus_out_handler (GtkWidget *toplevel,
|
||||
GdkEventFocus *event,
|
||||
GtkSocket *socket)
|
||||
static void
|
||||
socket_update_active (GtkSocket *socket)
|
||||
{
|
||||
send_xembed_message (socket, XEMBED_WINDOW_DEACTIVATE, 0, 0, 0,
|
||||
gtk_get_current_event_time ()); /* Will be GDK_CURRENT_TIME */
|
||||
gboolean active = FALSE;
|
||||
|
||||
return FALSE;
|
||||
if (socket->plug_window)
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
|
||||
if (GTK_WIDGET_TOPLEVEL (toplevel) &&
|
||||
GTK_WINDOW (toplevel)->is_active)
|
||||
active = TRUE;
|
||||
}
|
||||
|
||||
if (active != socket->active)
|
||||
{
|
||||
socket->active = active;
|
||||
|
||||
send_xembed_message (socket,
|
||||
active ? XEMBED_WINDOW_ACTIVATE : XEMBED_WINDOW_DEACTIVATE,
|
||||
0, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -703,8 +734,10 @@ gtk_socket_hierarchy_changed (GtkWidget *widget,
|
||||
if (socket->toplevel)
|
||||
{
|
||||
gtk_window_remove_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_focus_in_handler), socket);
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_focus_out_handler), socket);
|
||||
g_signal_handlers_disconnect_by_func (socket->toplevel,
|
||||
(gpointer) socket_update_focus_in, socket);
|
||||
g_signal_handlers_disconnect_by_func (socket->toplevel,
|
||||
(gpointer) socket_update_active, socket);
|
||||
}
|
||||
|
||||
socket->toplevel = toplevel;
|
||||
@ -712,11 +745,14 @@ gtk_socket_hierarchy_changed (GtkWidget *widget,
|
||||
if (toplevel)
|
||||
{
|
||||
gtk_window_add_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
|
||||
gtk_signal_connect (GTK_OBJECT (socket->toplevel), "focus_in_event",
|
||||
GTK_SIGNAL_FUNC (toplevel_focus_in_handler), socket);
|
||||
gtk_signal_connect (GTK_OBJECT (socket->toplevel), "focus_out_event",
|
||||
GTK_SIGNAL_FUNC (toplevel_focus_out_handler), socket);
|
||||
g_signal_connect_swapped (socket->toplevel, "notify::has_toplevel_focus",
|
||||
G_CALLBACK (socket_update_focus_in), socket);
|
||||
g_signal_connect_swapped (socket->toplevel, "notify::is_active",
|
||||
G_CALLBACK (socket_update_active), socket);
|
||||
}
|
||||
|
||||
socket_update_focus_in (socket);
|
||||
socket_update_active (socket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -769,39 +805,23 @@ gtk_socket_key_press_event (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_socket_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
|
||||
static void
|
||||
gtk_socket_notify (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkSocket *socket = GTK_SOCKET (widget);
|
||||
if (!strcmp (pspec->name, "is_focus"))
|
||||
return;
|
||||
|
||||
if (socket->plug_window)
|
||||
send_xembed_message (socket, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_socket_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
|
||||
{
|
||||
GtkSocket *socket = GTK_SOCKET (widget);
|
||||
if (socket->plug_window)
|
||||
{
|
||||
send_xembed_message (socket, XEMBED_FOCUS_OUT, 0, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
}
|
||||
|
||||
socket->focus_in = FALSE;
|
||||
|
||||
return TRUE;
|
||||
socket_update_focus_in (GTK_SOCKET (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_socket_claim_focus (GtkSocket *socket)
|
||||
gtk_socket_claim_focus (GtkSocket *socket,
|
||||
gboolean send_event)
|
||||
{
|
||||
if (!send_event)
|
||||
socket->focus_in = TRUE; /* Otherwise, our notify handler will send FOCUS_IN */
|
||||
|
||||
socket->focus_in = TRUE;
|
||||
|
||||
/* Oh, the trickery... */
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (socket, GTK_CAN_FOCUS);
|
||||
@ -841,8 +861,7 @@ gtk_socket_focus (GtkWidget *widget, GtkDirectionType direction)
|
||||
send_xembed_message (socket, XEMBED_FOCUS_IN, detail, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
|
||||
gtk_widget_grab_focus (widget);
|
||||
gtk_socket_claim_focus (socket, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -916,7 +935,6 @@ gtk_socket_add_window (GtkSocket *socket,
|
||||
GdkNativeWindow xid,
|
||||
gboolean need_reparent)
|
||||
{
|
||||
|
||||
GtkWidget *widget = GTK_WIDGET (socket);
|
||||
GdkDisplay *display = gtk_widget_get_display (widget);
|
||||
gpointer user_data = NULL;
|
||||
@ -996,7 +1014,7 @@ gtk_socket_add_window (GtkSocket *socket,
|
||||
{
|
||||
/* FIXME, we should probably actually check the state before we started */
|
||||
|
||||
socket->is_mapped = need_reparent ? TRUE : FALSE;
|
||||
socket->is_mapped = TRUE;
|
||||
}
|
||||
|
||||
socket->need_map = socket->is_mapped;
|
||||
@ -1017,6 +1035,11 @@ gtk_socket_add_window (GtkSocket *socket,
|
||||
if (toplevel && GTK_IS_WINDOW (toplevel))
|
||||
gtk_window_add_embedded_xid (GTK_WINDOW (toplevel), xid);
|
||||
|
||||
send_xembed_message (socket, XEMBED_EMBEDDED_NOTIFY, 0, 0, 0,
|
||||
gtk_get_current_event_time ());
|
||||
socket_update_active (socket);
|
||||
socket_update_focus_in (socket);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (socket));
|
||||
}
|
||||
|
||||
@ -1120,6 +1143,9 @@ handle_xembed_message (GtkSocket *socket,
|
||||
glong data2,
|
||||
guint32 time)
|
||||
{
|
||||
GTK_NOTE (PLUGSOCKET,
|
||||
g_message ("GtkSocket: Message of type %ld received", message));
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case XEMBED_EMBEDDED_NOTIFY:
|
||||
@ -1133,7 +1159,7 @@ handle_xembed_message (GtkSocket *socket,
|
||||
break;
|
||||
|
||||
case XEMBED_REQUEST_FOCUS:
|
||||
gtk_socket_claim_focus (socket);
|
||||
gtk_socket_claim_focus (socket, TRUE);
|
||||
break;
|
||||
|
||||
case XEMBED_FOCUS_NEXT:
|
||||
@ -1309,7 +1335,7 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
|
||||
case FocusIn:
|
||||
if (xevent->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS)
|
||||
{
|
||||
gtk_socket_claim_focus (socket);
|
||||
gtk_socket_claim_focus (socket, TRUE);
|
||||
}
|
||||
return_val = GDK_FILTER_REMOVE;
|
||||
break;
|
||||
|
@ -62,7 +62,8 @@ struct _GtkSocket
|
||||
guint have_size : 1;
|
||||
guint need_map : 1;
|
||||
guint is_mapped : 1;
|
||||
|
||||
guint active : 1;
|
||||
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkWidget *toplevel;
|
||||
};
|
||||
|
@ -131,6 +131,7 @@ enum {
|
||||
PROP_APP_PAINTABLE,
|
||||
PROP_CAN_FOCUS,
|
||||
PROP_HAS_FOCUS,
|
||||
PROP_IS_FOCUS,
|
||||
PROP_CAN_DEFAULT,
|
||||
PROP_HAS_DEFAULT,
|
||||
PROP_RECEIVES_DEFAULT,
|
||||
@ -453,6 +454,13 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
_("Whether the widget has the input focus"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_HAS_FOCUS,
|
||||
g_param_spec_boolean ("is_focus",
|
||||
_("Is focus"),
|
||||
_("Whether the widget is the focus widget within the toplevel"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_CAN_DEFAULT,
|
||||
g_param_spec_boolean ("can_default",
|
||||
@ -1142,6 +1150,10 @@ gtk_widget_set_property (GObject *object,
|
||||
if (g_value_get_boolean (value))
|
||||
gtk_widget_grab_focus (widget);
|
||||
break;
|
||||
case PROP_IS_FOCUS:
|
||||
if (g_value_get_boolean (value))
|
||||
gtk_widget_grab_focus (widget);
|
||||
break;
|
||||
case PROP_CAN_DEFAULT:
|
||||
saved_flags = GTK_WIDGET_FLAGS (widget);
|
||||
if (g_value_get_boolean (value))
|
||||
@ -1230,6 +1242,9 @@ gtk_widget_get_property (GObject *object,
|
||||
case PROP_HAS_FOCUS:
|
||||
g_value_set_boolean (value, (GTK_WIDGET_HAS_FOCUS (widget) != FALSE));
|
||||
break;
|
||||
case PROP_IS_FOCUS:
|
||||
g_value_set_boolean (value, (gtk_widget_is_focus (widget)));
|
||||
break;
|
||||
case PROP_CAN_DEFAULT:
|
||||
g_value_set_boolean (value, (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE));
|
||||
break;
|
||||
|
126
gtk/gtkwindow.c
126
gtk/gtkwindow.c
@ -70,6 +70,10 @@ enum {
|
||||
PROP_DESTROY_WITH_PARENT,
|
||||
PROP_ICON,
|
||||
PROP_SCREEN,
|
||||
|
||||
/* Readonly properties */
|
||||
PROP_IS_ACTIVE,
|
||||
PROP_HAS_TOPLEVEL_FOCUS,
|
||||
|
||||
LAST_ARG
|
||||
};
|
||||
@ -504,6 +508,22 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
GDK_TYPE_SCREEN,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_IS_ACTIVE,
|
||||
g_param_spec_boolean ("is_active",
|
||||
_("Is Active"),
|
||||
_("Whether the toplevel is the current active window"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_HAS_TOPLEVEL_FOCUS,
|
||||
g_param_spec_boolean ("has_toplevel_focus",
|
||||
_("Focus in Toplevel"),
|
||||
_("Whether the input focus is within this GtkWindow"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
window_signals[SET_FOCUS] =
|
||||
g_signal_new ("set_focus",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
@ -770,6 +790,12 @@ gtk_window_get_property (GObject *object,
|
||||
case PROP_SCREEN:
|
||||
g_value_set_object (value, window->screen);
|
||||
break;
|
||||
case PROP_IS_ACTIVE:
|
||||
g_value_set_boolean (value, window->is_active);
|
||||
break;
|
||||
case PROP_HAS_TOPLEVEL_FOCUS:
|
||||
g_value_set_boolean (value, window->has_toplevel_focus);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -3772,14 +3798,10 @@ gtk_window_focus_in_event (GtkWidget *widget,
|
||||
*/
|
||||
if (GTK_WIDGET_VISIBLE (widget))
|
||||
{
|
||||
window->has_focus = TRUE;
|
||||
|
||||
if (window->focus_widget &&
|
||||
window->focus_widget != widget &&
|
||||
!GTK_WIDGET_HAS_FOCUS (window->focus_widget))
|
||||
do_focus_change (window->focus_widget, TRUE);
|
||||
_gtk_window_set_has_toplevel_focus (window, TRUE);
|
||||
_gtk_window_set_is_active (window, TRUE);
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -3789,12 +3811,8 @@ gtk_window_focus_out_event (GtkWidget *widget,
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
|
||||
window->has_focus = FALSE;
|
||||
|
||||
if (window->focus_widget &&
|
||||
window->focus_widget != widget &&
|
||||
GTK_WIDGET_HAS_FOCUS (window->focus_widget))
|
||||
do_focus_change (window->focus_widget, FALSE);
|
||||
_gtk_window_set_has_toplevel_focus (window, FALSE);
|
||||
_gtk_window_set_is_active (window, FALSE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -3934,6 +3952,8 @@ gtk_window_real_set_focus (GtkWindow *window,
|
||||
|
||||
if (window->has_focus)
|
||||
do_focus_change (window->focus_widget, FALSE);
|
||||
|
||||
g_object_notify (G_OBJECT (window->focus_widget), "is_focus");
|
||||
}
|
||||
|
||||
window->focus_widget = focus;
|
||||
@ -3952,6 +3972,8 @@ gtk_window_real_set_focus (GtkWindow *window,
|
||||
|
||||
if (window->has_focus)
|
||||
do_focus_change (window->focus_widget, TRUE);
|
||||
|
||||
g_object_notify (G_OBJECT (window->focus_widget), "is_focus");
|
||||
}
|
||||
|
||||
if (window->default_widget &&
|
||||
@ -6084,3 +6106,81 @@ _gtk_window_activate_key (GtkWindow *window,
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
window_update_has_focus (GtkWindow *window)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (window);
|
||||
gboolean has_focus = window->has_toplevel_focus && window->is_active;
|
||||
|
||||
if (has_focus != window->has_focus)
|
||||
{
|
||||
window->has_focus = has_focus;
|
||||
|
||||
if (has_focus)
|
||||
{
|
||||
if (window->focus_widget &&
|
||||
window->focus_widget != widget &&
|
||||
!GTK_WIDGET_HAS_FOCUS (window->focus_widget))
|
||||
do_focus_change (window->focus_widget, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->focus_widget &&
|
||||
window->focus_widget != widget &&
|
||||
GTK_WIDGET_HAS_FOCUS (window->focus_widget))
|
||||
do_focus_change (window->focus_widget, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_window_set_is_active:
|
||||
* @window: a #GtkWindow
|
||||
* @is_active: %TRUE if the window is in the currently active toplevel
|
||||
*
|
||||
* Internal function that sets whether the #GtkWindow is part
|
||||
* of the currently active toplevel window (taking into account inter-process
|
||||
* embedding.)
|
||||
**/
|
||||
void
|
||||
_gtk_window_set_is_active (GtkWindow *window,
|
||||
gboolean is_active)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||
|
||||
is_active = is_active != FALSE;
|
||||
|
||||
if (is_active != window->is_active)
|
||||
{
|
||||
window->is_active = is_active;
|
||||
window_update_has_focus (window);
|
||||
|
||||
g_object_notify (G_OBJECT (window), "is_active");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_window_set_has_toplevel_focus:
|
||||
* @window: a #GtkWindow
|
||||
* @has_toplevel_focus: %TRUE if the in
|
||||
*
|
||||
* Internal function that sets whether the keyboard focus for the
|
||||
* toplevel window (taking into account inter-process embedding.)
|
||||
**/
|
||||
void
|
||||
_gtk_window_set_has_toplevel_focus (GtkWindow *window,
|
||||
gboolean has_toplevel_focus)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||
|
||||
has_toplevel_focus = has_toplevel_focus != FALSE;
|
||||
|
||||
if (has_toplevel_focus != window->has_toplevel_focus)
|
||||
{
|
||||
window->has_toplevel_focus = has_toplevel_focus;
|
||||
window_update_has_focus (window);
|
||||
|
||||
g_object_notify (G_OBJECT (window), "has_toplevel_focus");
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,10 @@ struct _GtkWindow
|
||||
guint decorated : 1;
|
||||
|
||||
guint type_hint : 3; /* GdkWindowTypeHint */
|
||||
guint gravity : 5; /* GdkGravity */
|
||||
guint gravity : 5; /* GdkGravity */
|
||||
|
||||
guint is_active : 1;
|
||||
guint has_toplevel_focus : 1;
|
||||
|
||||
guint frame_left;
|
||||
guint frame_top;
|
||||
@ -344,6 +347,11 @@ GtkWindowGroup *_gtk_window_get_group (GtkWindow *window);
|
||||
gboolean _gtk_window_activate_key (GtkWindow *window,
|
||||
GdkEventKey *event);
|
||||
|
||||
void _gtk_window_set_has_toplevel_focus (GtkWindow *window,
|
||||
gboolean has_toplevel_focus);
|
||||
void _gtk_window_set_is_active (GtkWindow *window,
|
||||
gboolean is_active);
|
||||
|
||||
typedef void (*GtkWindowKeysForeachFunc) (GtkWindow *window,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
|
Reference in New Issue
Block a user