im.pidgin.pidgin.next.minor: 457a3a60abf75010d7855c1f25254e8118d38466
sadrul at pidgin.im
sadrul at pidgin.im
Tue Nov 27 21:00:40 EST 2007
-----------------------------------------------------------------
Revision: 457a3a60abf75010d7855c1f25254e8118d38466
Ancestor: da0d4c8ba9b1b9cd941d52c03d6beac54afe1a6e
Author: sadrul at pidgin.im
Date: 2007-11-28T01:54:34
Branch: im.pidgin.pidgin.next.minor
Modified files:
ChangeLog.API pidgin/gtkconv.c pidgin/gtknotify.c
pidgin/gtkrequest.c pidgin/gtkutils.c pidgin/gtkutils.h
ChangeLog:
Try to make a window transient for a suitable parent window. This currently
happens only for the request and notify windows, and only when they are
triggered by some GTK+ event.
There are some issues when a request/notify window pops up from activating
a popup menuitem. I found a fix for when the menuitem is activated by a
keypress. I'll try to find a fix for a mouse-button later.
-------------- next part --------------
============================================================
--- ChangeLog.API 52bdd2272f65bbc2ede73e6cb2e86b84faa45021
+++ ChangeLog.API ffebba18e0926bf97f901441acec51ad4465f108
@@ -15,6 +15,8 @@ version 2.4.0 (??/??/????):
pidgin_create_dialog.
* GTK_IMHTML_NO_SMILEY for GtkIMHtmlOptions means not to look for
smileys in the text. (Florian 'goutnet' Delizy)
+ * pidgin_auto_parent_window to make a window transient for a suitable
+ parent window.
version 2.3.0 (11/24/2007):
libpurple:
============================================================
--- pidgin/gtkconv.c 3cead6dc548476a7beee928e939f305f7f0acba5
+++ pidgin/gtkconv.c f152ddda1ea63ffc8bdc264cd67e2d0d232ddf81
@@ -8163,7 +8163,7 @@ infopane_press_cb(GtkWidget *widget, Gdk
}
if (e->button == 3) {
- /* Right click was pressed. Popup the Send To menu. */
+ /* Right click was pressed. Popup the context menu. */
GtkWidget *menu = gtk_menu_new(), *sub;
gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
============================================================
--- pidgin/gtknotify.c 4a1812fcd29fe4424adf89865e4b0f7deedc0c46
+++ pidgin/gtknotify.c fcdecd5714ca8e71c1b407bff4450e06fda78810
@@ -284,6 +284,8 @@ pidgin_notify_message(PurpleNotifyMsgTyp
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ pidgin_auto_parent_window(dialog);
+
gtk_widget_show_all(dialog);
return dialog;
@@ -684,6 +686,8 @@ pidgin_notify_formatted(const char *titl
g_object_set_data(G_OBJECT(window), "info-widget", imhtml);
/* Show the window */
+ pidgin_auto_parent_window(window);
+
gtk_widget_show(window);
return window;
@@ -894,6 +898,8 @@ pidgin_notify_searchresults(PurpleConnec
pidgin_notify_searchresults_new_rows(gc, results, data);
/* Show the window */
+ pidgin_auto_parent_window(window);
+
gtk_widget_show(window);
return data;
}
============================================================
--- pidgin/gtkrequest.c 72f053d9098adc6c1cc9cc0ac25607db12c64405
+++ pidgin/gtkrequest.c c698c330d40d7470a8bd84491dacfc844a06bc09
@@ -439,6 +439,8 @@ pidgin_request_input(const char *title,
pidgin_set_accessible_label (entry, label);
data->u.input.entry = entry;
+ pidgin_auto_parent_window(dialog);
+
/* Show everything. */
gtk_widget_show(dialog);
@@ -546,6 +548,8 @@ pidgin_request_choice(const char *title,
g_object_set_data(G_OBJECT(dialog), "radio", radio);
/* Show everything. */
+ pidgin_auto_parent_window(dialog);
+
gtk_widget_show_all(dialog);
return data;
@@ -661,6 +665,8 @@ pidgin_request_action(const char *title,
gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_action);
/* Show everything. */
+ pidgin_auto_parent_window(dialog);
+
gtk_widget_show_all(dialog);
return data;
@@ -1394,6 +1400,8 @@ pidgin_request_fields(const char *title,
if (!purple_request_fields_all_required_filled(fields))
gtk_widget_set_sensitive(button, FALSE);
+ pidgin_auto_parent_window(win);
+
gtk_widget_show(win);
return data;
@@ -1601,6 +1609,8 @@ pidgin_request_file(const char *title, c
G_CALLBACK(file_ok_check_if_exists_cb), data);
#endif /* FILECHOOSER */
+ pidgin_auto_parent_window(filesel);
+
data->dialog = filesel;
gtk_widget_show(filesel);
@@ -1652,6 +1662,8 @@ pidgin_request_folder(const char *title,
#endif
data->dialog = dirsel;
+ pidgin_auto_parent_window(dirsel);
+
gtk_widget_show(dirsel);
return (void *)data;
============================================================
--- pidgin/gtkutils.c 0d9cb43e8df70ba43c59d2b83535c04ea6ef7f79
+++ pidgin/gtkutils.c f350a8fecb960ac71eb7f05a09c0e32be8072dcc
@@ -3312,3 +3312,107 @@ void pidgin_text_combo_box_entry_set_tex
gtk_entry_set_text(GTK_ENTRY(GTK_BIN((widget))->child), (text));
}
+gboolean pidgin_auto_parent_window(GtkWidget *widget)
+{
+#if 0
+ /* This looks at the most recent window that received focus, and makes
+ * that the parent window. */
+#ifndef _WIN32
+ static GdkAtom _WindowTime = GDK_NONE;
+ static GdkAtom _Cardinal = GDK_NONE;
+ GList *windows = NULL;
+ GtkWidget *parent = NULL;
+ time_t window_time = 0;
+
+ windows = gtk_window_list_toplevels();
+
+ if (_WindowTime == GDK_NONE) {
+ _WindowTime = gdk_x11_xatom_to_atom(gdk_x11_get_xatom_by_name("_NET_WM_USER_TIME"));
+ }
+ if (_Cardinal == GDK_NONE) {
+ _Cardinal = gdk_atom_intern("CARDINAL", FALSE);
+ }
+
+ while (windows) {
+ GtkWidget *window = windows->data;
+ guchar *data = NULL;
+ int al = 0;
+ time_t value;
+
+ windows = g_list_delete_link(windows, windows);
+
+ if (window == widget ||
+ !GTK_WIDGET_VISIBLE(window))
+ continue;
+
+ if (!gdk_property_get(window->window, _WindowTime, _Cardinal, 0, sizeof(time_t), FALSE,
+ NULL, NULL, &al, &data))
+ continue;
+ value = *(time_t *)data;
+ if (window_time < value) {
+ window_time = value;
+ parent = window;
+ }
+ g_free(data);
+ }
+ if (windows)
+ g_list_free(windows);
+ if (parent) {
+ if (!gtk_get_current_event() && gtk_window_has_toplevel_focus(GTK_WINDOW(parent))) {
+ /* The window is in focus, and the new window was not triggered by a keypress/click
+ * event. So do not set it transient, to avoid focus stealing and all that.
+ */
+ return FALSE;
+ }
+ gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(parent));
+ return TRUE;
+ }
+ return FALSE;
+#endif
+#else
+ /* This finds the currently active window and makes that the parent window. */
+ GList *windows = NULL;
+ GtkWidget *parent = NULL;
+ GdkEvent *event = gtk_get_current_event();
+ GdkWindow *menu = NULL;
+
+ if (event == NULL)
+ /* The window was not triggered by a user action. */
+ return FALSE;
+
+ /* We need to special case events from a popup menu. */
+ if (event->type == GDK_BUTTON_RELEASE) {
+ /* XXX: Neither of the following works:
+ menu = event->button.window;
+ menu = gdk_window_get_parent(event->button.window);
+ menu = gdk_window_get_toplevel(event->button.window);
+ */
+ } else if (event->type == GDK_KEY_PRESS)
+ menu = event->key.window;
+
+ windows = gtk_window_list_toplevels();
+ while (windows) {
+ GtkWidget *window = windows->data;
+ windows = g_list_delete_link(windows, windows);
+
+ if (window == widget ||
+ !GTK_WIDGET_VISIBLE(window)) {
+ continue;
+ }
+
+ if (gtk_window_has_toplevel_focus(GTK_WINDOW(window)) ||
+ (menu && menu == window->window)) {
+ parent = window;
+ break;
+ }
+ }
+ if (windows)
+ g_list_free(windows);
+ if (parent) {
+ gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(parent));
+ return TRUE;
+ }
+ return FALSE;
+#endif
+}
+
============================================================
--- pidgin/gtkutils.h 7c98029c3be852990b736ce6ee3b988c534ad943
+++ pidgin/gtkutils.h 0e942b173e025518f0003b5afc7c28a1d50348f6
@@ -780,5 +780,15 @@ void pidgin_text_combo_box_entry_set_tex
*/
void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text);
+/**
+ * Automatically make a window transient to a suitable parent window.
+ *
+ * @param window The window to make transient.
+ *
+ * @return Whether the window was made transient or not.
+ * @since 2.4.0
+ */
+gboolean pidgin_auto_parent_window(GtkWidget *window);
+
#endif /* _PIDGINUTILS_H_ */
More information about the Commits
mailing list