From a707ec228ff39d0df26d78f715561952d2f8c0b9 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Tue, 2 Apr 2013 14:08:57 +0100 Subject: Prevent toolbox getting lost when minimising windows On X, window managers don't like WM_TRANSIENT_FOR being altered while a window is visible; this meant that if you opened TikZiT and opened a second main window and minimised the main window that had focus, the toolbox and properties window would both disappear, with no way to get them back (well, almost - the properties window could be retreived with the menu item that shows/hides it). Tested with KWin, Metacity (Gnome 2's WM), Mutter (Gnome 3) and xfwm4 (XFCE 4). Metacity and Mutter still behave a little oddly - you have to click one of the main windows *twice* to get it to focus. KWin and xfwm4 work fine. --- tikzit/src/gtk/Application.m | 4 ++-- tikzit/src/gtk/ContextWindow.h | 2 +- tikzit/src/gtk/ContextWindow.m | 4 ++-- tikzit/src/gtk/ToolBox.h | 2 +- tikzit/src/gtk/ToolBox.m | 4 ++-- tikzit/src/gtk/gtkhelpers.h | 2 ++ tikzit/src/gtk/gtkhelpers.m | 21 +++++++++++++++++++++ 7 files changed, 31 insertions(+), 8 deletions(-) diff --git a/tikzit/src/gtk/Application.m b/tikzit/src/gtk/Application.m index 89fb7fd..99ad24d 100644 --- a/tikzit/src/gtk/Application.m +++ b/tikzit/src/gtk/Application.m @@ -387,8 +387,8 @@ Application* app = nil; [contextWindow setDocument:[window document]]; - [contextWindow setTransientFor:window]; - [toolBox setTransientFor:window]; + [contextWindow attachToWindow:window]; + [toolBox attachToWindow:window]; [[NSNotificationCenter defaultCenter] addObserver:self diff --git a/tikzit/src/gtk/ContextWindow.h b/tikzit/src/gtk/ContextWindow.h index 64ecd19..fcad9df 100644 --- a/tikzit/src/gtk/ContextWindow.h +++ b/tikzit/src/gtk/ContextWindow.h @@ -43,7 +43,7 @@ andEdgeStylesModel:(EdgeStylesModel*)esm; - (void) present; -- (void) setTransientFor:(Window*)parent; +- (void) attachToWindow:(Window*)parent; - (void) loadConfiguration:(Configuration*)config; - (void) saveConfiguration:(Configuration*)config; diff --git a/tikzit/src/gtk/ContextWindow.m b/tikzit/src/gtk/ContextWindow.m index 9f376a0..d8e9d20 100644 --- a/tikzit/src/gtk/ContextWindow.m +++ b/tikzit/src/gtk/ContextWindow.m @@ -119,8 +119,8 @@ static gboolean props_window_delete_event_cb (GtkWidget *widget, GdkEvent *event gtk_window_present (GTK_WINDOW (window)); } -- (void) setTransientFor:(Window*)parent { - gtk_window_set_transient_for (GTK_WINDOW (window), [parent gtkWindow]); +- (void) attachToWindow:(Window*)parent { + utility_window_attach (GTK_WINDOW (window), [parent gtkWindow]); } - (void) loadConfiguration:(Configuration*)config { diff --git a/tikzit/src/gtk/ToolBox.h b/tikzit/src/gtk/ToolBox.h index 7076417..60074c1 100644 --- a/tikzit/src/gtk/ToolBox.h +++ b/tikzit/src/gtk/ToolBox.h @@ -36,7 +36,7 @@ - (void) show; - (void) present; -- (void) setTransientFor:(Window*)w; +- (void) attachToWindow:(Window*)parent; - (void) loadConfiguration:(Configuration*)config; - (void) saveConfiguration:(Configuration*)config; diff --git a/tikzit/src/gtk/ToolBox.m b/tikzit/src/gtk/ToolBox.m index 4b6aa0a..c6d2ccf 100644 --- a/tikzit/src/gtk/ToolBox.m +++ b/tikzit/src/gtk/ToolBox.m @@ -231,8 +231,8 @@ static void tool_button_toggled_cb (GtkWidget *widget, ToolBox *toolBox); gtk_window_present (GTK_WINDOW (window)); } -- (void) setTransientFor:(Window*)parent { - gtk_window_set_transient_for (GTK_WINDOW (window), [parent gtkWindow]); +- (void) attachToWindow:(Window*)parent { + utility_window_attach (GTK_WINDOW (window), [parent gtkWindow]); } - (void) loadConfiguration:(Configuration*)config { diff --git a/tikzit/src/gtk/gtkhelpers.h b/tikzit/src/gtk/gtkhelpers.h index 4da949b..e4b79b8 100644 --- a/tikzit/src/gtk/gtkhelpers.h +++ b/tikzit/src/gtk/gtkhelpers.h @@ -55,4 +55,6 @@ void widget_clear_error (GtkWidget *widget); void text_buffer_clear_tag (GtkTextBuffer *buffer, GtkTextTag *tag); +void utility_window_attach (GtkWindow *util_win, GtkWindow *parent_win); + // vim:ft=objc:sts=2:sw=2:et diff --git a/tikzit/src/gtk/gtkhelpers.m b/tikzit/src/gtk/gtkhelpers.m index e6b1aef..9d26af5 100644 --- a/tikzit/src/gtk/gtkhelpers.m +++ b/tikzit/src/gtk/gtkhelpers.m @@ -251,4 +251,25 @@ void text_buffer_clear_tag (GtkTextBuffer *buffer, GtkTextTag *tag) { gtk_text_buffer_remove_tag (buffer, tag, &start, &end); } +void utility_window_attach (GtkWindow *util_win, GtkWindow *parent_win) { + if (parent_win == gtk_window_get_transient_for (util_win)) + return; + + // HACK: X window managers tend to move windows around when they are + // unmapped and mapped again, so we save the position + gint x, y; + gtk_window_get_position (util_win, &x, &y); + + // HACK: Altering WM_TRANSIENT_FOR on a non-hidden but unmapped window + // (eg: when you have minimised the original parent window) can + // cause the window to be lost forever, so we hide it first + gtk_widget_hide (GTK_WIDGET (util_win)); + gtk_window_set_focus_on_map (util_win, FALSE); + gtk_window_set_transient_for (util_win, parent_win); + gtk_widget_show (GTK_WIDGET (util_win)); + + // HACK: see above + gtk_window_move (util_win, x, y); +} + // vim:ft=objc:ts=8:et:sts=4:sw=4 -- cgit v1.2.3