[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 2ff5763836: Prevent crashes when embedding Emacs in a nonexistent
From: |
Po Lu |
Subject: |
master 2ff5763836: Prevent crashes when embedding Emacs in a nonexistent parent |
Date: |
Fri, 2 Sep 2022 05:20:03 -0400 (EDT) |
branch: master
commit 2ff57638365411904e76979ef628534098ce3549
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
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.
---
src/xfns.c | 12 +++++++-----
src/xterm.c | 39 +++++++++++++++++++++++++++++++++++++++
src/xterm.h | 4 ++--
3 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/src/xfns.c b/src/xfns.c
index 0b1f707e9f..2da1e7bcf8 100644
--- a/src/xfns.c
+++ b/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);
diff --git a/src/xterm.c b/src/xterm.c
index 71b84f8174..138fa7ea6c 100644
--- a/src/xterm.c
+++ b/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. */
diff --git a/src/xterm.h b/src/xterm.h
index a0ae3a330a..7c5a889af3 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -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), \
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 2ff5763836: Prevent crashes when embedding Emacs in a nonexistent parent,
Po Lu <=