diff options
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 246 |
1 files changed, 179 insertions, 67 deletions
diff --git a/src/xterm.c b/src/xterm.c index 20516ee9d6f..ddc5db23414 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* X Communication module for terminals which understand the X protocol. | 1 | /* X Communication module for terminals which understand the X protocol. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1993-2011 Free Software Foundation, Inc. | 3 | Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -93,6 +93,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 93 | 93 | ||
| 94 | #ifdef USE_GTK | 94 | #ifdef USE_GTK |
| 95 | #include "gtkutil.h" | 95 | #include "gtkutil.h" |
| 96 | #ifdef HAVE_GTK3 | ||
| 97 | #include <X11/Xproto.h> | ||
| 98 | #endif | ||
| 96 | #endif | 99 | #endif |
| 97 | 100 | ||
| 98 | #ifdef USE_LUCID | 101 | #ifdef USE_LUCID |
| @@ -100,7 +103,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 100 | #endif | 103 | #endif |
| 101 | 104 | ||
| 102 | #ifdef USE_X_TOOLKIT | 105 | #ifdef USE_X_TOOLKIT |
| 103 | #if !defined(NO_EDITRES) | 106 | #if !defined (NO_EDITRES) |
| 104 | #define HACK_EDITRES | 107 | #define HACK_EDITRES |
| 105 | extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *); | 108 | extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *); |
| 106 | #endif /* not NO_EDITRES */ | 109 | #endif /* not NO_EDITRES */ |
| @@ -343,7 +346,7 @@ static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, | |||
| 343 | enum scroll_bar_part *, | 346 | enum scroll_bar_part *, |
| 344 | Lisp_Object *, Lisp_Object *, | 347 | Lisp_Object *, Lisp_Object *, |
| 345 | Time *); | 348 | Time *); |
| 346 | static void x_handle_net_wm_state (struct frame *, XPropertyEvent *); | 349 | static int x_handle_net_wm_state (struct frame *, XPropertyEvent *); |
| 347 | static void x_check_fullscreen (struct frame *); | 350 | static void x_check_fullscreen (struct frame *); |
| 348 | static void x_check_expected_move (struct frame *, int, int); | 351 | static void x_check_expected_move (struct frame *, int, int); |
| 349 | static void x_sync_with_move (struct frame *, int, int, int); | 352 | static void x_sync_with_move (struct frame *, int, int, int); |
| @@ -442,6 +445,27 @@ x_display_info_for_display (Display *dpy) | |||
| 442 | return 0; | 445 | return 0; |
| 443 | } | 446 | } |
| 444 | 447 | ||
| 448 | static Window | ||
| 449 | x_find_topmost_parent (struct frame *f) | ||
| 450 | { | ||
| 451 | struct x_output *x = f->output_data.x; | ||
| 452 | Window win = None, wi = x->parent_desc; | ||
| 453 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 454 | |||
| 455 | while (wi != FRAME_X_DISPLAY_INFO (f)->root_window) | ||
| 456 | { | ||
| 457 | Window root; | ||
| 458 | Window *children; | ||
| 459 | unsigned int nchildren; | ||
| 460 | |||
| 461 | win = wi; | ||
| 462 | XQueryTree (dpy, win, &root, &wi, &children, &nchildren); | ||
| 463 | XFree (children); | ||
| 464 | } | ||
| 465 | |||
| 466 | return win; | ||
| 467 | } | ||
| 468 | |||
| 445 | #define OPAQUE 0xffffffff | 469 | #define OPAQUE 0xffffffff |
| 446 | 470 | ||
| 447 | void | 471 | void |
| @@ -453,6 +477,7 @@ x_set_frame_alpha (struct frame *f) | |||
| 453 | double alpha = 1.0; | 477 | double alpha = 1.0; |
| 454 | double alpha_min = 1.0; | 478 | double alpha_min = 1.0; |
| 455 | unsigned long opac; | 479 | unsigned long opac; |
| 480 | Window parent; | ||
| 456 | 481 | ||
| 457 | if (dpyinfo->x_highlight_frame == f) | 482 | if (dpyinfo->x_highlight_frame == f) |
| 458 | alpha = f->alpha[0]; | 483 | alpha = f->alpha[0]; |
| @@ -473,6 +498,19 @@ x_set_frame_alpha (struct frame *f) | |||
| 473 | 498 | ||
| 474 | opac = alpha * OPAQUE; | 499 | opac = alpha * OPAQUE; |
| 475 | 500 | ||
| 501 | x_catch_errors (dpy); | ||
| 502 | |||
| 503 | /* If there is a parent from the window manager, put the property there | ||
| 504 | also, to work around broken window managers that fail to do that. | ||
| 505 | Do this unconditionally as this function is called on reparent when | ||
| 506 | alpha has not changed on the frame. */ | ||
| 507 | |||
| 508 | parent = x_find_topmost_parent (f); | ||
| 509 | if (parent != None) | ||
| 510 | XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, | ||
| 511 | XA_CARDINAL, 32, PropModeReplace, | ||
| 512 | (unsigned char *) &opac, 1L); | ||
| 513 | |||
| 476 | /* return unless necessary */ | 514 | /* return unless necessary */ |
| 477 | { | 515 | { |
| 478 | unsigned char *data; | 516 | unsigned char *data; |
| @@ -480,7 +518,6 @@ x_set_frame_alpha (struct frame *f) | |||
| 480 | int rc, format; | 518 | int rc, format; |
| 481 | unsigned long n, left; | 519 | unsigned long n, left; |
| 482 | 520 | ||
| 483 | x_catch_errors (dpy); | ||
| 484 | rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, | 521 | rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, |
| 485 | 0L, 1L, False, XA_CARDINAL, | 522 | 0L, 1L, False, XA_CARDINAL, |
| 486 | &actual, &format, &n, &left, | 523 | &actual, &format, &n, &left, |
| @@ -1272,6 +1309,8 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s) | |||
| 1272 | int y = s->ybase; | 1309 | int y = s->ybase; |
| 1273 | 1310 | ||
| 1274 | for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) | 1311 | for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) |
| 1312 | /* TAB in a composition means display glyphs with padding | ||
| 1313 | space on the left or right. */ | ||
| 1275 | if (COMPOSITION_GLYPH (s->cmp, j) != '\t') | 1314 | if (COMPOSITION_GLYPH (s->cmp, j) != '\t') |
| 1276 | { | 1315 | { |
| 1277 | int xx = x + s->cmp->offsets[j * 2]; | 1316 | int xx = x + s->cmp->offsets[j * 2]; |
| @@ -1625,19 +1664,18 @@ x_color_cells (Display *dpy, int *ncells) | |||
| 1625 | if (dpyinfo->color_cells == NULL) | 1664 | if (dpyinfo->color_cells == NULL) |
| 1626 | { | 1665 | { |
| 1627 | Screen *screen = dpyinfo->screen; | 1666 | Screen *screen = dpyinfo->screen; |
| 1667 | int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); | ||
| 1628 | int i; | 1668 | int i; |
| 1629 | 1669 | ||
| 1630 | dpyinfo->ncolor_cells | 1670 | dpyinfo->color_cells = xnmalloc (ncolor_cells, |
| 1631 | = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); | 1671 | sizeof *dpyinfo->color_cells); |
| 1632 | dpyinfo->color_cells | 1672 | dpyinfo->ncolor_cells = ncolor_cells; |
| 1633 | = (XColor *) xmalloc (dpyinfo->ncolor_cells | ||
| 1634 | * sizeof *dpyinfo->color_cells); | ||
| 1635 | 1673 | ||
| 1636 | for (i = 0; i < dpyinfo->ncolor_cells; ++i) | 1674 | for (i = 0; i < ncolor_cells; ++i) |
| 1637 | dpyinfo->color_cells[i].pixel = i; | 1675 | dpyinfo->color_cells[i].pixel = i; |
| 1638 | 1676 | ||
| 1639 | XQueryColors (dpy, dpyinfo->cmap, | 1677 | XQueryColors (dpy, dpyinfo->cmap, |
| 1640 | dpyinfo->color_cells, dpyinfo->ncolor_cells); | 1678 | dpyinfo->color_cells, ncolor_cells); |
| 1641 | } | 1679 | } |
| 1642 | 1680 | ||
| 1643 | *ncells = dpyinfo->ncolor_cells; | 1681 | *ncells = dpyinfo->ncolor_cells; |
| @@ -2254,7 +2292,8 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 2254 | static void | 2292 | static void |
| 2255 | x_draw_image_relief (struct glyph_string *s) | 2293 | x_draw_image_relief (struct glyph_string *s) |
| 2256 | { | 2294 | { |
| 2257 | int x0, y0, x1, y1, thick, raised_p, extra; | 2295 | int x0, y0, x1, y1, thick, raised_p; |
| 2296 | int extra_x, extra_y; | ||
| 2258 | XRectangle r; | 2297 | XRectangle r; |
| 2259 | int x = s->x; | 2298 | int x = s->x; |
| 2260 | int y = s->ybase - image_ascent (s->img, s->face, &s->slice); | 2299 | int y = s->ybase - image_ascent (s->img, s->face, &s->slice); |
| @@ -2285,13 +2324,24 @@ x_draw_image_relief (struct glyph_string *s) | |||
| 2285 | raised_p = s->img->relief > 0; | 2324 | raised_p = s->img->relief > 0; |
| 2286 | } | 2325 | } |
| 2287 | 2326 | ||
| 2288 | extra = s->face->id == TOOL_BAR_FACE_ID | 2327 | extra_x = extra_y = 0; |
| 2289 | ? XINT (Vtool_bar_button_margin) : 0; | 2328 | if (s->face->id == TOOL_BAR_FACE_ID) |
| 2329 | { | ||
| 2330 | if (CONSP (Vtool_bar_button_margin) | ||
| 2331 | && INTEGERP (XCAR (Vtool_bar_button_margin)) | ||
| 2332 | && INTEGERP (XCDR (Vtool_bar_button_margin))) | ||
| 2333 | { | ||
| 2334 | extra_x = XINT (XCAR (Vtool_bar_button_margin)); | ||
| 2335 | extra_y = XINT (XCDR (Vtool_bar_button_margin)); | ||
| 2336 | } | ||
| 2337 | else if (INTEGERP (Vtool_bar_button_margin)) | ||
| 2338 | extra_x = extra_y = XINT (Vtool_bar_button_margin); | ||
| 2339 | } | ||
| 2290 | 2340 | ||
| 2291 | x0 = x - thick - extra; | 2341 | x0 = x - thick - extra_x; |
| 2292 | y0 = y - thick - extra; | 2342 | y0 = y - thick - extra_y; |
| 2293 | x1 = x + s->slice.width + thick - 1 + extra; | 2343 | x1 = x + s->slice.width + thick - 1 + extra_x; |
| 2294 | y1 = y + s->slice.height + thick - 1 + extra; | 2344 | y1 = y + s->slice.height + thick - 1 + extra_y; |
| 2295 | 2345 | ||
| 2296 | x_setup_relief_colors (s); | 2346 | x_setup_relief_colors (s); |
| 2297 | get_glyph_string_clip_rect (s, &r); | 2347 | get_glyph_string_clip_rect (s, &r); |
| @@ -2925,9 +2975,7 @@ x_clear_frame (struct frame *f) | |||
| 2925 | follow an explicit cursor_to. */ | 2975 | follow an explicit cursor_to. */ |
| 2926 | BLOCK_INPUT; | 2976 | BLOCK_INPUT; |
| 2927 | 2977 | ||
| 2928 | /* The following call is commented out because it does not seem to accomplish | 2978 | XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| 2929 | anything, apart from causing flickering during window resize. */ | ||
| 2930 | /* XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); */ | ||
| 2931 | 2979 | ||
| 2932 | /* We have to clear the scroll bars. If we have changed colors or | 2980 | /* We have to clear the scroll bars. If we have changed colors or |
| 2933 | something like that, then they should be notified. */ | 2981 | something like that, then they should be notified. */ |
| @@ -3281,7 +3329,7 @@ x_scroll_run (struct window *w, struct run *run) | |||
| 3281 | } | 3329 | } |
| 3282 | else | 3330 | else |
| 3283 | { | 3331 | { |
| 3284 | /* Scolling down. Make sure we don't copy over the mode line. | 3332 | /* Scrolling down. Make sure we don't copy over the mode line. |
| 3285 | at the bottom. */ | 3333 | at the bottom. */ |
| 3286 | if (to_y + run->height > bottom_y) | 3334 | if (to_y + run->height > bottom_y) |
| 3287 | height = bottom_y - to_y; | 3335 | height = bottom_y - to_y; |
| @@ -3320,8 +3368,14 @@ frame_highlight (struct frame *f) | |||
| 3320 | and border pixel are window attributes which are "private to the | 3368 | and border pixel are window attributes which are "private to the |
| 3321 | client", so we can always change it to whatever we want. */ | 3369 | client", so we can always change it to whatever we want. */ |
| 3322 | BLOCK_INPUT; | 3370 | BLOCK_INPUT; |
| 3371 | /* I recently started to get errors in this XSetWindowBorder, depending on | ||
| 3372 | the window-manager in use, tho something more is at play since I've been | ||
| 3373 | using that same window-manager binary for ever. Let's not crash just | ||
| 3374 | because of this (bug#9310). */ | ||
| 3375 | x_catch_errors (FRAME_X_DISPLAY (f)); | ||
| 3323 | XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3376 | XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 3324 | f->output_data.x->border_pixel); | 3377 | f->output_data.x->border_pixel); |
| 3378 | x_uncatch_errors (); | ||
| 3325 | UNBLOCK_INPUT; | 3379 | UNBLOCK_INPUT; |
| 3326 | x_update_cursor (f, 1); | 3380 | x_update_cursor (f, 1); |
| 3327 | x_set_frame_alpha (f); | 3381 | x_set_frame_alpha (f); |
| @@ -3335,8 +3389,11 @@ frame_unhighlight (struct frame *f) | |||
| 3335 | and border pixel are window attributes which are "private to the | 3389 | and border pixel are window attributes which are "private to the |
| 3336 | client", so we can always change it to whatever we want. */ | 3390 | client", so we can always change it to whatever we want. */ |
| 3337 | BLOCK_INPUT; | 3391 | BLOCK_INPUT; |
| 3392 | /* Same as above for XSetWindowBorder (bug#9310). */ | ||
| 3393 | x_catch_errors (FRAME_X_DISPLAY (f)); | ||
| 3338 | XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3394 | XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 3339 | f->output_data.x->border_tile); | 3395 | f->output_data.x->border_tile); |
| 3396 | x_uncatch_errors (); | ||
| 3340 | UNBLOCK_INPUT; | 3397 | UNBLOCK_INPUT; |
| 3341 | x_update_cursor (f, 1); | 3398 | x_update_cursor (f, 1); |
| 3342 | x_set_frame_alpha (f); | 3399 | x_set_frame_alpha (f); |
| @@ -4137,7 +4194,7 @@ static Boolean xaw3d_arrow_scroll; | |||
| 4137 | 4194 | ||
| 4138 | /* Whether the drag scrolling maintains the mouse at the top of the | 4195 | /* Whether the drag scrolling maintains the mouse at the top of the |
| 4139 | thumb. If not, resizing the thumb needs to be done more carefully | 4196 | thumb. If not, resizing the thumb needs to be done more carefully |
| 4140 | to avoid jerkyness. */ | 4197 | to avoid jerkiness. */ |
| 4141 | 4198 | ||
| 4142 | static Boolean xaw3d_pick_top; | 4199 | static Boolean xaw3d_pick_top; |
| 4143 | 4200 | ||
| @@ -4190,7 +4247,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, | |||
| 4190 | x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ | 4247 | x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ |
| 4191 | 4248 | ||
| 4192 | static struct window **scroll_bar_windows; | 4249 | static struct window **scroll_bar_windows; |
| 4193 | static size_t scroll_bar_windows_size; | 4250 | static ptrdiff_t scroll_bar_windows_size; |
| 4194 | 4251 | ||
| 4195 | 4252 | ||
| 4196 | /* Send a client message with message type Xatom_Scrollbar for a | 4253 | /* Send a client message with message type Xatom_Scrollbar for a |
| @@ -4205,7 +4262,7 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) | |||
| 4205 | XClientMessageEvent *ev = (XClientMessageEvent *) &event; | 4262 | XClientMessageEvent *ev = (XClientMessageEvent *) &event; |
| 4206 | struct window *w = XWINDOW (window); | 4263 | struct window *w = XWINDOW (window); |
| 4207 | struct frame *f = XFRAME (w->frame); | 4264 | struct frame *f = XFRAME (w->frame); |
| 4208 | size_t i; | 4265 | ptrdiff_t i; |
| 4209 | 4266 | ||
| 4210 | BLOCK_INPUT; | 4267 | BLOCK_INPUT; |
| 4211 | 4268 | ||
| @@ -4226,16 +4283,15 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) | |||
| 4226 | 4283 | ||
| 4227 | if (i == scroll_bar_windows_size) | 4284 | if (i == scroll_bar_windows_size) |
| 4228 | { | 4285 | { |
| 4229 | size_t new_size = max (10, 2 * scroll_bar_windows_size); | 4286 | ptrdiff_t old_nbytes = |
| 4230 | size_t nbytes = new_size * sizeof *scroll_bar_windows; | 4287 | scroll_bar_windows_size * sizeof *scroll_bar_windows; |
| 4231 | size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; | 4288 | ptrdiff_t nbytes; |
| 4232 | 4289 | enum { XClientMessageEvent_MAX = 0x7fffffff }; | |
| 4233 | if ((size_t) -1 / sizeof *scroll_bar_windows < new_size) | 4290 | scroll_bar_windows = |
| 4234 | memory_full (SIZE_MAX); | 4291 | xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1, |
| 4235 | scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, | 4292 | XClientMessageEvent_MAX, sizeof *scroll_bar_windows); |
| 4236 | nbytes); | 4293 | nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; |
| 4237 | memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); | 4294 | memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); |
| 4238 | scroll_bar_windows_size = new_size; | ||
| 4239 | } | 4295 | } |
| 4240 | 4296 | ||
| 4241 | scroll_bar_windows[i] = w; | 4297 | scroll_bar_windows[i] = w; |
| @@ -5107,7 +5163,7 @@ x_scroll_bar_remove (struct scroll_bar *bar) | |||
| 5107 | XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window); | 5163 | XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window); |
| 5108 | #endif | 5164 | #endif |
| 5109 | 5165 | ||
| 5110 | /* Disassociate this scroll bar from its window. */ | 5166 | /* Dissociate this scroll bar from its window. */ |
| 5111 | XWINDOW (bar->window)->vertical_scroll_bar = Qnil; | 5167 | XWINDOW (bar->window)->vertical_scroll_bar = Qnil; |
| 5112 | 5168 | ||
| 5113 | UNBLOCK_INPUT; | 5169 | UNBLOCK_INPUT; |
| @@ -5813,11 +5869,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 5813 | } inev; | 5869 | } inev; |
| 5814 | int count = 0; | 5870 | int count = 0; |
| 5815 | int do_help = 0; | 5871 | int do_help = 0; |
| 5816 | int nbytes = 0; | 5872 | ptrdiff_t nbytes = 0; |
| 5817 | struct frame *f = NULL; | 5873 | struct frame *f = NULL; |
| 5818 | struct coding_system coding; | 5874 | struct coding_system coding; |
| 5819 | XEvent event = *eventptr; | 5875 | XEvent event = *eventptr; |
| 5820 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; | 5876 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; |
| 5877 | USE_SAFE_ALLOCA; | ||
| 5821 | 5878 | ||
| 5822 | *finish = X_EVENT_NORMAL; | 5879 | *finish = X_EVENT_NORMAL; |
| 5823 | 5880 | ||
| @@ -6069,7 +6126,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6069 | last_user_time = event.xproperty.time; | 6126 | last_user_time = event.xproperty.time; |
| 6070 | f = x_top_window_to_frame (dpyinfo, event.xproperty.window); | 6127 | f = x_top_window_to_frame (dpyinfo, event.xproperty.window); |
| 6071 | if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state) | 6128 | if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state) |
| 6072 | x_handle_net_wm_state (f, &event.xproperty); | 6129 | if (x_handle_net_wm_state (f, &event.xproperty) && f->iconified |
| 6130 | && f->output_data.x->net_wm_state_hidden_seen) | ||
| 6131 | { | ||
| 6132 | /* Gnome shell does not iconify us when C-z is pressed. It hides | ||
| 6133 | the frame. So if our state says we aren't hidden anymore, | ||
| 6134 | treat it as deiconified. */ | ||
| 6135 | if (! f->async_iconified) | ||
| 6136 | SET_FRAME_GARBAGED (f); | ||
| 6137 | f->async_visible = 1; | ||
| 6138 | f->async_iconified = 0; | ||
| 6139 | f->output_data.x->has_been_visible = 1; | ||
| 6140 | f->output_data.x->net_wm_state_hidden_seen = 0; | ||
| 6141 | inev.ie.kind = DEICONIFY_EVENT; | ||
| 6142 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 6143 | } | ||
| 6073 | 6144 | ||
| 6074 | x_handle_property_notify (&event.xproperty); | 6145 | x_handle_property_notify (&event.xproperty); |
| 6075 | xft_settings_event (dpyinfo, &event); | 6146 | xft_settings_event (dpyinfo, &event); |
| @@ -6088,6 +6159,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6088 | /* Perhaps reparented due to a WM restart. Reset this. */ | 6159 | /* Perhaps reparented due to a WM restart. Reset this. */ |
| 6089 | FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; | 6160 | FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; |
| 6090 | FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0; | 6161 | FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0; |
| 6162 | |||
| 6163 | x_set_frame_alpha (f); | ||
| 6091 | } | 6164 | } |
| 6092 | goto OTHER; | 6165 | goto OTHER; |
| 6093 | 6166 | ||
| @@ -6511,7 +6584,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6511 | } | 6584 | } |
| 6512 | 6585 | ||
| 6513 | { /* Raw bytes, not keysym. */ | 6586 | { /* Raw bytes, not keysym. */ |
| 6514 | register int i; | 6587 | ptrdiff_t i; |
| 6515 | int nchars, len; | 6588 | int nchars, len; |
| 6516 | 6589 | ||
| 6517 | for (i = 0, nchars = 0; i < nbytes; i++) | 6590 | for (i = 0, nchars = 0; i < nbytes; i++) |
| @@ -6524,7 +6597,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6524 | if (nchars < nbytes) | 6597 | if (nchars < nbytes) |
| 6525 | { | 6598 | { |
| 6526 | /* Decode the input data. */ | 6599 | /* Decode the input data. */ |
| 6527 | int require; | ||
| 6528 | 6600 | ||
| 6529 | /* The input should be decoded with `coding_system' | 6601 | /* The input should be decoded with `coding_system' |
| 6530 | which depends on which X*LookupString function | 6602 | which depends on which X*LookupString function |
| @@ -6537,9 +6609,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6537 | gives us composition information. */ | 6609 | gives us composition information. */ |
| 6538 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | 6610 | coding.common_flags &= ~CODING_ANNOTATION_MASK; |
| 6539 | 6611 | ||
| 6540 | require = MAX_MULTIBYTE_LENGTH * nbytes; | 6612 | SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, |
| 6541 | coding.destination = alloca (require); | 6613 | nbytes); |
| 6542 | coding.dst_bytes = require; | 6614 | coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes; |
| 6543 | coding.mode |= CODING_MODE_LAST_BLOCK; | 6615 | coding.mode |= CODING_MODE_LAST_BLOCK; |
| 6544 | decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil); | 6616 | decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil); |
| 6545 | nbytes = coding.produced; | 6617 | nbytes = coding.produced; |
| @@ -6998,6 +7070,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6998 | count++; | 7070 | count++; |
| 6999 | } | 7071 | } |
| 7000 | 7072 | ||
| 7073 | SAFE_FREE (); | ||
| 7001 | *eventptr = event; | 7074 | *eventptr = event; |
| 7002 | return count; | 7075 | return count; |
| 7003 | } | 7076 | } |
| @@ -7651,14 +7724,6 @@ x_fully_uncatch_errors (void) | |||
| 7651 | } | 7724 | } |
| 7652 | #endif | 7725 | #endif |
| 7653 | 7726 | ||
| 7654 | /* Nonzero if x_catch_errors has been done and not yet canceled. */ | ||
| 7655 | |||
| 7656 | int | ||
| 7657 | x_catching_errors (void) | ||
| 7658 | { | ||
| 7659 | return x_error_message != 0; | ||
| 7660 | } | ||
| 7661 | |||
| 7662 | #if 0 | 7727 | #if 0 |
| 7663 | static unsigned int x_wire_count; | 7728 | static unsigned int x_wire_count; |
| 7664 | x_trace_wire (void) | 7729 | x_trace_wire (void) |
| @@ -7819,6 +7884,15 @@ static void x_error_quitter (Display *, XErrorEvent *); | |||
| 7819 | static int | 7884 | static int |
| 7820 | x_error_handler (Display *display, XErrorEvent *event) | 7885 | x_error_handler (Display *display, XErrorEvent *event) |
| 7821 | { | 7886 | { |
| 7887 | #ifdef HAVE_GTK3 | ||
| 7888 | if (event->error_code == BadMatch | ||
| 7889 | && event->request_code == X_SetInputFocus | ||
| 7890 | && event->minor_code == 0) | ||
| 7891 | { | ||
| 7892 | return 0; | ||
| 7893 | } | ||
| 7894 | #endif | ||
| 7895 | |||
| 7822 | if (x_error_message) | 7896 | if (x_error_message) |
| 7823 | x_error_catcher (display, event); | 7897 | x_error_catcher (display, event); |
| 7824 | else | 7898 | else |
| @@ -7865,7 +7939,8 @@ x_io_error_quitter (Display *display) | |||
| 7865 | { | 7939 | { |
| 7866 | char buf[256]; | 7940 | char buf[256]; |
| 7867 | 7941 | ||
| 7868 | sprintf (buf, "Connection lost to X server `%s'", DisplayString (display)); | 7942 | snprintf (buf, sizeof buf, "Connection lost to X server `%s'", |
| 7943 | DisplayString (display)); | ||
| 7869 | x_connection_closed (display, buf); | 7944 | x_connection_closed (display, buf); |
| 7870 | return 0; | 7945 | return 0; |
| 7871 | } | 7946 | } |
| @@ -8376,9 +8451,11 @@ x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | |||
| 8376 | 8451 | ||
| 8377 | /* Return the current _NET_WM_STATE. | 8452 | /* Return the current _NET_WM_STATE. |
| 8378 | SIZE_STATE is set to one of the FULLSCREEN_* values. | 8453 | SIZE_STATE is set to one of the FULLSCREEN_* values. |
| 8379 | STICKY is set to 1 if the sticky state is set, 0 if not. */ | 8454 | STICKY is set to 1 if the sticky state is set, 0 if not. |
| 8380 | 8455 | ||
| 8381 | static void | 8456 | Return non-zero if we are not hidden, zero if we are. */ |
| 8457 | |||
| 8458 | static int | ||
| 8382 | get_current_wm_state (struct frame *f, | 8459 | get_current_wm_state (struct frame *f, |
| 8383 | Window window, | 8460 | Window window, |
| 8384 | int *size_state, | 8461 | int *size_state, |
| @@ -8386,7 +8463,7 @@ get_current_wm_state (struct frame *f, | |||
| 8386 | { | 8463 | { |
| 8387 | Atom actual_type; | 8464 | Atom actual_type; |
| 8388 | unsigned long actual_size, bytes_remaining; | 8465 | unsigned long actual_size, bytes_remaining; |
| 8389 | int i, rc, actual_format; | 8466 | int i, rc, actual_format, is_hidden = 0; |
| 8390 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 8467 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); |
| 8391 | long max_len = 65536; | 8468 | long max_len = 65536; |
| 8392 | Display *dpy = FRAME_X_DISPLAY (f); | 8469 | Display *dpy = FRAME_X_DISPLAY (f); |
| @@ -8408,7 +8485,7 @@ get_current_wm_state (struct frame *f, | |||
| 8408 | if (tmp_data) XFree (tmp_data); | 8485 | if (tmp_data) XFree (tmp_data); |
| 8409 | x_uncatch_errors (); | 8486 | x_uncatch_errors (); |
| 8410 | UNBLOCK_INPUT; | 8487 | UNBLOCK_INPUT; |
| 8411 | return; | 8488 | return ! f->iconified; |
| 8412 | } | 8489 | } |
| 8413 | 8490 | ||
| 8414 | x_uncatch_errors (); | 8491 | x_uncatch_errors (); |
| @@ -8416,7 +8493,12 @@ get_current_wm_state (struct frame *f, | |||
| 8416 | for (i = 0; i < actual_size; ++i) | 8493 | for (i = 0; i < actual_size; ++i) |
| 8417 | { | 8494 | { |
| 8418 | Atom a = ((Atom*)tmp_data)[i]; | 8495 | Atom a = ((Atom*)tmp_data)[i]; |
| 8419 | if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) | 8496 | if (a == dpyinfo->Xatom_net_wm_state_hidden) |
| 8497 | { | ||
| 8498 | is_hidden = 1; | ||
| 8499 | f->output_data.x->net_wm_state_hidden_seen = 1; | ||
| 8500 | } | ||
| 8501 | else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) | ||
| 8420 | { | 8502 | { |
| 8421 | if (*size_state == FULLSCREEN_HEIGHT) | 8503 | if (*size_state == FULLSCREEN_HEIGHT) |
| 8422 | *size_state = FULLSCREEN_MAXIMIZED; | 8504 | *size_state = FULLSCREEN_MAXIMIZED; |
| @@ -8438,6 +8520,7 @@ get_current_wm_state (struct frame *f, | |||
| 8438 | 8520 | ||
| 8439 | if (tmp_data) XFree (tmp_data); | 8521 | if (tmp_data) XFree (tmp_data); |
| 8440 | UNBLOCK_INPUT; | 8522 | UNBLOCK_INPUT; |
| 8523 | return ! is_hidden; | ||
| 8441 | } | 8524 | } |
| 8442 | 8525 | ||
| 8443 | /* Do fullscreen as specified in extended window manager hints */ | 8526 | /* Do fullscreen as specified in extended window manager hints */ |
| @@ -8449,7 +8532,7 @@ do_ewmh_fullscreen (struct frame *f) | |||
| 8449 | int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state); | 8532 | int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state); |
| 8450 | int cur, dummy; | 8533 | int cur, dummy; |
| 8451 | 8534 | ||
| 8452 | get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy); | 8535 | (void)get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy); |
| 8453 | 8536 | ||
| 8454 | /* Some window managers don't say they support _NET_WM_STATE, but they do say | 8537 | /* Some window managers don't say they support _NET_WM_STATE, but they do say |
| 8455 | they support _NET_WM_STATE_FULLSCREEN. Try that also. */ | 8538 | they support _NET_WM_STATE_FULLSCREEN. Try that also. */ |
| @@ -8524,14 +8607,14 @@ XTfullscreen_hook (FRAME_PTR f) | |||
| 8524 | } | 8607 | } |
| 8525 | 8608 | ||
| 8526 | 8609 | ||
| 8527 | static void | 8610 | static int |
| 8528 | x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) | 8611 | x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) |
| 8529 | { | 8612 | { |
| 8530 | int value = FULLSCREEN_NONE; | 8613 | int value = FULLSCREEN_NONE; |
| 8531 | Lisp_Object lval; | 8614 | Lisp_Object lval; |
| 8532 | int sticky = 0; | 8615 | int sticky = 0; |
| 8616 | int not_hidden = get_current_wm_state (f, event->window, &value, &sticky); | ||
| 8533 | 8617 | ||
| 8534 | get_current_wm_state (f, event->window, &value, &sticky); | ||
| 8535 | lval = Qnil; | 8618 | lval = Qnil; |
| 8536 | switch (value) | 8619 | switch (value) |
| 8537 | { | 8620 | { |
| @@ -8551,6 +8634,8 @@ x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) | |||
| 8551 | 8634 | ||
| 8552 | store_frame_param (f, Qfullscreen, lval); | 8635 | store_frame_param (f, Qfullscreen, lval); |
| 8553 | store_frame_param (f, Qsticky, sticky ? Qt : Qnil); | 8636 | store_frame_param (f, Qsticky, sticky ? Qt : Qnil); |
| 8637 | |||
| 8638 | return not_hidden; | ||
| 8554 | } | 8639 | } |
| 8555 | 8640 | ||
| 8556 | /* Check if we need to resize the frame due to a fullscreen request. | 8641 | /* Check if we need to resize the frame due to a fullscreen request. |
| @@ -8695,7 +8780,7 @@ x_wait_for_event (struct frame *f, int eventtype) | |||
| 8695 | pending_event_wait.f = f; | 8780 | pending_event_wait.f = f; |
| 8696 | pending_event_wait.eventtype = eventtype; | 8781 | pending_event_wait.eventtype = eventtype; |
| 8697 | 8782 | ||
| 8698 | /* Set timeout to 0.1 second. Hopefully not noticable. | 8783 | /* Set timeout to 0.1 second. Hopefully not noticeable. |
| 8699 | Maybe it should be configurable. */ | 8784 | Maybe it should be configurable. */ |
| 8700 | EMACS_SET_SECS_USECS (tmo, 0, 100000); | 8785 | EMACS_SET_SECS_USECS (tmo, 0, 100000); |
| 8701 | EMACS_GET_TIME (tmo_at); | 8786 | EMACS_GET_TIME (tmo_at); |
| @@ -8908,6 +8993,18 @@ x_lower_frame (struct frame *f) | |||
| 8908 | } | 8993 | } |
| 8909 | } | 8994 | } |
| 8910 | 8995 | ||
| 8996 | /* Request focus with XEmbed */ | ||
| 8997 | |||
| 8998 | void | ||
| 8999 | xembed_request_focus (FRAME_PTR f) | ||
| 9000 | { | ||
| 9001 | /* See XEmbed Protocol Specification at | ||
| 9002 | http://freedesktop.org/wiki/Specifications/xembed-spec */ | ||
| 9003 | if (f->async_visible) | ||
| 9004 | xembed_send_message (f, CurrentTime, | ||
| 9005 | XEMBED_REQUEST_FOCUS, 0, 0, 0); | ||
| 9006 | } | ||
| 9007 | |||
| 8911 | /* Activate frame with Extended Window Manager Hints */ | 9008 | /* Activate frame with Extended Window Manager Hints */ |
| 8912 | 9009 | ||
| 8913 | void | 9010 | void |
| @@ -9234,7 +9331,7 @@ x_iconify_frame (struct frame *f) | |||
| 9234 | if (!NILP (type)) | 9331 | if (!NILP (type)) |
| 9235 | x_bitmap_icon (f, type); | 9332 | x_bitmap_icon (f, type); |
| 9236 | 9333 | ||
| 9237 | #ifdef USE_GTK | 9334 | #if defined (USE_GTK) |
| 9238 | if (FRAME_GTK_OUTER_WIDGET (f)) | 9335 | if (FRAME_GTK_OUTER_WIDGET (f)) |
| 9239 | { | 9336 | { |
| 9240 | if (! FRAME_VISIBLE_P (f)) | 9337 | if (! FRAME_VISIBLE_P (f)) |
| @@ -9488,6 +9585,14 @@ x_wm_set_size_hint (struct frame *f, long flags, int user_position) | |||
| 9488 | XSizeHints size_hints; | 9585 | XSizeHints size_hints; |
| 9489 | Window window = FRAME_OUTER_WINDOW (f); | 9586 | Window window = FRAME_OUTER_WINDOW (f); |
| 9490 | 9587 | ||
| 9588 | #ifdef USE_X_TOOLKIT | ||
| 9589 | if (f->output_data.x->widget) | ||
| 9590 | { | ||
| 9591 | widget_update_wm_size_hints (f->output_data.x->widget); | ||
| 9592 | return; | ||
| 9593 | } | ||
| 9594 | #endif | ||
| 9595 | |||
| 9491 | /* Setting PMaxSize caused various problems. */ | 9596 | /* Setting PMaxSize caused various problems. */ |
| 9492 | size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; | 9597 | size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; |
| 9493 | 9598 | ||
| @@ -9822,6 +9927,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 9822 | struct x_display_info *dpyinfo; | 9927 | struct x_display_info *dpyinfo; |
| 9823 | XrmDatabase xrdb; | 9928 | XrmDatabase xrdb; |
| 9824 | Mouse_HLInfo *hlinfo; | 9929 | Mouse_HLInfo *hlinfo; |
| 9930 | ptrdiff_t lim; | ||
| 9825 | 9931 | ||
| 9826 | BLOCK_INPUT; | 9932 | BLOCK_INPUT; |
| 9827 | 9933 | ||
| @@ -9879,6 +9985,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 9879 | https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ | 9985 | https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ |
| 9880 | id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | 9986 | id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL |
| 9881 | | G_LOG_FLAG_RECURSION, my_log_handler, NULL); | 9987 | | G_LOG_FLAG_RECURSION, my_log_handler, NULL); |
| 9988 | |||
| 9989 | /* NULL window -> events for all windows go to our function. | ||
| 9990 | Call before gtk_init so Gtk+ event filters comes after our. */ | ||
| 9991 | gdk_window_add_filter (NULL, event_handler_gdk, NULL); | ||
| 9992 | |||
| 9882 | gtk_init (&argc, &argv2); | 9993 | gtk_init (&argc, &argv2); |
| 9883 | g_log_remove_handler ("GLib", id); | 9994 | g_log_remove_handler ("GLib", id); |
| 9884 | 9995 | ||
| @@ -9888,9 +9999,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 9888 | 9999 | ||
| 9889 | dpy = DEFAULT_GDK_DISPLAY (); | 10000 | dpy = DEFAULT_GDK_DISPLAY (); |
| 9890 | 10001 | ||
| 9891 | /* NULL window -> events for all windows go to our function */ | ||
| 9892 | gdk_window_add_filter (NULL, event_handler_gdk, NULL); | ||
| 9893 | |||
| 9894 | #if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90 | 10002 | #if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90 |
| 9895 | /* Load our own gtkrc if it exists. */ | 10003 | /* Load our own gtkrc if it exists. */ |
| 9896 | { | 10004 | { |
| @@ -10040,12 +10148,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10040 | XSetAfterFunction (x_current_display, x_trace_wire); | 10148 | XSetAfterFunction (x_current_display, x_trace_wire); |
| 10041 | #endif /* ! 0 */ | 10149 | #endif /* ! 0 */ |
| 10042 | 10150 | ||
| 10151 | lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@"; | ||
| 10152 | if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name)) | ||
| 10153 | memory_full (SIZE_MAX); | ||
| 10043 | dpyinfo->x_id_name | 10154 | dpyinfo->x_id_name |
| 10044 | = (char *) xmalloc (SBYTES (Vinvocation_name) | 10155 | = (char *) xmalloc (SBYTES (Vinvocation_name) |
| 10045 | + SBYTES (Vsystem_name) | 10156 | + SBYTES (Vsystem_name) |
| 10046 | + 2); | 10157 | + 2); |
| 10047 | sprintf (dpyinfo->x_id_name, "%s@%s", | 10158 | strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), |
| 10048 | SSDATA (Vinvocation_name), SSDATA (Vsystem_name)); | 10159 | SSDATA (Vsystem_name)); |
| 10049 | 10160 | ||
| 10050 | /* Figure out which modifier bits mean what. */ | 10161 | /* Figure out which modifier bits mean what. */ |
| 10051 | x_find_modifier_meanings (dpyinfo); | 10162 | x_find_modifier_meanings (dpyinfo); |
| @@ -10210,6 +10321,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10210 | { "_NET_WM_STATE_MAXIMIZED_VERT", | 10321 | { "_NET_WM_STATE_MAXIMIZED_VERT", |
| 10211 | &dpyinfo->Xatom_net_wm_state_maximized_vert }, | 10322 | &dpyinfo->Xatom_net_wm_state_maximized_vert }, |
| 10212 | { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky }, | 10323 | { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky }, |
| 10324 | { "_NET_WM_STATE_HIDDEN", &dpyinfo->Xatom_net_wm_state_hidden }, | ||
| 10213 | { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type }, | 10325 | { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type }, |
| 10214 | { "_NET_WM_WINDOW_TYPE_TOOLTIP", | 10326 | { "_NET_WM_WINDOW_TYPE_TOOLTIP", |
| 10215 | &dpyinfo->Xatom_net_window_type_tooltip }, | 10327 | &dpyinfo->Xatom_net_window_type_tooltip }, |
| @@ -10744,7 +10856,7 @@ selected window or cursor position is preserved. */); | |||
| 10744 | A value of nil means Emacs doesn't use toolkit scroll bars. | 10856 | A value of nil means Emacs doesn't use toolkit scroll bars. |
| 10745 | With the X Window system, the value is a symbol describing the | 10857 | With the X Window system, the value is a symbol describing the |
| 10746 | X toolkit. Possible values are: gtk, motif, xaw, or xaw3d. | 10858 | X toolkit. Possible values are: gtk, motif, xaw, or xaw3d. |
| 10747 | With MS Windows, the value is t. */); | 10859 | With MS Windows or Nextstep, the value is t. */); |
| 10748 | #ifdef USE_TOOLKIT_SCROLL_BARS | 10860 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 10749 | #ifdef USE_MOTIF | 10861 | #ifdef USE_MOTIF |
| 10750 | Vx_toolkit_scroll_bars = intern_c_string ("motif"); | 10862 | Vx_toolkit_scroll_bars = intern_c_string ("motif"); |