aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-09-02 17:19:29 +0800
committerPo Lu2022-09-02 17:19:51 +0800
commit2ff57638365411904e76979ef628534098ce3549 (patch)
tree4bc7295290f1dbac1f775da5856723abfa08e064 /src
parent0ec831b91cde2a0e1b65f99c1190975c6e6959f9 (diff)
downloademacs-2ff57638365411904e76979ef628534098ce3549.tar.gz
emacs-2ff57638365411904e76979ef628534098ce3549.zip
Prevent crashes when embedding Emacs in a nonexistent parent
* src/xfns.c (x_window, Fx_create_frame): Handle X errors while trying to reparent the frame onto an explicitly specified parent. * src/xterm.c (handle_one_xevent): Handle unparenting embedded windows correctly. This only works if the embedder is aware of the fixes extension and has put the window into the right save set. (x_embed_frame): New function. * src/xterm.h (FRAME_X_EMBEDDED_P): Fix coding style.
Diffstat (limited to 'src')
-rw-r--r--src/xfns.c12
-rw-r--r--src/xterm.c39
-rw-r--r--src/xterm.h4
3 files changed, 48 insertions, 7 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 0b1f707e9fc..2da1e7bcf80 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3955,10 +3955,6 @@ x_window (struct frame *f, long window_prompting)
3955 XtManageChild (pane_widget); 3955 XtManageChild (pane_widget);
3956 XtRealizeWidget (shell_widget); 3956 XtRealizeWidget (shell_widget);
3957 3957
3958 if (FRAME_X_EMBEDDED_P (f))
3959 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
3960 f->output_data.x->parent_desc, 0, 0);
3961
3962 FRAME_X_WINDOW (f) = XtWindow (frame_widget); 3958 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
3963 initial_set_up_x_back_buffer (f); 3959 initial_set_up_x_back_buffer (f);
3964 validate_x_resource_name (); 3960 validate_x_resource_name ();
@@ -4132,7 +4128,7 @@ x_window (struct frame *f)
4132 block_input (); 4128 block_input ();
4133 FRAME_X_WINDOW (f) 4129 FRAME_X_WINDOW (f)
4134 = XCreateWindow (FRAME_X_DISPLAY (f), 4130 = XCreateWindow (FRAME_X_DISPLAY (f),
4135 f->output_data.x->parent_desc, 4131 FRAME_DISPLAY_INFO (f)->root_window,
4136 f->left_pos, 4132 f->left_pos,
4137 f->top_pos, 4133 f->top_pos,
4138 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), 4134 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
@@ -4958,6 +4954,12 @@ This function is an internal primitive--use `make-frame' instead. */)
4958 x_window (f); 4954 x_window (f);
4959#endif 4955#endif
4960 4956
4957#ifndef USE_GTK
4958 if (FRAME_X_EMBEDDED_P (f)
4959 && !x_embed_frame (dpyinfo, f))
4960 error ("The frame could not be embedded; does the embedder exist?");
4961#endif
4962
4961 x_icon (f, parms); 4963 x_icon (f, parms);
4962 x_make_gc (f); 4964 x_make_gc (f);
4963 4965
diff --git a/src/xterm.c b/src/xterm.c
index 71b84f81747..138fa7ea6c8 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -18416,6 +18416,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
18416 f = x_top_window_to_frame (dpyinfo, event->xreparent.window); 18416 f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
18417 if (f) 18417 if (f)
18418 { 18418 {
18419#ifndef USE_GTK
18420 if (FRAME_OUTPUT_DATA (f)->parent_desc
18421 && FRAME_X_EMBEDDED_P (f))
18422 {
18423 /* The frame's embedder was destroyed; mark the frame as
18424 no longer embedded, and map the frame. An
18425 UnmapNotify event must have previously been received
18426 during the start of save-set processing. */
18427
18428 FRAME_X_OUTPUT (f)->explicit_parent = false;
18429 x_make_frame_visible (f);
18430 }
18431#endif
18432
18419 /* Maybe we shouldn't set this for child frames ?? */ 18433 /* Maybe we shouldn't set this for child frames ?? */
18420 f->output_data.x->parent_desc = event->xreparent.parent; 18434 f->output_data.x->parent_desc = event->xreparent.parent;
18421 18435
@@ -27456,6 +27470,31 @@ x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
27456 return value; 27470 return value;
27457} 27471}
27458 27472
27473#ifndef USE_GTK
27474
27475/* Set up XEmbed for F, and change its save set to handle the parent
27476 being destroyed. */
27477
27478bool
27479x_embed_frame (struct x_display_info *dpyinfo, struct frame *f)
27480{
27481 bool rc;
27482
27483 x_catch_errors (dpyinfo->display);
27484 /* Catch errors; the target window might no longer exist. */
27485 XReparentWindow (dpyinfo->display, FRAME_OUTER_WINDOW (f),
27486 FRAME_OUTPUT_DATA (f)->parent_desc, 0, 0);
27487 rc = x_had_errors_p (dpyinfo->display);
27488 x_uncatch_errors_after_check ();
27489
27490 if (rc)
27491 return false;
27492
27493 return true;
27494}
27495
27496#endif
27497
27459 27498
27460/* Setting window manager hints. */ 27499/* Setting window manager hints. */
27461 27500
diff --git a/src/xterm.h b/src/xterm.h
index a0ae3a330a9..7c5a889af30 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1209,7 +1209,6 @@ enum
1209 FOCUS_EXPLICIT = 2 1209 FOCUS_EXPLICIT = 2
1210}; 1210};
1211 1211
1212
1213/* Return the X output data for frame F. */ 1212/* Return the X output data for frame F. */
1214#define FRAME_X_OUTPUT(f) ((f)->output_data.x) 1213#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
1215#define FRAME_OUTPUT_DATA(f) FRAME_X_OUTPUT (f) 1214#define FRAME_OUTPUT_DATA(f) FRAME_X_OUTPUT (f)
@@ -1588,6 +1587,7 @@ extern void x_wm_set_size_hint (struct frame *, long, bool);
1588 && defined HAVE_CLOCK_GETTIME 1587 && defined HAVE_CLOCK_GETTIME
1589extern void x_sync_init_fences (struct frame *); 1588extern void x_sync_init_fences (struct frame *);
1590#endif 1589#endif
1590extern bool x_embed_frame (struct x_display_info *, struct frame *);
1591 1591
1592extern void x_delete_terminal (struct terminal *); 1592extern void x_delete_terminal (struct terminal *);
1593extern Cursor x_create_font_cursor (struct x_display_info *, int); 1593extern Cursor x_create_font_cursor (struct x_display_info *, int);
@@ -1827,7 +1827,7 @@ extern void mark_xterm (void);
1827 1827
1828/* Is the frame embedded into another application? */ 1828/* Is the frame embedded into another application? */
1829 1829
1830#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0) 1830#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT (f)->explicit_parent != 0)
1831 1831
1832#define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \ 1832#define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \
1833 ((nr).x = (rx), \ 1833 ((nr).x = (rx), \