summaryrefslogtreecommitdiff
path: root/src/gui_gtk_x11.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-03-20 21:59:49 +0000
committerBram Moolenaar <Bram@vim.org>2006-03-20 21:59:49 +0000
commitb3656edcb96bd36277db157baec80cb5e7a6f534 (patch)
tree196eed24afb857886081bbdc690e385715c59cb9 /src/gui_gtk_x11.c
parent9b2200acd6bd572eea00ea89eeb3b2c0764c8942 (diff)
downloadvim-b3656edcb96bd36277db157baec80cb5e7a6f534.zip
updated for version 7.0230
Diffstat (limited to 'src/gui_gtk_x11.c')
-rw-r--r--src/gui_gtk_x11.c247
1 files changed, 191 insertions, 56 deletions
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 964fcf687..7399fb1ca 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -806,9 +806,9 @@ focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
if (blink_state == BLINK_NONE)
gui_mch_start_blink();
- /* make sure keyboard input goes there */
- if (gtk_socket_id == 0)
- gtk_widget_grab_focus(gui.drawarea);
+ /* make sure keyboard input goes to the draw area (if this is focus for a window) */
+ if (widget != gui.drawarea)
+ gtk_widget_grab_focus(gui.drawarea);
return TRUE;
}
@@ -2837,14 +2837,21 @@ get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
if (using_gnome && widget != NULL)
{
# ifdef HAVE_GTK2
+ GtkWidget *parent;
BonoboDockItem *dockitem;
- widget = gtk_widget_get_parent(widget);
- dockitem = BONOBO_DOCK_ITEM(widget);
-
- if (dockitem == NULL || dockitem->is_floating)
- return 0;
- item_orientation = bonobo_dock_item_get_orientation(dockitem);
+ parent = gtk_widget_get_parent(widget);
+ if (G_TYPE_FROM_INSTANCE(parent) == BONOBO_TYPE_DOCK_ITEM)
+ {
+ /* Only menu & toolbar are dock items. Could tabline be?
+ * Seem to be only the 2 defined in GNOME */
+ widget = parent;
+ dockitem = BONOBO_DOCK_ITEM(widget);
+
+ if (dockitem == NULL || dockitem->is_floating)
+ return 0;
+ item_orientation = bonobo_dock_item_get_orientation(dockitem);
+ }
# else
GnomeDockItem *dockitem;
@@ -2911,16 +2918,39 @@ get_menu_tool_height(void)
return height;
}
+/* This controls whether we can set the real window hints at
+ * start-up when in a GtkPlug.
+ * 0 = normal processing (default)
+ * 1 = init. hints set, no-one's tried to reset since last check
+ * 2 = init. hints set, attempt made to change hints
+ */
+static int init_window_hints_state = 0;
+
static void
-update_window_manager_hints(void)
+update_window_manager_hints(int force_width, int force_height)
{
static int old_width = 0;
static int old_height = 0;
+ static int old_min_width = 0;
+ static int old_min_height = 0;
static int old_char_width = 0;
static int old_char_height = 0;
int width;
int height;
+ int min_width;
+ int min_height;
+
+ /* At start-up, don't try to set the hints until the initial
+ * values have been used (those that dictate our initial size)
+ * Let forced (i.e., correct) values thruogh always.
+ */
+ if (!(force_width && force_height) && init_window_hints_state > 0)
+ {
+ /* Don't do it! */
+ init_window_hints_state = 2;
+ return;
+ }
/* This also needs to be done when the main window isn't there yet,
* otherwise the hints don't work. */
@@ -2934,9 +2964,28 @@ update_window_manager_hints(void)
height += get_menu_tool_height();
# endif
+ /* GtkSockets use GtkPlug's [gui,mainwin] min-size hints to determine
+ * their actual widget size. When we set our size ourselve (e.g.,
+ * 'set columns=' or init. -geom) we briefly set the min. to the size
+ * we wish to be instead of the legitimate minimum so that we actually
+ * resize correctly.
+ */
+ if (force_width && force_height)
+ {
+ min_width = force_width;
+ min_height = force_height;
+ }
+ else
+ {
+ min_width = width + MIN_COLUMNS * gui.char_width;
+ min_height = height + MIN_LINES * gui.char_height;
+ }
+
/* Avoid an expose event when the size didn't change. */
if (width != old_width
|| height != old_height
+ || min_width != old_min_width
+ || min_height != old_min_height
|| gui.char_width != old_char_width
|| gui.char_height != old_char_height)
{
@@ -2947,8 +2996,8 @@ update_window_manager_hints(void)
geometry.height_inc = gui.char_height;
geometry.base_width = width;
geometry.base_height = height;
- geometry.min_width = width + MIN_COLUMNS * gui.char_width;
- geometry.min_height = height + MIN_LINES * gui.char_height;
+ geometry.min_width = min_width;
+ geometry.min_height = min_height;
geometry_mask = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC
|GDK_HINT_MIN_SIZE;
# ifdef HAVE_GTK2
@@ -2961,10 +3010,12 @@ update_window_manager_hints(void)
gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin,
&geometry, geometry_mask);
# endif
- old_width = width;
- old_height = height;
- old_char_width = gui.char_width;
- old_char_height = gui.char_height;
+ old_width = width;
+ old_height = height;
+ old_min_width = min_width;
+ old_min_height = min_height;
+ old_char_width = gui.char_width;
+ old_char_height = gui.char_height;
}
}
@@ -3211,7 +3262,7 @@ gui_mch_show_tabline(int showit)
{
/* Note: this may cause a resize event */
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit);
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
#ifndef HAVE_GTK2
showing_tabline = showit;
#endif
@@ -3583,35 +3634,31 @@ gui_mch_init(void)
/*
* Use a Notebook for the tab pages labels. The labels are hidden by
* default.
- * TODO: currently doesn't work for Gnome.
*/
- if (!using_gnome)
- {
- gui.tabline = gtk_notebook_new();
- gtk_widget_show(gui.tabline);
- gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0);
- gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE);
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE);
-
- {
- GtkWidget *page, *label;
+ gui.tabline = gtk_notebook_new();
+ gtk_widget_show(gui.tabline);
+ gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE);
+ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE);
- /* Add the first tab. */
- page = gtk_vbox_new(FALSE, 0);
- gtk_widget_show(page);
- gtk_container_add(GTK_CONTAINER(gui.tabline), page);
- label = gtk_label_new("-Empty-");
- gtk_widget_show(label);
- gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, label);
- }
- gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page",
- GTK_SIGNAL_FUNC(on_select_tab), NULL);
+ {
+ GtkWidget *page, *label;
- /* Create a popup menu for the tab line and connect it. */
- tabline_menu = create_tabline_menu();
- gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event",
- GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu));
+ /* Add the first tab. */
+ page = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(page);
+ gtk_container_add(GTK_CONTAINER(gui.tabline), page);
+ label = gtk_label_new("-Empty-");
+ gtk_widget_show(label);
+ gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, label);
}
+ gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page",
+ GTK_SIGNAL_FUNC(on_select_tab), NULL);
+
+ /* Create a popup menu for the tab line and connect it. */
+ tabline_menu = create_tabline_menu();
+ gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event",
+ GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu));
#endif
gui.formwin = gtk_form_new();
@@ -3705,10 +3752,30 @@ gui_mch_init(void)
GTK_SIGNAL_FUNC(enter_notify_event), NULL);
}
- gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event",
- GTK_SIGNAL_FUNC(focus_out_event), NULL);
- gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event",
- GTK_SIGNAL_FUNC(focus_in_event), NULL);
+ /* Real windows can get focus ... GtkPlug, being a mere container can't,
+ * only its widgets. Arguably, this could be common code and we not use
+ * the window focus at all, but let's be safe.
+ */
+ if (gtk_socket_id == 0)
+ {
+ gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event",
+ GTK_SIGNAL_FUNC(focus_out_event), NULL);
+ gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event",
+ GTK_SIGNAL_FUNC(focus_in_event), NULL);
+ }
+ else
+ {
+ gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_out_event",
+ GTK_SIGNAL_FUNC(focus_out_event), NULL);
+ gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_in_event",
+ GTK_SIGNAL_FUNC(focus_in_event), NULL);
+#ifdef FEAT_GUI_TABLINE
+ gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_out_event",
+ GTK_SIGNAL_FUNC(focus_out_event), NULL);
+ gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_in_event",
+ GTK_SIGNAL_FUNC(focus_in_event), NULL);
+#endif /* FEAT_GUI_TABLINE */
+ }
gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event",
GTK_SIGNAL_FUNC(motion_notify_event), NULL);
@@ -3793,8 +3860,17 @@ gui_mch_new_colors(void)
form_configure_event(GtkWidget *widget, GdkEventConfigure *event,
gpointer data)
{
+ int usable_height = event->height;
+
+ /* When in a GtkPlug, we can't guarantee valid heights (as a round
+ * no. of char-heights), so we have to manually sanitise them.
+ * Widths seem to sort themselves out, don't ask me why.
+ */
+ if (gtk_socket_id != 0)
+ usable_height -= (gui.char_height - (gui.char_height/2)); /* sic. */
+
gtk_form_freeze(GTK_FORM(gui.formwin));
- gui_resize_shell(event->width, event->height);
+ gui_resize_shell(event->width, usable_height);
gtk_form_thaw(GTK_FORM(gui.formwin));
return TRUE;
@@ -3824,6 +3900,37 @@ mainwin_destroy_cb(GtkObject *object, gpointer data)
}
}
+
+/*
+ * Bit of a hack to ensure we start GtkPlug windows with the correct window
+ * hints (and thus the required size from -geom), but that after that we
+ * put the hints back to normal (the actual minimum size) so we may
+ * subsequently be resized smaller. GtkSocket (the parent end) uses the
+ * plug's window 'min hints to set *it's* minum size, but that's also the
+ * only way we have of making ourselves bigger (by set lines/columns).
+ * Thus set hints at start-up to ensure correct init. size, then a
+ * second after the final attempt to reset the real minimum hinst (done by
+ * scrollbar init.), actually do the sttandard hinst and stop the timer.
+ * We'll not let the default hints be set while this timer's active.
+ */
+/*ARGSUSED*/
+ static gboolean
+check_startup_plug_hints(gpointer data)
+{
+ if (init_window_hints_state == 1)
+ {
+ /* Safe to use normal hints now */
+ init_window_hints_state = 0;
+ update_window_manager_hints(0, 0);
+ return FALSE; /* stop timer */
+ }
+
+ /* Keep on trying */
+ init_window_hints_state = 1;
+ return TRUE;
+}
+
+
/*
* Open the GUI window which was created by a call to gui_mch_init().
*/
@@ -3887,12 +3994,32 @@ gui_mch_open(void)
#endif
vim_free(gui.geom);
gui.geom = NULL;
+
+ /* From now until everyone's stopped trying to set the window hints
+ * to their correct minimum values, stop them being set as we need
+ * them to remain at our required size for the parent GtkSocket to
+ * give us the right initial size.
+ */
+ if (gtk_socket_id != 0 && (mask & WidthValue || mask & HeightValue))
+ {
+ guint pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width);
+ guint pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height);
+
+#ifdef HAVE_GTK2
+ pixel_width += get_menu_tool_width();
+ pixel_height += get_menu_tool_height();
+#endif
+
+ update_window_manager_hints(pixel_width, pixel_height);
+ init_window_hints_state = 1;
+ g_timeout_add(1000, check_startup_plug_hints, NULL);
+ }
}
gtk_form_set_size(GTK_FORM(gui.formwin),
(guint)(gui_get_base_width() + Columns * gui.char_width),
(guint)(gui_get_base_height() + Rows * gui.char_height));
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
if (foreground_argument != NULL)
fg_pixel = gui_get_color((char_u *)foreground_argument);
@@ -4125,17 +4252,25 @@ gui_mch_set_shellsize(int width, int height,
/* give GTK+ a chance to put all widget's into place */
gui_mch_update();
+#ifndef HAVE_GTK2
/* this will cause the proper resizement to happen too */
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
+
+#else /* HAVE_GTK2 */
+ /* this will cause the proper resizement to happen too */
+ if (gtk_socket_id == 0)
+ update_window_manager_hints(0, 0);
-#ifdef HAVE_GTK2
/* With GTK+ 2, changing the size of the form widget doesn't resize
- * the window. So lets do it the other way around and resize the
+ * the window. So let's do it the other way around and resize the
* main window instead. */
width += get_menu_tool_width();
height += get_menu_tool_height();
- gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height);
+ if (gtk_socket_id == 0)
+ gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height);
+ else
+ update_window_manager_hints(width, height);
#if 0
if (!resize_idle_installed)
@@ -4231,7 +4366,7 @@ gui_mch_enable_menu(int showit)
else
gtk_widget_hide(widget);
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
}
}
#endif /* FEAT_MENU */
@@ -4262,7 +4397,7 @@ gui_mch_show_toolbar(int showit)
else
gtk_widget_hide(widget);
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
}
}
#endif /* FEAT_TOOLBAR */
@@ -4960,7 +5095,7 @@ gui_mch_init_font(char_u *font_name, int fontset)
#endif /* !HAVE_GTK2 */
/* Preserve the logical dimensions of the screen. */
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
return OK;
}
@@ -6577,7 +6712,7 @@ gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
else
gtk_widget_hide(sb->id);
- update_window_manager_hints();
+ update_window_manager_hints(0, 0);
}