X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ded997c16032a6c658e345452d7e5ec275c0642e..2a205424e771703217ce8c6b4252d810d3310cd2:/src/gtkutil.c diff --git a/src/gtkutil.c b/src/gtkutil.c index 0983724f95..1cb1004f57 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -16,17 +16,19 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #include "config.h" #ifdef USE_GTK #include +#include #include #include "lisp.h" #include "xterm.h" #include "blockinput.h" +#include "syssignal.h" #include "window.h" #include "atimer.h" #include "gtkutil.h" @@ -554,12 +556,6 @@ xg_resize_outer_widget (f, columns, rows) int columns; int rows; { - gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - FRAME_PIXEL_WIDTH (f), FRAME_TOTAL_PIXEL_HEIGHT (f)); - - /* base_height is now changed. */ - x_wm_set_size_hint (f, 0, 0); - /* If we are not mapped yet, set geometry once again, as window height now have changed. */ if (! GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f))) @@ -582,14 +578,14 @@ xg_resize_widgets (f, pixelwidth, pixelheight) { int mbheight = FRAME_MENUBAR_HEIGHT (f); int tbheight = FRAME_TOOLBAR_HEIGHT (f); - int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (pixelheight + int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (pixelheight - mbheight - tbheight)); int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth); if (FRAME_GTK_WIDGET (f) - && (columns != FRAME_COLS (f) + && (columns != FRAME_COLS (f) || rows != FRAME_LINES (f) - || pixelwidth != FRAME_PIXEL_WIDTH (f) + || pixelwidth != FRAME_PIXEL_WIDTH (f) || pixelheight != FRAME_PIXEL_HEIGHT (f))) { struct x_output *x = f->output_data.x; @@ -717,6 +713,7 @@ xg_create_frame_widgets (f) if (wvbox) gtk_widget_destroy (wvbox); if (wfixed) gtk_widget_destroy (wfixed); + UNBLOCK_INPUT; return 0; } @@ -754,7 +751,7 @@ xg_create_frame_widgets (f) So we cheat a bit by setting a height that is what it will have later on when tool bar items are added. */ if (FRAME_EXTERNAL_TOOL_BAR (f) && f->n_tool_bar_items == 0) - FRAME_TOOLBAR_HEIGHT (f) = 34; + FRAME_TOOLBAR_HEIGHT (f) = 38; /* We don't want this widget double buffered, because we draw on it @@ -1310,9 +1307,16 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p) char *fn = 0; int filesel_done = 0; xg_get_file_func func; + extern int x_use_old_gtk_file_dialog; + +#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN) + /* I really don't know why this is needed, but without this the GLIBC add on + library linuxthreads hangs when the Gnome file chooser backend creates + threads. */ + sigblock (sigmask (__SIGRTMIN)); +#endif /* HAVE_GTK_AND_PTHREAD */ #ifdef HAVE_GTK_FILE_BOTH - extern int x_use_old_gtk_file_dialog; if (x_use_old_gtk_file_dialog) w = xg_get_file_with_selection (f, prompt, default_filename, @@ -1358,6 +1362,10 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p) gtk_main_iteration (); } +#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN) + sigunblock (sigmask (__SIGRTMIN)); +#endif + if (filesel_done == GTK_RESPONSE_OK) fn = (*func) (w); @@ -1892,7 +1900,7 @@ create_menus (data, f, select_cb, deactivate_cb, highlight_cb, if (deactivate_cb) g_signal_connect (G_OBJECT (wmenu), - "deactivate", deactivate_cb, 0); + "selection-done", deactivate_cb, 0); g_signal_connect (G_OBJECT (wmenu), "grab-notify", G_CALLBACK (menu_grab_callback), 0); @@ -2837,7 +2845,7 @@ xg_gtk_scroll_destroy (widget, data) gpointer data; { gpointer p; - int id = (int)data; + int id = (int) (EMACS_INT) data; /* The EMACS_INT cast avoids a warning. */ p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); if (p) xfree (p); @@ -2868,7 +2876,7 @@ scroll_bar_button_cb (widget, event, user_data) if (xg_timer) xg_stop_timer (); bar->dragging = Qnil; } - + return FALSE; } @@ -2907,10 +2915,11 @@ xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name) "value-changed", scroll_callback, (gpointer) bar); + /* The EMACS_INT cast avoids a warning. */ g_signal_connect (G_OBJECT (wscroll), "destroy", G_CALLBACK (xg_gtk_scroll_destroy), - (gpointer) scroll_id); + (gpointer) (EMACS_INT) scroll_id); /* Connect to button press and button release to detect if any scroll bar has the pointer. */ @@ -2931,7 +2940,7 @@ xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name) event box window. */ gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1); gtk_container_add (GTK_CONTAINER (webox), wscroll); - + /* Set the cursor to an arrow. */ xg_set_cursor (webox, FRAME_X_DISPLAY_INFO (f)->xg_cursor); @@ -2990,9 +2999,14 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height) GtkWidget *wparent = gtk_widget_get_parent (wscroll); /* Move and resize to new values. */ - gtk_widget_set_size_request (wscroll, width, height); gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top); - + gtk_widget_set_size_request (wscroll, width, height); + gtk_widget_queue_draw (wparent); + gdk_window_process_all_updates (); + /* GTK does not redraw until the main loop is entered again, but + if there are no X events pending we will not enter it. So we sync + here to get some events. */ + x_sync (f); SET_FRAME_GARBAGED (f); cancel_mouse_face (f); } @@ -3099,7 +3113,8 @@ xg_tool_bar_callback (w, client_data) GtkWidget *w; gpointer client_data; { - int idx = (int)client_data; + /* The EMACS_INT cast avoids a warning. */ + int idx = (int) (EMACS_INT) client_data; FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object key, frame; struct input_event event; @@ -3141,10 +3156,11 @@ xg_tool_bar_detach_callback (wbox, w, client_data) if (f) { + FRAME_X_OUTPUT (f)->toolbar_detached = 1; + /* When detaching a tool bar, not everything dissapear. There are a few pixels left that are used to drop the tool bar back into place. */ - int bw = gtk_container_get_border_width (GTK_CONTAINER (wbox)); FRAME_TOOLBAR_HEIGHT (f) = 2; /* The height has changed, resize outer widget and set columns @@ -3172,11 +3188,13 @@ xg_tool_bar_attach_callback (wbox, w, client_data) { GtkRequisition req; + FRAME_X_OUTPUT (f)->toolbar_detached = 0; + gtk_widget_size_request (w, &req); FRAME_TOOLBAR_HEIGHT (f) = req.height; /* The height has changed, resize outer widget and set columns - rows to what we had before detaching the tool bar. */ + rows to what we had before attaching the tool bar. */ xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f)); } } @@ -3196,7 +3214,8 @@ xg_tool_bar_help_callback (w, event, client_data) GdkEventCrossing *event; gpointer client_data; { - int idx = (int)client_data; + /* The EMACS_INT cast avoids a warning. */ + int idx = (int) (EMACS_INT) client_data; FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object help, frame; @@ -3251,10 +3270,10 @@ xg_tool_bar_item_expose_callback (w, event, client_data) event->area.x = max (0, event->area.x); event->area.y = max (0, event->area.y); - + event->area.width = max (width, event->area.width); event->area.height = max (height, event->area.height); - + return FALSE; } @@ -3289,6 +3308,8 @@ xg_create_tool_bar (f) x->toolbar_widget = gtk_toolbar_new (); x->handlebox_widget = gtk_handle_box_new (); + x->toolbar_detached = 0; + gtk_container_add (GTK_CONTAINER (x->handlebox_widget), x->toolbar_widget); @@ -3343,12 +3364,37 @@ update_frame_tool_bar (f) GList *icon_list; GList *iter; struct x_output *x = f->output_data.x; + int hmargin, vmargin; if (! FRAME_GTK_WIDGET (f)) return; BLOCK_INPUT; + if (INTEGERP (Vtool_bar_button_margin) + && XINT (Vtool_bar_button_margin) > 0) + { + hmargin = XFASTINT (Vtool_bar_button_margin); + vmargin = XFASTINT (Vtool_bar_button_margin); + } + else if (CONSP (Vtool_bar_button_margin)) + { + if (INTEGERP (XCAR (Vtool_bar_button_margin)) + && XINT (XCAR (Vtool_bar_button_margin)) > 0) + hmargin = XFASTINT (XCAR (Vtool_bar_button_margin)); + + if (INTEGERP (XCDR (Vtool_bar_button_margin)) + && XINT (XCDR (Vtool_bar_button_margin)) > 0) + vmargin = XFASTINT (XCDR (Vtool_bar_button_margin)); + } + + /* The natural size (i.e. when GTK uses 0 as margin) looks best, + so take DEFAULT_TOOL_BAR_BUTTON_MARGIN to mean "default for GTK", + i.e. zero. This means that margins less than + DEFAULT_TOOL_BAR_BUTTON_MARGIN has no effect. */ + hmargin = max (0, hmargin - DEFAULT_TOOL_BAR_BUTTON_MARGIN); + vmargin = max (0, vmargin - DEFAULT_TOOL_BAR_BUTTON_MARGIN); + if (! x->toolbar_widget) xg_create_tool_bar (f); @@ -3412,11 +3458,14 @@ update_frame_tool_bar (f) { GtkWidget *w = xg_get_image_for_pixmap (f, img, x->widget, NULL); + gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); + + /* The EMACS_INT cast avoids a warning. */ gtk_toolbar_append_item (GTK_TOOLBAR (x->toolbar_widget), 0, 0, 0, w, GTK_SIGNAL_FUNC (xg_tool_bar_callback), - (gpointer)i); + (gpointer) (EMACS_INT) i); /* Save the image so we can see if an update is needed when this function is called again. */ @@ -3446,14 +3495,15 @@ update_frame_tool_bar (f) rather than the GtkButton specific signals "enter" and "leave", so we can have only one callback. The event will tell us what kind of event it is. */ + /* The EMACS_INT cast avoids a warning. */ g_signal_connect (G_OBJECT (w), "enter-notify-event", G_CALLBACK (xg_tool_bar_help_callback), - (gpointer)i); + (gpointer) (EMACS_INT) i); g_signal_connect (G_OBJECT (w), "leave-notify-event", G_CALLBACK (xg_tool_bar_help_callback), - (gpointer)i); + (gpointer) (EMACS_INT) i); } } else @@ -3467,6 +3517,8 @@ update_frame_tool_bar (f) XG_TOOL_BAR_IMAGE_DATA); g_list_free (chlist); + gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin); + if (old_img != img->pixmap) (void) xg_get_image_for_pixmap (f, img, x->widget, wimage); @@ -3490,7 +3542,8 @@ update_frame_tool_bar (f) } gtk_widget_size_request (x->toolbar_widget, &new_req); - if (old_req.height != new_req.height) + if (old_req.height != new_req.height + && ! FRAME_X_OUTPUT (f)->toolbar_detached) { FRAME_TOOLBAR_HEIGHT (f) = new_req.height; xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f)); @@ -3536,6 +3589,8 @@ free_frame_tool_bar (f) void xg_initialize () { + GtkBindingSet *binding_set; + xg_ignore_gtk_scrollbar = 0; xg_detached_menus = 0; xg_menu_cb_list.prev = xg_menu_cb_list.next = @@ -3558,6 +3613,17 @@ xg_initialize () "gtk-key-theme-name", "Emacs", EMACS_CLASS); + + /* Make dialogs close on C-g. Since file dialog inherits from + dialog, this works for them also. */ + binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_DIALOG)); + gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK, + "close", 0); + + /* Make menus close on C-g. */ + binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_MENU_SHELL)); + gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK, + "cancel", 0); } #endif /* USE_GTK */