+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
+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
+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
+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
+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
+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
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;
/* 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 ());
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");
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:
break;
case XEMBED_FOCUS_IN:
+ _gtk_window_set_has_toplevel_focus (window, TRUE);
switch (detail)
{
case XEMBED_FOCUS_FIRST:
focus_first_last (plug, GTK_DIR_TAB_BACKWARD);
break;
case XEMBED_FOCUS_CURRENT:
- /* fall through */;
+ 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;
+ break;
- 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;
- }
+ case XEMBED_FOCUS_OUT:
+ _gtk_window_set_has_toplevel_focus (window, FALSE);
+ break;
case XEMBED_GRAB_KEY:
case XEMBED_UNGRAB_KEY:
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include <string.h>
+
#include "gdk/gdkkeysyms.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
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,
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);
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);
}
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;
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;
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);
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;
+
+ 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;
- return FALSE;
+ 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
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;
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);
}
}
return FALSE;
}
-static gboolean
-gtk_socket_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
-{
- GtkSocket *socket = GTK_SOCKET (widget);
-
- 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)
+static void
+gtk_socket_notify (GObject *object,
+ GParamSpec *pspec)
{
- GtkSocket *socket = GTK_SOCKET (widget);
- if (socket->plug_window)
- {
- send_xembed_message (socket, XEMBED_FOCUS_OUT, 0, 0, 0,
- gtk_get_current_event_time ());
- }
+ if (!strcmp (pspec->name, "is_focus"))
+ return;
- 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);
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;
}
GdkNativeWindow xid,
gboolean need_reparent)
{
-
GtkWidget *widget = GTK_WIDGET (socket);
GdkDisplay *display = gtk_widget_get_display (widget);
gpointer user_data = NULL;
{
/* 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;
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));
}
glong data2,
guint32 time)
{
+ GTK_NOTE (PLUGSOCKET,
+ g_message ("GtkSocket: Message of type %ld received", message));
+
switch (message)
{
case XEMBED_EMBEDDED_NOTIFY:
break;
case XEMBED_REQUEST_FOCUS:
- gtk_socket_claim_focus (socket);
+ gtk_socket_claim_focus (socket, TRUE);
break;
case XEMBED_FOCUS_NEXT:
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;
guint have_size : 1;
guint need_map : 1;
guint is_mapped : 1;
-
+ guint active : 1;
+
GtkAccelGroup *accel_group;
GtkWidget *toplevel;
};
PROP_APP_PAINTABLE,
PROP_CAN_FOCUS,
PROP_HAS_FOCUS,
+ PROP_IS_FOCUS,
PROP_CAN_DEFAULT,
PROP_HAS_DEFAULT,
PROP_RECEIVES_DEFAULT,
_("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",
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))
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;
PROP_DESTROY_WITH_PARENT,
PROP_ICON,
PROP_SCREEN,
+
+ /* Readonly properties */
+ PROP_IS_ACTIVE,
+ PROP_HAS_TOPLEVEL_FOCUS,
LAST_ARG
};
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),
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;
*/
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;
}
{
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;
}
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;
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 &&
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");
+ }
+}
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;
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,