diff options
Diffstat (limited to 'src/gtkutil.c')
| -rw-r--r-- | src/gtkutil.c | 338 |
1 files changed, 217 insertions, 121 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c index 6ecd5d624af..754f61e366d 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -40,6 +40,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 40 | #include <X11/Xft/Xft.h> | 40 | #include <X11/Xft/Xft.h> |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #ifdef HAVE_GTK3 | ||
| 44 | #include <gtk/gtkx.h> | ||
| 45 | #endif | ||
| 46 | |||
| 43 | #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ | 47 | #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ |
| 44 | (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) | 48 | (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) |
| 45 | 49 | ||
| @@ -69,8 +73,26 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 69 | #define remove_submenu(w) gtk_menu_item_remove_submenu ((w)) | 73 | #define remove_submenu(w) gtk_menu_item_remove_submenu ((w)) |
| 70 | #endif | 74 | #endif |
| 71 | 75 | ||
| 76 | #ifndef HAVE_GTK3 | ||
| 77 | #ifdef USE_GTK_TOOLTIP | ||
| 78 | #define gdk_window_get_screen(w) gdk_drawable_get_screen (w) | ||
| 79 | #endif | ||
| 80 | #define gdk_window_get_geometry(w, a, b, c, d) \ | ||
| 81 | gdk_window_get_geometry (w, a, b, c, d, 0) | ||
| 82 | #define gdk_x11_window_lookup_for_display(d, w) \ | ||
| 83 | gdk_xid_table_lookup_for_display (d, w) | ||
| 84 | #define GDK_KEY_g GDK_g | ||
| 85 | #endif | ||
| 86 | |||
| 72 | #define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x)) | 87 | #define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x)) |
| 73 | 88 | ||
| 89 | /* Get the current value of the range, truncated to an integer. */ | ||
| 90 | static int | ||
| 91 | int_gtk_range_get_value (GtkRange *range) | ||
| 92 | { | ||
| 93 | return gtk_range_get_value (range); | ||
| 94 | } | ||
| 95 | |||
| 74 | 96 | ||
| 75 | /*********************************************************************** | 97 | /*********************************************************************** |
| 76 | Display handling functions | 98 | Display handling functions |
| @@ -88,7 +110,7 @@ static GdkDisplay *gdpy_def; | |||
| 88 | static void | 110 | static void |
| 89 | xg_set_screen (GtkWidget *w, FRAME_PTR f) | 111 | xg_set_screen (GtkWidget *w, FRAME_PTR f) |
| 90 | { | 112 | { |
| 91 | if (FRAME_X_DISPLAY (f) != GDK_DISPLAY ()) | 113 | if (FRAME_X_DISPLAY (f) != DEFAULT_GDK_DISPLAY ()) |
| 92 | { | 114 | { |
| 93 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | 115 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); |
| 94 | GdkScreen *gscreen = gdk_display_get_default_screen (gdpy); | 116 | GdkScreen *gscreen = gdk_display_get_default_screen (gdpy); |
| @@ -229,29 +251,55 @@ xg_create_default_cursor (Display *dpy) | |||
| 229 | return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR); | 251 | return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR); |
| 230 | } | 252 | } |
| 231 | 253 | ||
| 254 | static GdkPixbuf * | ||
| 255 | xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix) | ||
| 256 | { | ||
| 257 | int iunused; | ||
| 258 | GdkPixbuf *tmp_buf; | ||
| 259 | Window wunused; | ||
| 260 | unsigned int width, height, uunused; | ||
| 261 | XImage *xim; | ||
| 262 | |||
| 263 | XGetGeometry (FRAME_X_DISPLAY (f), pix, &wunused, &iunused, &iunused, | ||
| 264 | &width, &height, &uunused, &uunused); | ||
| 265 | |||
| 266 | xim = XGetImage (FRAME_X_DISPLAY (f), pix, 0, 0, width, height, | ||
| 267 | ~0, XYPixmap); | ||
| 268 | if (!xim) return 0; | ||
| 269 | |||
| 270 | tmp_buf = gdk_pixbuf_new_from_data ((guchar *) xim->data, | ||
| 271 | GDK_COLORSPACE_RGB, | ||
| 272 | FALSE, | ||
| 273 | xim->bitmap_unit, | ||
| 274 | (int) width, | ||
| 275 | (int) height, | ||
| 276 | xim->bytes_per_line, | ||
| 277 | NULL, | ||
| 278 | NULL); | ||
| 279 | XDestroyImage (xim); | ||
| 280 | return tmp_buf; | ||
| 281 | } | ||
| 282 | |||
| 232 | /* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */ | 283 | /* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */ |
| 233 | 284 | ||
| 234 | static GdkPixbuf * | 285 | static GdkPixbuf * |
| 235 | xg_get_pixbuf_from_pix_and_mask (GdkPixmap *gpix, | 286 | xg_get_pixbuf_from_pix_and_mask (FRAME_PTR f, |
| 236 | GdkPixmap *gmask, | 287 | Pixmap pix, |
| 237 | GdkColormap *cmap) | 288 | Pixmap mask) |
| 238 | { | 289 | { |
| 239 | int width, height; | 290 | int width, height; |
| 240 | GdkPixbuf *icon_buf, *tmp_buf; | 291 | GdkPixbuf *icon_buf, *tmp_buf; |
| 241 | 292 | ||
| 242 | gdk_drawable_get_size (gpix, &width, &height); | 293 | tmp_buf = xg_get_pixbuf_from_pixmap (f, pix); |
| 243 | tmp_buf = gdk_pixbuf_get_from_drawable (NULL, gpix, cmap, | ||
| 244 | 0, 0, 0, 0, width, height); | ||
| 245 | icon_buf = gdk_pixbuf_add_alpha (tmp_buf, FALSE, 0, 0, 0); | 294 | icon_buf = gdk_pixbuf_add_alpha (tmp_buf, FALSE, 0, 0, 0); |
| 246 | g_object_unref (G_OBJECT (tmp_buf)); | 295 | g_object_unref (G_OBJECT (tmp_buf)); |
| 247 | 296 | ||
| 248 | if (gmask) | 297 | width = gdk_pixbuf_get_width (icon_buf); |
| 298 | height = gdk_pixbuf_get_height (icon_buf); | ||
| 299 | |||
| 300 | if (mask) | ||
| 249 | { | 301 | { |
| 250 | GdkPixbuf *mask_buf = gdk_pixbuf_get_from_drawable (NULL, | 302 | GdkPixbuf *mask_buf = xg_get_pixbuf_from_pixmap (f, mask); |
| 251 | gmask, | ||
| 252 | NULL, | ||
| 253 | 0, 0, 0, 0, | ||
| 254 | width, height); | ||
| 255 | guchar *pixels = gdk_pixbuf_get_pixels (icon_buf); | 303 | guchar *pixels = gdk_pixbuf_get_pixels (icon_buf); |
| 256 | guchar *mask_pixels = gdk_pixbuf_get_pixels (mask_buf); | 304 | guchar *mask_pixels = gdk_pixbuf_get_pixels (mask_buf); |
| 257 | int rowstride = gdk_pixbuf_get_rowstride (icon_buf); | 305 | int rowstride = gdk_pixbuf_get_rowstride (icon_buf); |
| @@ -316,10 +364,6 @@ xg_get_image_for_pixmap (FRAME_PTR f, | |||
| 316 | GtkWidget *widget, | 364 | GtkWidget *widget, |
| 317 | GtkImage *old_widget) | 365 | GtkImage *old_widget) |
| 318 | { | 366 | { |
| 319 | GdkPixmap *gpix; | ||
| 320 | GdkPixmap *gmask; | ||
| 321 | GdkDisplay *gdpy; | ||
| 322 | GdkColormap *cmap; | ||
| 323 | GdkPixbuf *icon_buf; | 367 | GdkPixbuf *icon_buf; |
| 324 | 368 | ||
| 325 | /* If we have a file, let GTK do all the image handling. | 369 | /* If we have a file, let GTK do all the image handling. |
| @@ -347,10 +391,6 @@ xg_get_image_for_pixmap (FRAME_PTR f, | |||
| 347 | on a monochrome display, and sometimes bad on all displays with | 391 | on a monochrome display, and sometimes bad on all displays with |
| 348 | certain themes. */ | 392 | certain themes. */ |
| 349 | 393 | ||
| 350 | gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | ||
| 351 | gpix = gdk_pixmap_foreign_new_for_display (gdpy, img->pixmap); | ||
| 352 | gmask = img->mask ? gdk_pixmap_foreign_new_for_display (gdpy, img->mask) : 0; | ||
| 353 | |||
| 354 | /* This is a workaround to make icons look good on pseudo color | 394 | /* This is a workaround to make icons look good on pseudo color |
| 355 | displays. Apparently GTK expects the images to have an alpha | 395 | displays. Apparently GTK expects the images to have an alpha |
| 356 | channel. If they don't, insensitive and activated icons will | 396 | channel. If they don't, insensitive and activated icons will |
| @@ -360,18 +400,17 @@ xg_get_image_for_pixmap (FRAME_PTR f, | |||
| 360 | not associated with the img->pixmap. The img->pixmap may be removed | 400 | not associated with the img->pixmap. The img->pixmap may be removed |
| 361 | by clearing the image cache and then the tool bar redraw fails, since | 401 | by clearing the image cache and then the tool bar redraw fails, since |
| 362 | Gtk+ assumes the pixmap is always there. */ | 402 | Gtk+ assumes the pixmap is always there. */ |
| 363 | cmap = gtk_widget_get_colormap (widget); | 403 | icon_buf = xg_get_pixbuf_from_pix_and_mask (f, img->pixmap, img->mask); |
| 364 | icon_buf = xg_get_pixbuf_from_pix_and_mask (gpix, gmask, cmap); | ||
| 365 | 404 | ||
| 366 | if (! old_widget) | 405 | if (icon_buf) |
| 367 | old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf)); | 406 | { |
| 368 | else | 407 | if (! old_widget) |
| 369 | gtk_image_set_from_pixbuf (old_widget, icon_buf); | 408 | old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf)); |
| 370 | 409 | else | |
| 371 | g_object_unref (G_OBJECT (icon_buf)); | 410 | gtk_image_set_from_pixbuf (old_widget, icon_buf); |
| 372 | 411 | ||
| 373 | g_object_unref (G_OBJECT (gpix)); | 412 | g_object_unref (G_OBJECT (icon_buf)); |
| 374 | if (gmask) g_object_unref (G_OBJECT (gmask)); | 413 | } |
| 375 | 414 | ||
| 376 | return GTK_WIDGET (old_widget); | 415 | return GTK_WIDGET (old_widget); |
| 377 | } | 416 | } |
| @@ -455,22 +494,22 @@ get_utf8_string (const char *str) | |||
| 455 | gsize bytes_written; | 494 | gsize bytes_written; |
| 456 | unsigned char *p = (unsigned char *)str; | 495 | unsigned char *p = (unsigned char *)str; |
| 457 | char *cp, *up; | 496 | char *cp, *up; |
| 458 | GError *error = NULL; | 497 | GError *err = NULL; |
| 459 | 498 | ||
| 460 | while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, | 499 | while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, |
| 461 | &bytes_written, &error)) | 500 | &bytes_written, &err)) |
| 462 | && error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) | 501 | && err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) |
| 463 | { | 502 | { |
| 464 | ++nr_bad; | 503 | ++nr_bad; |
| 465 | p += bytes_written+1; | 504 | p += bytes_written+1; |
| 466 | g_error_free (error); | 505 | g_error_free (err); |
| 467 | error = NULL; | 506 | err = NULL; |
| 468 | } | 507 | } |
| 469 | 508 | ||
| 470 | if (error) | 509 | if (err) |
| 471 | { | 510 | { |
| 472 | g_error_free (error); | 511 | g_error_free (err); |
| 473 | error = NULL; | 512 | err = NULL; |
| 474 | } | 513 | } |
| 475 | if (cp) g_free (cp); | 514 | if (cp) g_free (cp); |
| 476 | 515 | ||
| @@ -478,16 +517,16 @@ get_utf8_string (const char *str) | |||
| 478 | p = (unsigned char *)str; | 517 | p = (unsigned char *)str; |
| 479 | 518 | ||
| 480 | while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, | 519 | while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, |
| 481 | &bytes_written, &error)) | 520 | &bytes_written, &err)) |
| 482 | && error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) | 521 | && err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) |
| 483 | { | 522 | { |
| 484 | strncpy (up, (char *)p, bytes_written); | 523 | strncpy (up, (char *)p, bytes_written); |
| 485 | sprintf (up + bytes_written, "\\%03o", p[bytes_written]); | 524 | sprintf (up + bytes_written, "\\%03o", p[bytes_written]); |
| 486 | up[bytes_written+4] = '\0'; | 525 | up[bytes_written+4] = '\0'; |
| 487 | up += bytes_written+4; | 526 | up += bytes_written+4; |
| 488 | p += bytes_written+1; | 527 | p += bytes_written+1; |
| 489 | g_error_free (error); | 528 | g_error_free (err); |
| 490 | error = NULL; | 529 | err = NULL; |
| 491 | } | 530 | } |
| 492 | 531 | ||
| 493 | if (cp) | 532 | if (cp) |
| @@ -495,10 +534,10 @@ get_utf8_string (const char *str) | |||
| 495 | strcat (utf8_str, cp); | 534 | strcat (utf8_str, cp); |
| 496 | g_free (cp); | 535 | g_free (cp); |
| 497 | } | 536 | } |
| 498 | if (error) | 537 | if (err) |
| 499 | { | 538 | { |
| 500 | g_error_free (error); | 539 | g_error_free (err); |
| 501 | error = NULL; | 540 | err = NULL; |
| 502 | } | 541 | } |
| 503 | } | 542 | } |
| 504 | return utf8_str; | 543 | return utf8_str; |
| @@ -514,28 +553,43 @@ xg_check_special_colors (struct frame *f, | |||
| 514 | XColor *color) | 553 | XColor *color) |
| 515 | { | 554 | { |
| 516 | int success_p = 0; | 555 | int success_p = 0; |
| 517 | if (FRAME_GTK_WIDGET (f)) | 556 | int get_bg = strcmp ("gtk_selection_bg_color", color_name) == 0; |
| 518 | { | 557 | int get_fg = !get_bg && strcmp ("gtk_selection_fg_color", color_name) == 0; |
| 519 | if (strcmp ("gtk_selection_bg_color", color_name) == 0) | ||
| 520 | { | ||
| 521 | GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f)); | ||
| 522 | color->red = gsty->bg[GTK_STATE_SELECTED].red; | ||
| 523 | color->green = gsty->bg[GTK_STATE_SELECTED].green; | ||
| 524 | color->blue = gsty->bg[GTK_STATE_SELECTED].blue; | ||
| 525 | color->pixel = gsty->bg[GTK_STATE_SELECTED].pixel; | ||
| 526 | success_p = 1; | ||
| 527 | } | ||
| 528 | else if (strcmp ("gtk_selection_fg_color", color_name) == 0) | ||
| 529 | { | ||
| 530 | GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f)); | ||
| 531 | color->red = gsty->fg[GTK_STATE_SELECTED].red; | ||
| 532 | color->green = gsty->fg[GTK_STATE_SELECTED].green; | ||
| 533 | color->blue = gsty->fg[GTK_STATE_SELECTED].blue; | ||
| 534 | color->pixel = gsty->fg[GTK_STATE_SELECTED].pixel; | ||
| 535 | success_p = 1; | ||
| 536 | } | ||
| 537 | } | ||
| 538 | 558 | ||
| 559 | if (! FRAME_GTK_WIDGET (f) || ! (get_bg || get_fg)) | ||
| 560 | return success_p; | ||
| 561 | |||
| 562 | BLOCK_INPUT; | ||
| 563 | { | ||
| 564 | #ifdef HAVE_GTK3 | ||
| 565 | GtkStyleContext *gsty | ||
| 566 | = gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 567 | GdkRGBA col; | ||
| 568 | char buf[64]; | ||
| 569 | int state = GTK_STATE_FLAG_SELECTED|GTK_STATE_FLAG_FOCUSED; | ||
| 570 | if (get_fg) | ||
| 571 | gtk_style_context_get_color (gsty, state, &col); | ||
| 572 | else | ||
| 573 | gtk_style_context_get_background_color (gsty, state, &col); | ||
| 574 | |||
| 575 | sprintf (buf, "rgbi:%lf/%lf/%lf", col.red, col.green, col.blue); | ||
| 576 | success_p = XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), | ||
| 577 | buf, color); | ||
| 578 | #else | ||
| 579 | GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f)); | ||
| 580 | GdkColor *grgb = get_bg | ||
| 581 | ? &gsty->bg[GTK_STATE_SELECTED] | ||
| 582 | : &gsty->fg[GTK_STATE_SELECTED]; | ||
| 583 | |||
| 584 | color->red = grgb->red; | ||
| 585 | color->green = grgb->green; | ||
| 586 | color->blue = grgb->blue; | ||
| 587 | color->pixel = grgb->pixel; | ||
| 588 | success_p = 1; | ||
| 589 | #endif | ||
| 590 | |||
| 591 | } | ||
| 592 | UNBLOCK_INPUT; | ||
| 539 | return success_p; | 593 | return success_p; |
| 540 | } | 594 | } |
| 541 | 595 | ||
| @@ -629,7 +683,7 @@ xg_prepare_tooltip (FRAME_PTR f, | |||
| 629 | encoded_string = ENCODE_UTF_8 (string); | 683 | encoded_string = ENCODE_UTF_8 (string); |
| 630 | widget = GTK_WIDGET (x->ttip_lbl); | 684 | widget = GTK_WIDGET (x->ttip_lbl); |
| 631 | gwin = gtk_widget_get_window (GTK_WIDGET (x->ttip_window)); | 685 | gwin = gtk_widget_get_window (GTK_WIDGET (x->ttip_window)); |
| 632 | screen = gdk_drawable_get_screen (gwin); | 686 | screen = gdk_window_get_screen (gwin); |
| 633 | settings = gtk_settings_get_for_screen (screen); | 687 | settings = gtk_settings_get_for_screen (screen); |
| 634 | g_object_get (settings, "gtk-enable-tooltips", &tt_enabled, NULL); | 688 | g_object_get (settings, "gtk-enable-tooltips", &tt_enabled, NULL); |
| 635 | if (tt_enabled) | 689 | if (tt_enabled) |
| @@ -650,7 +704,7 @@ xg_prepare_tooltip (FRAME_PTR f, | |||
| 650 | gtk_tooltip_set_custom (x->ttip_widget, widget); | 704 | gtk_tooltip_set_custom (x->ttip_widget, widget); |
| 651 | 705 | ||
| 652 | gtk_tooltip_set_text (x->ttip_widget, SDATA (encoded_string)); | 706 | gtk_tooltip_set_text (x->ttip_widget, SDATA (encoded_string)); |
| 653 | gtk_widget_size_request (GTK_WIDGET (x->ttip_window), &req); | 707 | gtk_widget_get_preferred_size (GTK_WIDGET (x->ttip_window), NULL, &req); |
| 654 | if (width) *width = req.width; | 708 | if (width) *width = req.width; |
| 655 | if (height) *height = req.height; | 709 | if (height) *height = req.height; |
| 656 | 710 | ||
| @@ -696,7 +750,7 @@ xg_hide_tooltip (FRAME_PTR f) | |||
| 696 | if (g_object_get_data (G_OBJECT (win), "restore-tt")) | 750 | if (g_object_get_data (G_OBJECT (win), "restore-tt")) |
| 697 | { | 751 | { |
| 698 | GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win)); | 752 | GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win)); |
| 699 | GdkScreen *screen = gdk_drawable_get_screen (gwin); | 753 | GdkScreen *screen = gdk_window_get_screen (gwin); |
| 700 | GtkSettings *settings = gtk_settings_get_for_screen (screen); | 754 | GtkSettings *settings = gtk_settings_get_for_screen (screen); |
| 701 | g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL); | 755 | g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL); |
| 702 | } | 756 | } |
| @@ -797,7 +851,7 @@ xg_frame_resized (FRAME_PTR f, int pixelwidth, int pixelheight) | |||
| 797 | if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f))) | 851 | if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f))) |
| 798 | gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), | 852 | gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), |
| 799 | 0, 0, | 853 | 0, 0, |
| 800 | &pixelwidth, &pixelheight, 0); | 854 | &pixelwidth, &pixelheight); |
| 801 | else return; | 855 | else return; |
| 802 | } | 856 | } |
| 803 | 857 | ||
| @@ -910,8 +964,8 @@ xg_win_to_widget (Display *dpy, Window wdesc) | |||
| 910 | 964 | ||
| 911 | BLOCK_INPUT; | 965 | BLOCK_INPUT; |
| 912 | 966 | ||
| 913 | gdkwin = gdk_xid_table_lookup_for_display (gdk_x11_lookup_xdisplay (dpy), | 967 | gdkwin = gdk_x11_window_lookup_for_display (gdk_x11_lookup_xdisplay (dpy), |
| 914 | wdesc); | 968 | wdesc); |
| 915 | if (gdkwin) | 969 | if (gdkwin) |
| 916 | { | 970 | { |
| 917 | GdkEvent event; | 971 | GdkEvent event; |
| @@ -923,14 +977,29 @@ xg_win_to_widget (Display *dpy, Window wdesc) | |||
| 923 | return gwdesc; | 977 | return gwdesc; |
| 924 | } | 978 | } |
| 925 | 979 | ||
| 926 | /* Fill in the GdkColor C so that it represents PIXEL. | 980 | /* Set the background of widget W to PIXEL. */ |
| 927 | W is the widget that color will be used for. Used to find colormap. */ | ||
| 928 | 981 | ||
| 929 | static void | 982 | static void |
| 930 | xg_pix_to_gcolor (GtkWidget *w, long unsigned int pixel, GdkColor *c) | 983 | xg_set_widget_bg (FRAME_PTR f, GtkWidget *w, long unsigned int pixel) |
| 931 | { | 984 | { |
| 985 | #ifdef HAVE_GTK3 | ||
| 986 | GdkRGBA bg; | ||
| 987 | XColor xbg; | ||
| 988 | xbg.pixel = pixel; | ||
| 989 | if (XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &xbg)) | ||
| 990 | { | ||
| 991 | bg.red = (double)xbg.red/65536.0; | ||
| 992 | bg.green = (double)xbg.green/65536.0; | ||
| 993 | bg.blue = (double)xbg.blue/65536.0; | ||
| 994 | bg.alpha = 1.0; | ||
| 995 | gtk_widget_override_background_color (w, GTK_STATE_FLAG_NORMAL, &bg); | ||
| 996 | } | ||
| 997 | #else | ||
| 998 | GdkColor bg; | ||
| 932 | GdkColormap *map = gtk_widget_get_colormap (w); | 999 | GdkColormap *map = gtk_widget_get_colormap (w); |
| 933 | gdk_colormap_query_color (map, pixel, c); | 1000 | gdk_colormap_query_color (map, pixel, &bg); |
| 1001 | gtk_widget_modify_bg (FRAME_GTK_WIDGET (f), GTK_STATE_NORMAL, &bg); | ||
| 1002 | #endif | ||
| 934 | } | 1003 | } |
| 935 | 1004 | ||
| 936 | /* Callback called when the gtk theme changes. | 1005 | /* Callback called when the gtk theme changes. |
| @@ -953,6 +1022,28 @@ style_changed_cb (GObject *go, | |||
| 953 | kbd_buffer_store_event (&event); | 1022 | kbd_buffer_store_event (&event); |
| 954 | } | 1023 | } |
| 955 | 1024 | ||
| 1025 | /* Called when a delete-event occurs on WIDGET. */ | ||
| 1026 | |||
| 1027 | static gboolean | ||
| 1028 | delete_cb (GtkWidget *widget, | ||
| 1029 | GdkEvent *event, | ||
| 1030 | gpointer user_data) | ||
| 1031 | { | ||
| 1032 | #ifdef HAVE_GTK3 | ||
| 1033 | /* The event doesn't arrive in the normal event loop. Send event | ||
| 1034 | here. */ | ||
| 1035 | FRAME_PTR f = (FRAME_PTR) user_data; | ||
| 1036 | struct input_event ie; | ||
| 1037 | |||
| 1038 | EVENT_INIT (ie); | ||
| 1039 | ie.kind = DELETE_WINDOW_EVENT; | ||
| 1040 | XSETFRAME (ie.frame_or_window, f); | ||
| 1041 | kbd_buffer_store_event (&ie); | ||
| 1042 | #endif | ||
| 1043 | |||
| 1044 | return TRUE; | ||
| 1045 | } | ||
| 1046 | |||
| 956 | /* Create and set up the GTK widgets for frame F. | 1047 | /* Create and set up the GTK widgets for frame F. |
| 957 | Return 0 if creation failed, non-zero otherwise. */ | 1048 | Return 0 if creation failed, non-zero otherwise. */ |
| 958 | 1049 | ||
| @@ -962,7 +1053,6 @@ xg_create_frame_widgets (FRAME_PTR f) | |||
| 962 | GtkWidget *wtop; | 1053 | GtkWidget *wtop; |
| 963 | GtkWidget *wvbox, *whbox; | 1054 | GtkWidget *wvbox, *whbox; |
| 964 | GtkWidget *wfixed; | 1055 | GtkWidget *wfixed; |
| 965 | GdkColor bg; | ||
| 966 | GtkRcStyle *style; | 1056 | GtkRcStyle *style; |
| 967 | char *title = 0; | 1057 | char *title = 0; |
| 968 | 1058 | ||
| @@ -1029,7 +1119,7 @@ xg_create_frame_widgets (FRAME_PTR f) | |||
| 1029 | /* Add callback to do nothing on WM_DELETE_WINDOW. The default in | 1119 | /* Add callback to do nothing on WM_DELETE_WINDOW. The default in |
| 1030 | GTK is to destroy the widget. We want Emacs to do that instead. */ | 1120 | GTK is to destroy the widget. We want Emacs to do that instead. */ |
| 1031 | g_signal_connect (G_OBJECT (wtop), "delete-event", | 1121 | g_signal_connect (G_OBJECT (wtop), "delete-event", |
| 1032 | G_CALLBACK (gtk_true), 0); | 1122 | G_CALLBACK (delete_cb), f); |
| 1033 | 1123 | ||
| 1034 | /* Convert our geometry parameters into a geometry string | 1124 | /* Convert our geometry parameters into a geometry string |
| 1035 | and specify it. | 1125 | and specify it. |
| @@ -1057,9 +1147,9 @@ xg_create_frame_widgets (FRAME_PTR f) | |||
| 1057 | 1147 | ||
| 1058 | /* Since GTK clears its window by filling with the background color, | 1148 | /* Since GTK clears its window by filling with the background color, |
| 1059 | we must keep X and GTK background in sync. */ | 1149 | we must keep X and GTK background in sync. */ |
| 1060 | xg_pix_to_gcolor (wfixed, FRAME_BACKGROUND_PIXEL (f), &bg); | 1150 | xg_set_widget_bg (f, wfixed, FRAME_BACKGROUND_PIXEL (f)); |
| 1061 | gtk_widget_modify_bg (wfixed, GTK_STATE_NORMAL, &bg); | ||
| 1062 | 1151 | ||
| 1152 | #ifndef HAVE_GTK3 | ||
| 1063 | /* Also, do not let any background pixmap to be set, this looks very | 1153 | /* Also, do not let any background pixmap to be set, this looks very |
| 1064 | bad as Emacs overwrites the background pixmap with its own idea | 1154 | bad as Emacs overwrites the background pixmap with its own idea |
| 1065 | of background color. */ | 1155 | of background color. */ |
| @@ -1068,6 +1158,9 @@ xg_create_frame_widgets (FRAME_PTR f) | |||
| 1068 | /* Must use g_strdup because gtk_widget_modify_style does g_free. */ | 1158 | /* Must use g_strdup because gtk_widget_modify_style does g_free. */ |
| 1069 | style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup ("<none>"); | 1159 | style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup ("<none>"); |
| 1070 | gtk_widget_modify_style (wfixed, style); | 1160 | gtk_widget_modify_style (wfixed, style); |
| 1161 | #else | ||
| 1162 | gtk_widget_set_can_focus (wfixed, TRUE); | ||
| 1163 | #endif | ||
| 1071 | 1164 | ||
| 1072 | #ifdef USE_GTK_TOOLTIP | 1165 | #ifdef USE_GTK_TOOLTIP |
| 1073 | /* Steal a tool tip window we can move ourselves. */ | 1166 | /* Steal a tool tip window we can move ourselves. */ |
| @@ -1104,7 +1197,9 @@ xg_free_frame_widgets (FRAME_PTR f) | |||
| 1104 | { | 1197 | { |
| 1105 | if (FRAME_GTK_OUTER_WIDGET (f)) | 1198 | if (FRAME_GTK_OUTER_WIDGET (f)) |
| 1106 | { | 1199 | { |
| 1200 | #ifdef USE_GTK_TOOLTIP | ||
| 1107 | struct x_output *x = f->output_data.x; | 1201 | struct x_output *x = f->output_data.x; |
| 1202 | #endif | ||
| 1108 | gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f)); | 1203 | gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f)); |
| 1109 | FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */ | 1204 | FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */ |
| 1110 | FRAME_GTK_OUTER_WIDGET (f) = 0; | 1205 | FRAME_GTK_OUTER_WIDGET (f) = 0; |
| @@ -1224,11 +1319,8 @@ xg_set_background_color (FRAME_PTR f, long unsigned int bg) | |||
| 1224 | { | 1319 | { |
| 1225 | if (FRAME_GTK_WIDGET (f)) | 1320 | if (FRAME_GTK_WIDGET (f)) |
| 1226 | { | 1321 | { |
| 1227 | GdkColor gdk_bg; | ||
| 1228 | |||
| 1229 | BLOCK_INPUT; | 1322 | BLOCK_INPUT; |
| 1230 | xg_pix_to_gcolor (FRAME_GTK_WIDGET (f), bg, &gdk_bg); | 1323 | xg_set_widget_bg (f, FRAME_GTK_WIDGET (f), FRAME_BACKGROUND_PIXEL (f)); |
| 1231 | gtk_widget_modify_bg (FRAME_GTK_WIDGET (f), GTK_STATE_NORMAL, &gdk_bg); | ||
| 1232 | UNBLOCK_INPUT; | 1324 | UNBLOCK_INPUT; |
| 1233 | } | 1325 | } |
| 1234 | } | 1326 | } |
| @@ -1240,11 +1332,10 @@ xg_set_background_color (FRAME_PTR f, long unsigned int bg) | |||
| 1240 | void | 1332 | void |
| 1241 | xg_set_frame_icon (FRAME_PTR f, Pixmap icon_pixmap, Pixmap icon_mask) | 1333 | xg_set_frame_icon (FRAME_PTR f, Pixmap icon_pixmap, Pixmap icon_mask) |
| 1242 | { | 1334 | { |
| 1243 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | 1335 | GdkPixbuf *gp = xg_get_pixbuf_from_pix_and_mask (f, |
| 1244 | GdkPixmap *gpix = gdk_pixmap_foreign_new_for_display (gdpy, icon_pixmap); | 1336 | icon_pixmap, |
| 1245 | GdkPixmap *gmask = gdk_pixmap_foreign_new_for_display (gdpy, icon_mask); | 1337 | icon_mask); |
| 1246 | GdkPixbuf *gp = xg_get_pixbuf_from_pix_and_mask (gpix, gmask, NULL); | 1338 | if (gp) |
| 1247 | |||
| 1248 | gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), gp); | 1339 | gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), gp); |
| 1249 | } | 1340 | } |
| 1250 | 1341 | ||
| @@ -1326,8 +1417,6 @@ create_dialog (widget_value *wv, | |||
| 1326 | GtkDialog *wd = GTK_DIALOG (wdialog); | 1417 | GtkDialog *wd = GTK_DIALOG (wdialog); |
| 1327 | GtkBox *cur_box = GTK_BOX (gtk_dialog_get_action_area (wd)); | 1418 | GtkBox *cur_box = GTK_BOX (gtk_dialog_get_action_area (wd)); |
| 1328 | widget_value *item; | 1419 | widget_value *item; |
| 1329 | GtkWidget *wvbox; | ||
| 1330 | GtkWidget *whbox_up; | ||
| 1331 | GtkWidget *whbox_down; | 1420 | GtkWidget *whbox_down; |
| 1332 | 1421 | ||
| 1333 | /* If the number of buttons is greater than 4, make two rows of buttons | 1422 | /* If the number of buttons is greater than 4, make two rows of buttons |
| @@ -1343,8 +1432,8 @@ create_dialog (widget_value *wv, | |||
| 1343 | 1432 | ||
| 1344 | if (make_two_rows) | 1433 | if (make_two_rows) |
| 1345 | { | 1434 | { |
| 1346 | wvbox = gtk_vbox_new (TRUE, button_spacing); | 1435 | GtkWidget *wvbox = gtk_vbox_new (TRUE, button_spacing); |
| 1347 | whbox_up = gtk_hbox_new (FALSE, 0); | 1436 | GtkWidget *whbox_up = gtk_hbox_new (FALSE, 0); |
| 1348 | whbox_down = gtk_hbox_new (FALSE, 0); | 1437 | whbox_down = gtk_hbox_new (FALSE, 0); |
| 1349 | 1438 | ||
| 1350 | gtk_box_pack_start (cur_box, wvbox, FALSE, FALSE, 0); | 1439 | gtk_box_pack_start (cur_box, wvbox, FALSE, FALSE, 0); |
| @@ -1381,7 +1470,7 @@ create_dialog (widget_value *wv, | |||
| 1381 | /* Try to make dialog look better. Must realize first so | 1470 | /* Try to make dialog look better. Must realize first so |
| 1382 | the widget can calculate the size it needs. */ | 1471 | the widget can calculate the size it needs. */ |
| 1383 | gtk_widget_realize (w); | 1472 | gtk_widget_realize (w); |
| 1384 | gtk_widget_size_request (w, &req); | 1473 | gtk_widget_get_preferred_size (w, NULL, &req); |
| 1385 | gtk_box_set_spacing (wvbox, req.height); | 1474 | gtk_box_set_spacing (wvbox, req.height); |
| 1386 | if (item->value && strlen (item->value) > 0) | 1475 | if (item->value && strlen (item->value) > 0) |
| 1387 | button_spacing = 2*req.width/strlen (item->value); | 1476 | button_spacing = 2*req.width/strlen (item->value); |
| @@ -1613,7 +1702,7 @@ xg_get_file_with_chooser (FRAME_PTR f, | |||
| 1613 | int mustmatch_p, int only_dir_p, | 1702 | int mustmatch_p, int only_dir_p, |
| 1614 | xg_get_file_func *func) | 1703 | xg_get_file_func *func) |
| 1615 | { | 1704 | { |
| 1616 | char message[1024]; | 1705 | char msgbuf[1024]; |
| 1617 | 1706 | ||
| 1618 | GtkWidget *filewin, *wtoggle, *wbox, *wmessage; | 1707 | GtkWidget *filewin, *wtoggle, *wbox, *wmessage; |
| 1619 | GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); | 1708 | GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); |
| @@ -1649,16 +1738,16 @@ xg_get_file_with_chooser (FRAME_PTR f, | |||
| 1649 | 1738 | ||
| 1650 | if (x_gtk_file_dialog_help_text) | 1739 | if (x_gtk_file_dialog_help_text) |
| 1651 | { | 1740 | { |
| 1652 | message[0] = '\0'; | 1741 | msgbuf[0] = '\0'; |
| 1653 | /* Gtk+ 2.10 has the file name text entry box integrated in the dialog. | 1742 | /* Gtk+ 2.10 has the file name text entry box integrated in the dialog. |
| 1654 | Show the C-l help text only for versions < 2.10. */ | 1743 | Show the C-l help text only for versions < 2.10. */ |
| 1655 | if (gtk_check_version (2, 10, 0) && action != GTK_FILE_CHOOSER_ACTION_SAVE) | 1744 | if (gtk_check_version (2, 10, 0) && action != GTK_FILE_CHOOSER_ACTION_SAVE) |
| 1656 | strcat (message, "\nType C-l to display a file name text entry box.\n"); | 1745 | strcat (msgbuf, "\nType C-l to display a file name text entry box.\n"); |
| 1657 | strcat (message, "\nIf you don't like this file selector, use the " | 1746 | strcat (msgbuf, "\nIf you don't like this file selector, use the " |
| 1658 | "corresponding\nkey binding or customize " | 1747 | "corresponding\nkey binding or customize " |
| 1659 | "use-file-dialog to turn it off."); | 1748 | "use-file-dialog to turn it off."); |
| 1660 | 1749 | ||
| 1661 | wmessage = gtk_label_new (message); | 1750 | wmessage = gtk_label_new (msgbuf); |
| 1662 | gtk_widget_show (wmessage); | 1751 | gtk_widget_show (wmessage); |
| 1663 | } | 1752 | } |
| 1664 | 1753 | ||
| @@ -3028,7 +3117,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data) | |||
| 3028 | { | 3117 | { |
| 3029 | GtkRequisition req; | 3118 | GtkRequisition req; |
| 3030 | FRAME_PTR f = (FRAME_PTR) user_data; | 3119 | FRAME_PTR f = (FRAME_PTR) user_data; |
| 3031 | gtk_widget_size_request (w, &req); | 3120 | gtk_widget_get_preferred_size (w, NULL, &req); |
| 3032 | if (FRAME_MENUBAR_HEIGHT (f) != req.height) | 3121 | if (FRAME_MENUBAR_HEIGHT (f) != req.height) |
| 3033 | { | 3122 | { |
| 3034 | FRAME_MENUBAR_HEIGHT (f) = req.height; | 3123 | FRAME_MENUBAR_HEIGHT (f) = req.height; |
| @@ -3059,7 +3148,7 @@ xg_update_frame_menubar (FRAME_PTR f) | |||
| 3059 | 3148 | ||
| 3060 | g_signal_connect (x->menubar_widget, "map", G_CALLBACK (menubar_map_cb), f); | 3149 | g_signal_connect (x->menubar_widget, "map", G_CALLBACK (menubar_map_cb), f); |
| 3061 | gtk_widget_show_all (x->menubar_widget); | 3150 | gtk_widget_show_all (x->menubar_widget); |
| 3062 | gtk_widget_size_request (x->menubar_widget, &req); | 3151 | gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req); |
| 3063 | 3152 | ||
| 3064 | /* If menu bar doesn't know its height yet, cheat a little so the frame | 3153 | /* If menu bar doesn't know its height yet, cheat a little so the frame |
| 3065 | doesn't jump so much when resized later in menubar_map_cb. */ | 3154 | doesn't jump so much when resized later in menubar_map_cb. */ |
| @@ -3120,7 +3209,7 @@ xg_event_is_for_menubar (FRAME_PTR f, XEvent *event) | |||
| 3120 | return 0; | 3209 | return 0; |
| 3121 | 3210 | ||
| 3122 | gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | 3211 | gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); |
| 3123 | gw = gdk_xid_table_lookup_for_display (gdpy, event->xbutton.window); | 3212 | gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); |
| 3124 | if (! gw) return 0; | 3213 | if (! gw) return 0; |
| 3125 | gevent.any.window = gw; | 3214 | gevent.any.window = gw; |
| 3126 | gwdesc = gtk_get_event_widget (&gevent); | 3215 | gwdesc = gtk_get_event_widget (&gevent); |
| @@ -3284,8 +3373,12 @@ xg_create_scroll_bar (FRAME_PTR f, | |||
| 3284 | { | 3373 | { |
| 3285 | GtkWidget *wscroll; | 3374 | GtkWidget *wscroll; |
| 3286 | GtkWidget *webox; | 3375 | GtkWidget *webox; |
| 3287 | GtkObject *vadj; | ||
| 3288 | int scroll_id; | 3376 | int scroll_id; |
| 3377 | #ifdef HAVE_GTK3 | ||
| 3378 | GtkAdjustment *vadj; | ||
| 3379 | #else | ||
| 3380 | GtkObject *vadj; | ||
| 3381 | #endif | ||
| 3289 | 3382 | ||
| 3290 | /* Page, step increment values are not so important here, they | 3383 | /* Page, step increment values are not so important here, they |
| 3291 | will be corrected in x_set_toolkit_scroll_bar_thumb. */ | 3384 | will be corrected in x_set_toolkit_scroll_bar_thumb. */ |
| @@ -3295,7 +3388,9 @@ xg_create_scroll_bar (FRAME_PTR f, | |||
| 3295 | wscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (vadj)); | 3388 | wscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (vadj)); |
| 3296 | webox = gtk_event_box_new (); | 3389 | webox = gtk_event_box_new (); |
| 3297 | gtk_widget_set_name (wscroll, scroll_bar_name); | 3390 | gtk_widget_set_name (wscroll, scroll_bar_name); |
| 3391 | #ifndef HAVE_GTK3 | ||
| 3298 | gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS); | 3392 | gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS); |
| 3393 | #endif | ||
| 3299 | g_object_set_data (G_OBJECT (wscroll), XG_FRAME_DATA, (gpointer)f); | 3394 | g_object_set_data (G_OBJECT (wscroll), XG_FRAME_DATA, (gpointer)f); |
| 3300 | 3395 | ||
| 3301 | scroll_id = xg_store_widget_in_map (wscroll); | 3396 | scroll_id = xg_store_widget_in_map (wscroll); |
| @@ -3474,7 +3569,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, | |||
| 3474 | changed = 1; | 3569 | changed = 1; |
| 3475 | } | 3570 | } |
| 3476 | 3571 | ||
| 3477 | if (changed || (int) gtk_range_get_value (GTK_RANGE (wscroll)) != value) | 3572 | if (changed || int_gtk_range_get_value (GTK_RANGE (wscroll)) != value) |
| 3478 | { | 3573 | { |
| 3479 | BLOCK_INPUT; | 3574 | BLOCK_INPUT; |
| 3480 | 3575 | ||
| @@ -3482,7 +3577,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, | |||
| 3482 | ignore_gtk_scrollbar to make the callback do nothing */ | 3577 | ignore_gtk_scrollbar to make the callback do nothing */ |
| 3483 | xg_ignore_gtk_scrollbar = 1; | 3578 | xg_ignore_gtk_scrollbar = 1; |
| 3484 | 3579 | ||
| 3485 | if ((int) gtk_range_get_value (GTK_RANGE (wscroll)) != value) | 3580 | if (int_gtk_range_get_value (GTK_RANGE (wscroll)) != value) |
| 3486 | gtk_range_set_value (GTK_RANGE (wscroll), (gdouble)value); | 3581 | gtk_range_set_value (GTK_RANGE (wscroll), (gdouble)value); |
| 3487 | else if (changed) | 3582 | else if (changed) |
| 3488 | gtk_adjustment_changed (adj); | 3583 | gtk_adjustment_changed (adj); |
| @@ -3578,8 +3673,8 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data) | |||
| 3578 | { | 3673 | { |
| 3579 | /* The EMACS_INT cast avoids a warning. */ | 3674 | /* The EMACS_INT cast avoids a warning. */ |
| 3580 | int idx = (int) (EMACS_INT) client_data; | 3675 | int idx = (int) (EMACS_INT) client_data; |
| 3581 | int mod = (int) (EMACS_INT) g_object_get_data (G_OBJECT (w), | 3676 | gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); |
| 3582 | XG_TOOL_BAR_LAST_MODIFIER); | 3677 | int mod = (int) (EMACS_INT) gmod; |
| 3583 | 3678 | ||
| 3584 | FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); | 3679 | FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); |
| 3585 | Lisp_Object key, frame; | 3680 | Lisp_Object key, frame; |
| @@ -3793,8 +3888,8 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox, | |||
| 3793 | { | 3888 | { |
| 3794 | GtkRequisition req, req2; | 3889 | GtkRequisition req, req2; |
| 3795 | FRAME_X_OUTPUT (f)->toolbar_detached = 1; | 3890 | FRAME_X_OUTPUT (f)->toolbar_detached = 1; |
| 3796 | gtk_widget_size_request (GTK_WIDGET (wbox), &req); | 3891 | gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req); |
| 3797 | gtk_widget_size_request (w, &req2); | 3892 | gtk_widget_get_preferred_size (w, NULL, &req2); |
| 3798 | req.width -= req2.width; | 3893 | req.width -= req2.width; |
| 3799 | req.height -= req2.height; | 3894 | req.height -= req2.height; |
| 3800 | if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0) | 3895 | if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0) |
| @@ -3828,8 +3923,8 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox, | |||
| 3828 | { | 3923 | { |
| 3829 | GtkRequisition req, req2; | 3924 | GtkRequisition req, req2; |
| 3830 | FRAME_X_OUTPUT (f)->toolbar_detached = 0; | 3925 | FRAME_X_OUTPUT (f)->toolbar_detached = 0; |
| 3831 | gtk_widget_size_request (GTK_WIDGET (wbox), &req); | 3926 | gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req); |
| 3832 | gtk_widget_size_request (w, &req2); | 3927 | gtk_widget_get_preferred_size (w, NULL, &req2); |
| 3833 | req.width += req2.width; | 3928 | req.width += req2.width; |
| 3834 | req.height += req2.height; | 3929 | req.height += req2.height; |
| 3835 | if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0) | 3930 | if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0) |
| @@ -3894,6 +3989,7 @@ xg_tool_bar_help_callback (GtkWidget *w, | |||
| 3894 | 3989 | ||
| 3895 | Returns FALSE to tell GTK to keep processing this event. */ | 3990 | Returns FALSE to tell GTK to keep processing this event. */ |
| 3896 | 3991 | ||
| 3992 | #ifndef HAVE_GTK3 | ||
| 3897 | static gboolean | 3993 | static gboolean |
| 3898 | xg_tool_bar_item_expose_callback (GtkWidget *w, | 3994 | xg_tool_bar_item_expose_callback (GtkWidget *w, |
| 3899 | GdkEventExpose *event, | 3995 | GdkEventExpose *event, |
| @@ -3902,7 +3998,6 @@ xg_tool_bar_item_expose_callback (GtkWidget *w, | |||
| 3902 | gint width, height; | 3998 | gint width, height; |
| 3903 | 3999 | ||
| 3904 | gdk_drawable_get_size (event->window, &width, &height); | 4000 | gdk_drawable_get_size (event->window, &width, &height); |
| 3905 | |||
| 3906 | event->area.x -= width > event->area.width ? width-event->area.width : 0; | 4001 | event->area.x -= width > event->area.width ? width-event->area.width : 0; |
| 3907 | event->area.y -= height > event->area.height ? height-event->area.height : 0; | 4002 | event->area.y -= height > event->area.height ? height-event->area.height : 0; |
| 3908 | 4003 | ||
| @@ -3914,6 +4009,7 @@ xg_tool_bar_item_expose_callback (GtkWidget *w, | |||
| 3914 | 4009 | ||
| 3915 | return FALSE; | 4010 | return FALSE; |
| 3916 | } | 4011 | } |
| 4012 | #endif | ||
| 3917 | 4013 | ||
| 3918 | #ifdef HAVE_GTK_ORIENTABLE_SET_ORIENTATION | 4014 | #ifdef HAVE_GTK_ORIENTABLE_SET_ORIENTATION |
| 3919 | #define toolbar_set_orientation(w, o) \ | 4015 | #define toolbar_set_orientation(w, o) \ |
| @@ -4063,13 +4159,14 @@ xg_make_tool_item (FRAME_PTR f, | |||
| 4063 | 4159 | ||
| 4064 | g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f); | 4160 | g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f); |
| 4065 | 4161 | ||
| 4162 | #ifndef HAVE_GTK3 | ||
| 4066 | /* Catch expose events to overcome an annoying redraw bug, see | 4163 | /* Catch expose events to overcome an annoying redraw bug, see |
| 4067 | comment for xg_tool_bar_item_expose_callback. */ | 4164 | comment for xg_tool_bar_item_expose_callback. */ |
| 4068 | g_signal_connect (G_OBJECT (ti), | 4165 | g_signal_connect (G_OBJECT (ti), |
| 4069 | "expose-event", | 4166 | "expose-event", |
| 4070 | G_CALLBACK (xg_tool_bar_item_expose_callback), | 4167 | G_CALLBACK (xg_tool_bar_item_expose_callback), |
| 4071 | 0); | 4168 | 0); |
| 4072 | 4169 | #endif | |
| 4073 | gtk_tool_item_set_homogeneous (ti, FALSE); | 4170 | gtk_tool_item_set_homogeneous (ti, FALSE); |
| 4074 | 4171 | ||
| 4075 | /* Callback to save modifyer mask (Shift/Control, etc). GTK makes | 4172 | /* Callback to save modifyer mask (Shift/Control, etc). GTK makes |
| @@ -4128,9 +4225,9 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name, | |||
| 4128 | } | 4225 | } |
| 4129 | else | 4226 | else |
| 4130 | { | 4227 | { |
| 4131 | Pixmap old_img | 4228 | gpointer gold_img = g_object_get_data (G_OBJECT (wimage), |
| 4132 | = (Pixmap) g_object_get_data (G_OBJECT (wimage), | 4229 | XG_TOOL_BAR_IMAGE_DATA); |
| 4133 | XG_TOOL_BAR_IMAGE_DATA); | 4230 | Pixmap old_img = (Pixmap) gold_img; |
| 4134 | if (old_img != img->pixmap) | 4231 | if (old_img != img->pixmap) |
| 4135 | return 1; | 4232 | return 1; |
| 4136 | } | 4233 | } |
| @@ -4153,7 +4250,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f) | |||
| 4153 | GtkRequisition req; | 4250 | GtkRequisition req; |
| 4154 | int nl = 0, nr = 0, nt = 0, nb = 0; | 4251 | int nl = 0, nr = 0, nt = 0, nb = 0; |
| 4155 | 4252 | ||
| 4156 | gtk_widget_size_request (GTK_WIDGET (x->handlebox_widget), &req); | 4253 | gtk_widget_get_preferred_size (GTK_WIDGET (x->handlebox_widget), NULL, &req); |
| 4157 | if (x->toolbar_in_hbox) | 4254 | if (x->toolbar_in_hbox) |
| 4158 | { | 4255 | { |
| 4159 | int pos; | 4256 | int pos; |
| @@ -4203,7 +4300,6 @@ update_frame_tool_bar (FRAME_PTR f) | |||
| 4203 | GtkToolItem *ti; | 4300 | GtkToolItem *ti; |
| 4204 | GtkTextDirection dir; | 4301 | GtkTextDirection dir; |
| 4205 | int pack_tool_bar = x->handlebox_widget == NULL; | 4302 | int pack_tool_bar = x->handlebox_widget == NULL; |
| 4206 | |||
| 4207 | Lisp_Object style; | 4303 | Lisp_Object style; |
| 4208 | int text_image, horiz; | 4304 | int text_image, horiz; |
| 4209 | 4305 | ||
| @@ -4551,13 +4647,13 @@ xg_initialize (void) | |||
| 4551 | /* Make dialogs close on C-g. Since file dialog inherits from | 4647 | /* Make dialogs close on C-g. Since file dialog inherits from |
| 4552 | dialog, this works for them also. */ | 4648 | dialog, this works for them also. */ |
| 4553 | binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_DIALOG)); | 4649 | binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_DIALOG)); |
| 4554 | gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK, | 4650 | gtk_binding_entry_add_signal (binding_set, GDK_KEY_g, GDK_CONTROL_MASK, |
| 4555 | "close", 0); | 4651 | "close", 0); |
| 4556 | 4652 | ||
| 4557 | /* Make menus close on C-g. */ | 4653 | /* Make menus close on C-g. */ |
| 4558 | binding_set = gtk_binding_set_by_class (g_type_class_ref | 4654 | binding_set = gtk_binding_set_by_class (g_type_class_ref |
| 4559 | (GTK_TYPE_MENU_SHELL)); | 4655 | (GTK_TYPE_MENU_SHELL)); |
| 4560 | gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK, | 4656 | gtk_binding_entry_add_signal (binding_set, GDK_KEY_g, GDK_CONTROL_MASK, |
| 4561 | "cancel", 0); | 4657 | "cancel", 0); |
| 4562 | } | 4658 | } |
| 4563 | 4659 | ||