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.
This commit is contained in:
parent
0ec831b91c
commit
2ff5763836
3 changed files with 48 additions and 7 deletions
12
src/xfns.c
12
src/xfns.c
|
@ -3955,10 +3955,6 @@ x_window (struct frame *f, long window_prompting)
|
|||
XtManageChild (pane_widget);
|
||||
XtRealizeWidget (shell_widget);
|
||||
|
||||
if (FRAME_X_EMBEDDED_P (f))
|
||||
XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
|
||||
f->output_data.x->parent_desc, 0, 0);
|
||||
|
||||
FRAME_X_WINDOW (f) = XtWindow (frame_widget);
|
||||
initial_set_up_x_back_buffer (f);
|
||||
validate_x_resource_name ();
|
||||
|
@ -4132,7 +4128,7 @@ x_window (struct frame *f)
|
|||
block_input ();
|
||||
FRAME_X_WINDOW (f)
|
||||
= XCreateWindow (FRAME_X_DISPLAY (f),
|
||||
f->output_data.x->parent_desc,
|
||||
FRAME_DISPLAY_INFO (f)->root_window,
|
||||
f->left_pos,
|
||||
f->top_pos,
|
||||
FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
|
||||
|
@ -4958,6 +4954,12 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
x_window (f);
|
||||
#endif
|
||||
|
||||
#ifndef USE_GTK
|
||||
if (FRAME_X_EMBEDDED_P (f)
|
||||
&& !x_embed_frame (dpyinfo, f))
|
||||
error ("The frame could not be embedded; does the embedder exist?");
|
||||
#endif
|
||||
|
||||
x_icon (f, parms);
|
||||
x_make_gc (f);
|
||||
|
||||
|
|
39
src/xterm.c
39
src/xterm.c
|
@ -18416,6 +18416,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
|
||||
if (f)
|
||||
{
|
||||
#ifndef USE_GTK
|
||||
if (FRAME_OUTPUT_DATA (f)->parent_desc
|
||||
&& FRAME_X_EMBEDDED_P (f))
|
||||
{
|
||||
/* The frame's embedder was destroyed; mark the frame as
|
||||
no longer embedded, and map the frame. An
|
||||
UnmapNotify event must have previously been received
|
||||
during the start of save-set processing. */
|
||||
|
||||
FRAME_X_OUTPUT (f)->explicit_parent = false;
|
||||
x_make_frame_visible (f);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Maybe we shouldn't set this for child frames ?? */
|
||||
f->output_data.x->parent_desc = event->xreparent.parent;
|
||||
|
||||
|
@ -27456,6 +27470,31 @@ x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
|
|||
return value;
|
||||
}
|
||||
|
||||
#ifndef USE_GTK
|
||||
|
||||
/* Set up XEmbed for F, and change its save set to handle the parent
|
||||
being destroyed. */
|
||||
|
||||
bool
|
||||
x_embed_frame (struct x_display_info *dpyinfo, struct frame *f)
|
||||
{
|
||||
bool rc;
|
||||
|
||||
x_catch_errors (dpyinfo->display);
|
||||
/* Catch errors; the target window might no longer exist. */
|
||||
XReparentWindow (dpyinfo->display, FRAME_OUTER_WINDOW (f),
|
||||
FRAME_OUTPUT_DATA (f)->parent_desc, 0, 0);
|
||||
rc = x_had_errors_p (dpyinfo->display);
|
||||
x_uncatch_errors_after_check ();
|
||||
|
||||
if (rc)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Setting window manager hints. */
|
||||
|
||||
|
|
|
@ -1209,7 +1209,6 @@ enum
|
|||
FOCUS_EXPLICIT = 2
|
||||
};
|
||||
|
||||
|
||||
/* Return the X output data for frame F. */
|
||||
#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
|
||||
#define FRAME_OUTPUT_DATA(f) FRAME_X_OUTPUT (f)
|
||||
|
@ -1588,6 +1587,7 @@ extern void x_wm_set_size_hint (struct frame *, long, bool);
|
|||
&& defined HAVE_CLOCK_GETTIME
|
||||
extern void x_sync_init_fences (struct frame *);
|
||||
#endif
|
||||
extern bool x_embed_frame (struct x_display_info *, struct frame *);
|
||||
|
||||
extern void x_delete_terminal (struct terminal *);
|
||||
extern Cursor x_create_font_cursor (struct x_display_info *, int);
|
||||
|
@ -1827,7 +1827,7 @@ extern void mark_xterm (void);
|
|||
|
||||
/* Is the frame embedded into another application? */
|
||||
|
||||
#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)
|
||||
#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT (f)->explicit_parent != 0)
|
||||
|
||||
#define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \
|
||||
((nr).x = (rx), \
|
||||
|
|
Loading…
Add table
Reference in a new issue