summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2022-01-22 11:02:50 +0000
committerAlan Mackenzie <acm@muc.de>2022-01-22 11:02:50 +0000
commit14d64a8adcc866deecd758b898e8ef2d836b354a (patch)
tree83cff9669e266f8e283ccb8cd7518e909240f1e1 /src
parentbdd9b5b8a0d37dd09ee530c1dab3a44bee09e0f8 (diff)
parentebe334cdc234de2897263aed4c05ac7088c11857 (diff)
downloademacs-scratch/correct-warning-pos.tar.gz
Merge branch 'master' into scratch/correct-warning-posscratch/correct-warning-pos
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in5
-rw-r--r--src/bidi.c8
-rw-r--r--src/buffer.c13
-rw-r--r--src/bytecode.c8
-rw-r--r--src/emacsgtkfixed.c6
-rw-r--r--src/frame.c8
-rw-r--r--src/gtkutil.c20
-rw-r--r--src/haiku_select.cc27
-rw-r--r--src/haiku_support.cc36
-rw-r--r--src/haiku_support.h8
-rw-r--r--src/haikufns.c498
-rw-r--r--src/haikumenu.c12
-rw-r--r--src/haikuselect.c31
-rw-r--r--src/haikuselect.h9
-rw-r--r--src/haikuterm.c90
-rw-r--r--src/haikuterm.h2
-rw-r--r--src/image.c6
-rw-r--r--src/keyboard.c47
-rw-r--r--src/nsterm.m11
-rw-r--r--src/pgtkfns.c14
-rw-r--r--src/pgtkterm.c38
-rw-r--r--src/syntax.c5
-rw-r--r--src/verbose.mk.in31
-rw-r--r--src/w32font.c3
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xfaces.c13
-rw-r--r--src/xfns.c98
-rw-r--r--src/xsettings.h5
-rw-r--r--src/xterm.c374
-rw-r--r--src/xterm.h15
-rw-r--r--src/xwidget.c3
31 files changed, 1015 insertions, 432 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 04fabd5f424..706beb453b6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -616,7 +616,7 @@ endif
## icon set.
ifeq ($(HAVE_BE_APP),yes)
-Emacs: emacs$(EXEEXT)
+Emacs: emacs$(EXEEXT) $(libsrc)/be-resources
$(AM_V_GEN) cp -f emacs$(EXEEXT) $@
$(AM_V_at) $(libsrc)/be-resources \
$(etc)/images/icons/hicolor/32x32/apps/emacs.png $@
@@ -914,6 +914,9 @@ $(bootstrap_pdmp): bootstrap-emacs$(EXEEXT)
$(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=pbootstrap \
--bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR)
@: Compile some files earlier to speed up further compilation.
+ @: First, byte compile these files, ....
+ ANCIENT=yes $(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)"
+ @: .... then use their .elcs in native compiling these and other files.
$(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)"
endif
diff --git a/src/bidi.c b/src/bidi.c
index c5d524f0493..d6ed607f14c 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -3569,7 +3569,9 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
ptrdiff_t
bidi_find_first_overridden (struct bidi_it *bidi_it)
{
- ptrdiff_t found_pos = ZV;
+ ptrdiff_t eob
+ = STRINGP (bidi_it->string.lstring) ? bidi_it->string.schars : ZV;
+ ptrdiff_t found_pos = eob;
/* Maximum bidi levels we allow for L2R and R2L characters. Note
that these are levels after resolving explicit embeddings,
overrides, and isolates, i.e. before resolving implicit levels. */
@@ -3607,8 +3609,8 @@ bidi_find_first_overridden (struct bidi_it *bidi_it)
|| ((category == WEAK || bidi_it->orig_type == NEUTRAL_ON)
&& level > max_weak))
found_pos = bidi_it->charpos;
- } while (found_pos == ZV
- && bidi_it->charpos < ZV
+ } while (found_pos == eob
+ && bidi_it->charpos < eob
&& bidi_it->ch != BIDI_EOB
&& bidi_it->ch != '\n');
diff --git a/src/buffer.c b/src/buffer.c
index a3091015d9b..0bdad086ddd 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -912,6 +912,10 @@ does not run the hooks `kill-buffer-hook',
Fset (intern ("buffer-save-without-query"), Qnil);
Fset (intern ("buffer-file-number"), Qnil);
Fset (intern ("buffer-stale-function"), Qnil);
+ /* Cloned buffers need extra setup, to do things such as deep
+ variable copies for list variables that might be mangled due
+ to destructive operations in the indirect buffer. */
+ run_hook (Qclone_indirect_buffer_hook);
set_buffer_internal_1 (old_b);
}
@@ -5569,6 +5573,8 @@ syms_of_buffer (void)
Fput (Qprotected_field, Qerror_message,
build_pure_c_string ("Attempt to modify a protected field"));
+ DEFSYM (Qclone_indirect_buffer_hook, "clone-indirect-buffer-hook");
+
DEFVAR_PER_BUFFER ("tab-line-format",
&BVAR (current_buffer, tab_line_format),
Qnil,
@@ -6392,6 +6398,13 @@ If `delete-auto-save-files' is nil, any autosave deletion is inhibited. */);
This is the default. If nil, auto-save file deletion is inhibited. */);
delete_auto_save_files = 1;
+ DEFVAR_LISP ("clone-indirect-buffer-hook", Vclone_indirect_buffer_hook,
+ doc: /* Normal hook to run in the new buffer at the end of `make-indirect-buffer'.
+
+Since `clone-indirect-buffer' calls `make-indirect-buffer', this hook
+will run for `clone-indirect-buffer' calls as well. */);
+ Vclone_indirect_buffer_hook = Qnil;
+
defsubr (&Sbuffer_live_p);
defsubr (&Sbuffer_list);
defsubr (&Sget_buffer);
diff --git a/src/bytecode.c b/src/bytecode.c
index 472992be180..b7e65d05aef 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1167,13 +1167,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
NEXT;
CASE (Bchar_syntax):
- {
- CHECK_CHARACTER (TOP);
- int c = XFIXNAT (TOP);
- if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
- c = make_char_multibyte (c);
- XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
- }
+ TOP = Fchar_syntax (TOP);
NEXT;
CASE (Bbuffer_substring):
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index da56031e2a4..a38ba35ad80 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -164,13 +164,9 @@ XSetWMSizeHints (Display *d,
if ((hints->flags & PMinSize) && f)
{
-#ifdef HAVE_PGTK
- int w = f->output_data.pgtk->size_hints.min_width;
- int h = f->output_data.pgtk->size_hints.min_height;
-#else
int w = f->output_data.x->size_hints.min_width;
int h = f->output_data.x->size_hints.min_height;
-#endif
+
data[5] = w;
data[6] = h;
}
diff --git a/src/frame.c b/src/frame.c
index e5d74edc168..8aaff949ba2 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -6472,6 +6472,14 @@ This variable is effective only with the X toolkit (and there only when
Gtk+ tooltips are not used) and on Windows. */);
tooltip_reuse_hidden_frame = false;
+ DEFVAR_BOOL ("use-system-tooltips", use_system_tooltips,
+ doc: /* Use the toolkit to display tooltips.
+This option is only meaningful when Emacs is built with GTK+ or Haiku
+windowing support, and results in tooltips that look like those
+displayed by other GTK+ or Haiku programs, but will not be able to
+display text properties inside tooltip text. */);
+ use_system_tooltips = true;
+
DEFVAR_LISP ("iconify-child-frame", iconify_child_frame,
doc: /* How to handle iconification of child frames.
This variable tells Emacs how to proceed when it is asked to iconify a
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 36ed55bc039..eb148560620 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -4534,6 +4534,12 @@ xg_update_scrollbar_pos (struct frame *f,
gtk_widget_show_all (wparent);
gtk_widget_set_size_request (wscroll, width, height);
}
+
+#if !defined HAVE_PGTK && GTK_CHECK_VERSION (2, 18, 0)
+ if (!gdk_window_ensure_native (gtk_widget_get_window (wscroll)))
+ emacs_abort ();
+#endif
+
if (oldx != -1 && oldw > 0 && oldh > 0)
{
/* Clear under old scroll bar position. */
@@ -4587,7 +4593,6 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
int width,
int height)
{
-
GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
if (wscroll)
@@ -4634,6 +4639,11 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
pgtk_clear_area (f, oldx, oldy, oldw, oldh);
#endif
+#if !defined HAVE_PGTK && GTK_CHECK_VERSION (2, 18, 0)
+ if (!gdk_window_ensure_native (gtk_widget_get_window (wscroll)))
+ emacs_abort ();
+#endif
+
/* GTK does not redraw until the main loop is entered again, but
if there are no X events pending we will not enter it. So we sync
here to get some events. */
@@ -6151,6 +6161,7 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event,
inev.ie.modifiers
|= x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), xstate);
+ inev.ie.timestamp = event->key.time;
if (event->key.is_modifier)
goto done;
@@ -6256,13 +6267,16 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event,
}
XNoOp (FRAME_X_DISPLAY (f));
+#ifdef USABLE_SIGIO
+ raise (SIGIO);
+#endif
return true;
}
bool
xg_filter_key (struct frame *frame, XEvent *xkey)
{
- GdkEvent *xg_event = gdk_event_new ((xkey->type == ButtonPress
+ GdkEvent *xg_event = gdk_event_new ((xkey->type == KeyPress
#ifdef HAVE_XINPUT2
|| (xkey->type == GenericEvent
&& xkey->xgeneric.evtype == XI_KeyPress)
@@ -6321,6 +6335,7 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
NULL, NULL, &consumed);
xg_add_virtual_mods (dpyinfo, &xg_event->key);
xg_event->key.state &= ~consumed;
+ xg_event->key.time = xkey->xkey.time;
#if GTK_CHECK_VERSION (3, 6, 0)
xg_event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap,
xg_event->key.hardware_keycode);
@@ -6334,6 +6349,7 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
xg_event->key.hardware_keycode = xev->detail;
xg_event->key.group = xev->group.effective;
xg_event->key.state = xev->mods.effective;
+ xg_event->key.time = xev->time;
gdk_keymap_translate_keyboard_state (keymap,
xev->detail,
xev->mods.effective,
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index 041e244f3ea..d39000d8bbe 100644
--- a/src/haiku_select.cc
+++ b/src/haiku_select.cc
@@ -29,6 +29,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
static BClipboard *primary = NULL;
static BClipboard *secondary = NULL;
static BClipboard *system_clipboard = NULL;
+static unsigned long count_clipboard = 0;
+static unsigned long count_primary = 0;
+static unsigned long count_secondary = 0;
int selection_state_flag;
@@ -174,6 +177,7 @@ BClipboard_set_system_data (const char *type, const char *data,
return;
BClipboard_set_data (system_clipboard, type, data, len, clear);
+ count_clipboard = system_clipboard->SystemCount ();
}
void
@@ -184,6 +188,7 @@ BClipboard_set_primary_selection_data (const char *type, const char *data,
return;
BClipboard_set_data (primary, type, data, len, clear);
+ count_primary = primary->SystemCount ();
}
void
@@ -194,6 +199,7 @@ BClipboard_set_secondary_selection_data (const char *type, const char *data,
return;
BClipboard_set_data (secondary, type, data, len, clear);
+ count_secondary = secondary->SystemCount ();
}
void
@@ -220,6 +226,27 @@ BClipboard_secondary_targets (char **buf, int len)
BClipboard_get_targets (secondary, buf, len);
}
+bool
+BClipboard_owns_clipboard (void)
+{
+ return (count_clipboard
+ == system_clipboard->SystemCount ());
+}
+
+bool
+BClipboard_owns_primary (void)
+{
+ return (count_primary
+ == primary->SystemCount ());
+}
+
+bool
+BClipboard_owns_secondary (void)
+{
+ return (count_secondary
+ == secondary->SystemCount ());
+}
+
void
init_haiku_select (void)
{
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index d49e319b98c..ae2736110ec 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <interface/MenuBar.h>
#include <interface/Alert.h>
#include <interface/Button.h>
+#include <interface/ControlLook.h>
#include <locale/UnicodeChar.h>
@@ -406,6 +407,7 @@ public:
bool menu_bar_active_p = false;
window_look pre_override_redirect_style;
window_feel pre_override_redirect_feel;
+ uint32 pre_override_redirect_workspaces;
EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -718,6 +720,7 @@ public:
int ret;
msg->FindInt32 ("raw_char", &raw);
msg->FindInt32 ("key", &key);
+ msg->FindInt64 ("when", &rq.time);
rq.modifiers = 0;
uint32_t mods = modifiers ();
@@ -1318,7 +1321,6 @@ public:
if (!offscreen_draw_view)
gui_abort ("Failed to lock offscreen view during buffer flip");
- offscreen_draw_view->Flush ();
offscreen_draw_view->Sync ();
EmacsWindow *w = (EmacsWindow *) Window ();
@@ -1381,8 +1383,8 @@ public:
rq.just_exited_p = transit == B_EXITED_VIEW;
rq.x = point.x;
rq.y = point.y;
- rq.be_code = transit;
rq.window = this->Window ();
+ rq.time = system_time ();
if (ToolTip ())
ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x),
@@ -1437,6 +1439,7 @@ public:
SetMouseEventMask (B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
+ rq.time = system_time ();
haiku_write (BUTTON_DOWN, &rq);
}
@@ -1483,6 +1486,7 @@ public:
if (!buttons)
SetMouseEventMask (0, 0);
+ rq.time = system_time ();
haiku_write (BUTTON_UP, &rq);
}
};
@@ -1632,17 +1636,17 @@ public:
{
struct haiku_menu_bar_help_event rq;
- if (menu_bar_id >= 0)
+ if (help)
+ {
+ Menu ()->SetToolTip (highlight_p ? help : NULL);
+ }
+ else if (menu_bar_id >= 0)
{
rq.window = wind_ptr;
rq.mb_idx = highlight_p ? menu_bar_id : -1;
haiku_write (MENU_BAR_HELP_EVENT, &rq);
}
- else if (help)
- {
- Menu ()->SetToolTip (highlight_p ? help : NULL);
- }
BMenuItem::Highlight (highlight_p);
}
@@ -1997,8 +2001,6 @@ BView_move_frame (void *view, int x, int y, int x1, int y1)
gui_abort ("Failed to lock view moving frame");
vw->MoveTo (x, y);
vw->ResizeTo (x1 - x, y1 - y);
- vw->Flush ();
- vw->Sync ();
vw->UnlockLooper ();
}
@@ -2018,7 +2020,9 @@ BView_scroll_bar_update (void *sb, int portion, int whole, int position)
int
BScrollBar_default_size (int horizontal_p)
{
- return horizontal_p ? B_H_SCROLL_BAR_HEIGHT : B_V_SCROLL_BAR_WIDTH;
+ return be_control_look->GetScrollBarWidth (horizontal_p
+ ? B_HORIZONTAL
+ : B_VERTICAL);
}
/* Invalidate VIEW, causing it to be drawn again. */
@@ -2224,7 +2228,11 @@ BWindow_set_tooltip_decoration (void *window)
if (!w->LockLooper ())
gui_abort ("Failed to lock window while setting ttip decoration");
w->SetLook (B_BORDERED_WINDOW_LOOK);
- w->SetFeel (B_FLOATING_APP_WINDOW_FEEL);
+ w->SetFeel (kMenuWindowFeel);
+ w->SetFlags (B_NOT_ZOOMABLE
+ | B_NOT_MINIMIZABLE
+ | B_AVOID_FRONT
+ | B_AVOID_FOCUS);
w->UnlockLooper ();
}
@@ -2241,7 +2249,6 @@ BWindow_set_avoid_focus (void *window, int avoid_focus_p)
w->SetFlags (w->Flags () & ~B_AVOID_FOCUS);
else
w->SetFlags (w->Flags () | B_AVOID_FOCUS);
- w->Sync ();
w->UnlockLooper ();
}
@@ -2818,7 +2825,7 @@ be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p, int
enum haiku_event_type type;
char *ptr = NULL;
- if (!haiku_read_with_timeout (&type, buf, 200, 100000))
+ if (!haiku_read_with_timeout (&type, buf, 200, 1000000))
{
block_input_function ();
if (type != FILE_PANEL_EVENT)
@@ -3166,11 +3173,14 @@ BWindow_set_override_redirect (void *window, bool override_redirect_p)
w->pre_override_redirect_style = w->Look ();
w->SetFeel (kMenuWindowFeel);
w->SetLook (B_NO_BORDER_WINDOW_LOOK);
+ w->pre_override_redirect_workspaces = w->Workspaces ();
+ w->SetWorkspaces (B_ALL_WORKSPACES);
}
else
{
w->SetFeel (w->pre_override_redirect_feel);
w->SetLook (w->pre_override_redirect_style);
+ w->SetWorkspaces (w->pre_override_redirect_workspaces);
}
w->UnlockLooper ();
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 83f22972ce2..6ddc28759b5 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -34,6 +34,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <math.h>
+#include <kernel/OS.h>
+
enum haiku_cursor
{
CURSOR_ID_NO_CURSOR = 12,
@@ -132,6 +134,9 @@ struct haiku_key_event
int modifiers;
unsigned keysym;
uint32_t multibyte_char;
+
+ /* Time the keypress occurred, in microseconds. */
+ bigtime_t time;
};
struct haiku_activation_event
@@ -146,7 +151,7 @@ struct haiku_mouse_motion_event
bool just_exited_p;
int x;
int y;
- uint32_t be_code;
+ bigtime_t time;
};
struct haiku_button_event
@@ -156,6 +161,7 @@ struct haiku_button_event
int modifiers;
int x;
int y;
+ bigtime_t time;
};
struct haiku_iconification_event
diff --git a/src/haikufns.c b/src/haikufns.c
index 52bb13bc89b..58a2e1d4642 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -45,7 +45,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
/* The frame of the currently visible tooltip. */
-static Lisp_Object tip_frame;
+Lisp_Object tip_frame;
/* The window-system window corresponding to the frame of the
currently visible tooltip. */
@@ -452,6 +452,15 @@ haiku_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object o
}
static void
+initial_setup_back_buffer (struct frame *f)
+{
+ block_input ();
+ if (NILP (CDR (Fassq (Qinhibit_double_buffering, f->param_alist))))
+ EmacsView_set_up_double_buffering (FRAME_HAIKU_VIEW (f));
+ unblock_input ();
+}
+
+static void
unwind_create_frame (Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
@@ -547,13 +556,12 @@ unwind_popup (void)
}
static Lisp_Object
-haiku_create_frame (Lisp_Object parms, int ttip_p)
+haiku_create_frame (Lisp_Object parms)
{
struct frame *f;
Lisp_Object frame, tem;
Lisp_Object name;
bool minibuffer_only = false;
- bool face_change_before = face_change;
long window_prompting = 0;
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object display;
@@ -593,10 +601,8 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
tem = gui_display_get_arg (dpyinfo, parms, Qminibuffer,
"minibuffer", "Minibuffer",
RES_TYPE_SYMBOL);
- if (ttip_p)
- f = make_frame (0);
- else if (EQ (tem, Qnone) || NILP (tem))
- f = make_frame_without_minibuffer (Qnil, kb, display);
+ if (EQ (tem, Qnone) || NILP (tem))
+ f = make_frame_without_minibuffer (Qnil, kb, display);
else if (EQ (tem, Qonly))
{
f = make_minibuffer_frame ();
@@ -618,22 +624,16 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
f->output_data.haiku->pending_zoom_width = INT_MIN;
f->output_data.haiku->pending_zoom_height = INT_MIN;
- if (ttip_p)
- f->wants_modeline = false;
-
fset_icon_name (f, gui_display_get_arg (dpyinfo, parms, Qicon_name,
"iconName", "Title",
RES_TYPE_STRING));
- if (! STRINGP (f->icon_name) || ttip_p)
+ if (! STRINGP (f->icon_name))
fset_icon_name (f, Qnil);
FRAME_DISPLAY_INFO (f) = dpyinfo;
/* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
- if (!ttip_p)
- record_unwind_protect (unwind_create_frame, frame);
- else
- record_unwind_protect (unwind_create_tip_frame, frame);
+ record_unwind_protect (unwind_create_frame, frame);
FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
FRAME_OUTPUT_DATA (f)->explicit_parent = 0;
@@ -660,8 +660,6 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
#endif
register_font_driver (&haikufont_driver, f);
- f->tooltip = ttip_p;
-
image_cache_refcount =
FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
@@ -674,7 +672,7 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
"borderwidth", "BorderWidth", RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (ttip_p ? 1 : 2),
+ gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2),
"internalBorderWidth", "InternalBorderWidth",
RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
@@ -684,7 +682,7 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
NULL, NULL, RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
NULL, NULL, RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qvertical_scroll_bars, !ttip_p ? Qt : Qnil,
+ gui_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
"verticalScrollBars", "VerticalScrollBars",
RES_TYPE_SYMBOL);
gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
@@ -700,7 +698,7 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
"leftFringe", "LeftFringe", RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qright_fringe, Qnil,
"rightFringe", "RightFringe", RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qno_special_glyphs, ttip_p ? Qnil : Qt,
+ gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
NULL, NULL, RES_TYPE_BOOLEAN);
init_frame_faces (f);
@@ -718,57 +716,39 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1,
Qx_create_frame_1);
- if (!ttip_p)
- {
- gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
- gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
- NULL, NULL, RES_TYPE_BOOLEAN);
- gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
- NULL, NULL, RES_TYPE_BOOLEAN);
-
- /* The resources controlling the menu-bar, tool-bar, and tab-bar are
- processed specially at startup, and reflected in the mode
- variables; ignore them here. */
- gui_default_parameter (f, parms, Qmenu_bar_lines,
- NILP (Vmenu_bar_mode)
- ? make_fixnum (0) : make_fixnum (1),
- NULL, NULL, RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qtab_bar_lines,
- NILP (Vtab_bar_mode)
- ? make_fixnum (0) : make_fixnum (1),
- NULL, NULL, RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qtool_bar_lines,
- NILP (Vtool_bar_mode)
- ? make_fixnum (0) : make_fixnum (1),
- NULL, NULL, RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
- "BufferPredicate", RES_TYPE_SYMBOL);
- gui_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
- RES_TYPE_STRING);
- }
+ gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ /* The resources controlling the menu-bar, tool-bar, and tab-bar are
+ processed specially at startup, and reflected in the mode
+ variables; ignore them here. */
+ gui_default_parameter (f, parms, Qmenu_bar_lines,
+ NILP (Vmenu_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtab_bar_lines,
+ NILP (Vtab_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtool_bar_lines,
+ NILP (Vtool_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
+ "BufferPredicate", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
+ RES_TYPE_STRING);
parms = get_geometry_from_preferences (dpyinfo, parms);
window_prompting = gui_figure_window_size (f, parms, false, true);
- if (ttip_p)
- {
- /* No fringes on tip frame. */
- f->fringe_cols = 0;
- f->left_fringe_width = 0;
- f->right_fringe_width = 0;
- /* No dividers on tip frame. */
- f->right_divider_width = 0;
- f->bottom_divider_width = 0;
- }
-
tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem));
- /* Add `tooltip' frame parameter's default value. */
- if (NILP (Fframe_parameter (frame, Qtooltip)) && ttip_p)
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
-
#define ASSIGN_CURSOR(cursor, be_cursor) \
(FRAME_OUTPUT_DATA (f)->cursor = be_cursor)
@@ -803,16 +783,13 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
ASSIGN_CURSOR (current_cursor, FRAME_OUTPUT_DATA (f)->text_cursor);
#undef ASSIGN_CURSOR
-
- if (ttip_p)
- f->no_split = true;
f->terminal->reference_count++;
FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
if (!FRAME_OUTPUT_DATA (f)->window)
xsignal1 (Qerror, build_unibyte_string ("Could not create window"));
- if (!minibuffer_only && !ttip_p && FRAME_EXTERNAL_MENU_BAR (f))
+ if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
initialize_frame_menubar (f);
FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window;
@@ -839,58 +816,33 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
gui_default_parameter (f, parms, Qicon_type, Qnil,
"bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
- if (ttip_p)
- {
- gui_default_parameter (f, parms, Qundecorated, Qt, NULL, NULL, RES_TYPE_BOOLEAN);
- gui_default_parameter (f, parms, Qno_accept_focus, Qt, NULL, NULL,
- RES_TYPE_BOOLEAN);
- }
- else
- {
- gui_default_parameter (f, parms, Qauto_raise, Qnil,
- "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- gui_default_parameter (f, parms, Qauto_lower, Qnil,
- "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
- gui_default_parameter (f, parms, Qcursor_type, Qbox,
- "cursorType", "CursorType", RES_TYPE_SYMBOL);
- gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
- "scrollBarWidth", "ScrollBarWidth",
- RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
- "scrollBarHeight", "ScrollBarHeight",
- RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qalpha, Qnil,
- "alpha", "Alpha", RES_TYPE_NUMBER);
- gui_default_parameter (f, parms, Qfullscreen, Qnil,
- "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
- }
+ gui_default_parameter (f, parms, Qauto_raise, Qnil,
+ "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qauto_lower, Qnil,
+ "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qcursor_type, Qbox,
+ "cursorType", "CursorType", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
+ "scrollBarWidth", "ScrollBarWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
+ "scrollBarHeight", "ScrollBarHeight",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qfullscreen, Qnil,
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
"inhibitDoubleBuffering", "InhibitDoubleBuffering",
RES_TYPE_BOOLEAN);
- if (ttip_p)
- {
- Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
-
- call2 (Qface_set_after_frame_default, frame, Qnil);
-
- if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
- {
- AUTO_FRAME_ARG (arg, Qbackground_color, bg);
- Fmodify_frame_parameters (frame, arg);
- }
- }
-
- if (ttip_p)
- face_change = face_change_before;
-
f->can_set_window_size = true;
adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
- 0, true, ttip_p ? Qtip_frame : Qx_create_frame_2);
+ 0, true, Qx_create_frame_2);
- if (!FRAME_OUTPUT_DATA (f)->explicit_parent && !ttip_p)
+ if (!FRAME_OUTPUT_DATA (f)->explicit_parent)
{
Lisp_Object visibility;
@@ -908,13 +860,10 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
}
}
- if (!ttip_p)
- {
- if (FRAME_HAS_MINIBUF_P (f)
- && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
- || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
- kset_default_minibuffer_frame (kb, frame);
- }
+ if (FRAME_HAS_MINIBUF_P (f)
+ && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
+ || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
+ kset_default_minibuffer_frame (kb, frame);
for (tem = parms; CONSP (tem); tem = XCDR (tem))
if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
@@ -929,13 +878,230 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
and similar functions. */
Vwindow_list = Qnil;
- if (ttip_p)
- adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
- 0, true, Qtip_frame);
+ return unbind_to (count, frame);
+}
+
+/* Create a frame for a tooltip. PARMS is a list of frame parameters.
+ TEXT is the string to display in the tip frame. Value is the
+ frame.
+
+ Note that functions called here, esp. gui_default_parameter can
+ signal errors, for instance when a specified color name is
+ undefined. We have to make sure that we're in a consistent state
+ when this happens. */
+static Lisp_Object
+haiku_create_tip_frame (Lisp_Object parms)
+{
+ struct frame *f;
+ Lisp_Object frame;
+ Lisp_Object name;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ bool face_change_before = face_change;
+ struct haiku_display_info *dpyinfo = x_display_list;
+
+ if (!dpyinfo->terminal->name)
+ error ("Terminal is not live, can't create new frames on it");
+
+ parms = Fcopy_alist (parms);
+
+ /* Get the name of the frame to use for resource lookup. */
+ name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
+ RES_TYPE_STRING);
+ if (!STRINGP (name)
+ && !EQ (name, Qunbound)
+ && !NILP (name))
+ error ("Invalid frame name--not a string or nil");
+
+ frame = Qnil;
+ f = make_frame (false);
+ f->wants_modeline = false;
+ XSETFRAME (frame, f);
+ record_unwind_protect (unwind_create_tip_frame, frame);
+
+ f->terminal = dpyinfo->terminal;
+
+ /* By setting the output method, we're essentially saying that
+ the frame is live, as per FRAME_LIVE_P. If we get a signal
+ from this point on, x_destroy_window might screw up reference
+ counts etc. */
+ f->output_method = output_haiku;
+ f->output_data.haiku = xzalloc (sizeof *f->output_data.haiku);
+
+ f->output_data.haiku->pending_zoom_x = INT_MIN;
+ f->output_data.haiku->pending_zoom_y = INT_MIN;
+ f->output_data.haiku->pending_zoom_width = INT_MIN;
+ f->output_data.haiku->pending_zoom_height = INT_MIN;
+
+ f->tooltip = true;
+ fset_icon_name (f, Qnil);
+ FRAME_DISPLAY_INFO (f) = dpyinfo;
+
+ FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
+ FRAME_OUTPUT_DATA (f)->explicit_parent = 0;
+
+ /* Set the name; the functions to which we pass f expect the name to
+ be set. */
+ if (EQ (name, Qunbound) || NILP (name))
+ f->explicit_name = false;
+ else
+ {
+ fset_name (f, name);
+ f->explicit_name = true;
+ /* use the frame's title when getting resources for this frame. */
+ specbind (Qx_resource_name, name);
+ }
+
+#ifdef USE_BE_CAIRO
+ register_font_driver (&ftcrfont_driver, f);
+#ifdef HAVE_HARFBUZZ
+ register_font_driver (&ftcrhbfont_driver, f);
+#endif
+#endif
+ register_font_driver (&haikufont_driver, f);
+
+ image_cache_refcount =
+ FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
+
+ gui_default_parameter (f, parms, Qfont_backend, Qnil,
+ "fontBackend", "FontBackend", RES_TYPE_STRING);
+
+ /* Extract the window parameters from the supplied values that are
+ needed to determine window geometry. */
+ FRAME_RIF (f)->default_font_parameter (f, parms);
+
+ /* This defaults to 1 in order to match xterm. We recognize either
+ internalBorderWidth or internalBorder (which is what xterm calls
+ it). */
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ {
+ Lisp_Object value;
+
+ value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
+ "internalBorder", "internalBorder",
+ RES_TYPE_NUMBER);
+ if (! EQ (value, Qunbound))
+ parms = Fcons (Fcons (Qinternal_border_width, value),
+ parms);
+ }
+
+ gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
+ "internalBorderWidth", "internalBorderWidth",
+ RES_TYPE_NUMBER);
+
+ gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+
+ /* Also do the stuff which must be set before the window exists. */
+ gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
+ "foreground", "Foreground", RES_TYPE_STRING);
+
+ gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
+ "background", "Background", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
+ "pointerColor", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
+ "cursorColor", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
+ "borderColor", "BorderColor", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ /* Init faces before gui_default_parameter is called for the
+ scroll-bar-width parameter because otherwise we end up in
+ init_iterator with a null face cache, which should not happen. */
+ init_frame_faces (f);
+
+ gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
+ "inhibitDoubleBuffering", "InhibitDoubleBuffering",
+ RES_TYPE_BOOLEAN);
+
+ gui_figure_window_size (f, parms, false, false);
+
+ {
+ void *window;
+
+ block_input ();
+ window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
+
+ FRAME_OUTPUT_DATA (f)->window = window;
+ if (!window)
+ emacs_abort ();
+
+ FRAME_OUTPUT_DATA (f)->window_desc = window;
+ BWindow_set_tooltip_decoration (window);
+ unblock_input ();
+ }
+
+ gui_default_parameter (f, parms, Qauto_raise, Qnil,
+ "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qauto_lower, Qnil,
+ "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qcursor_type, Qbox,
+ "cursorType", "CursorType", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
+
+ initial_setup_back_buffer (f);
+
+ /* Add `tooltip' frame parameter's default value. */
+ if (NILP (Fframe_parameter (frame, Qtooltip)))
+ {
+ AUTO_FRAME_ARG (arg, Qtooltip, Qt);
+ Fmodify_frame_parameters (frame, arg);
+ }
+
+ /* FIXME - can this be done in a similar way to normal frames?
+ https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */
+
+ /* Set up faces after all frame parameters are known. This call
+ also merges in face attributes specified for new frames.
+
+ Frame parameters may be changed if .Xdefaults contains
+ specifications for the default font. For example, if there is an
+ `Emacs.default.attributeBackground: pink', the `background-color'
+ attribute of the frame gets set, which let's the internal border
+ of the tooltip frame appear in pink. Prevent this. */
+ {
+ Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
+
+ call2 (Qface_set_after_frame_default, frame, Qnil);
+
+ if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
+ {
+ AUTO_FRAME_ARG (arg, Qbackground_color, bg);
+ Fmodify_frame_parameters (frame, arg);
+ }
+ }
+
+ f->no_split = true;
+
+ /* Now that the frame will be official, it counts as a reference to
+ its display and terminal. */
+ f->terminal->reference_count++;
+
+ /* It is now ok to make the frame official even if we get an error
+ below. And the frame needs to be on Vframe_list or making it
+ visible won't work. */
+ Vframe_list = Fcons (frame, Vframe_list);
+ f->can_set_window_size = true;
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 0, true, Qtip_frame);
+
+ /* Setting attributes of faces of the tooltip frame from resources
+ and similar will set face_change, which leads to the clearing of
+ all current matrices. Since this isn't necessary here, avoid it
+ by resetting face_change to the value it had before we created
+ the tip frame. */
+ face_change = face_change_before;
+
+ /* Discard the unwind_protect. */
return unbind_to (count, frame);
}
+
static void
compute_tip_xy (struct frame *f,
Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
@@ -1440,6 +1606,7 @@ haiku_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object o
if (new_width == old_width)
return;
+
f->internal_border_width = new_width;
if (FRAME_HAIKU_WINDOW (f))
@@ -1527,9 +1694,9 @@ haiku_set_inhibit_double_buffering (struct frame *f,
Lisp_Object old_value)
{
block_input ();
-#ifndef USE_BE_CAIRO
if (FRAME_HAIKU_WINDOW (f))
{
+#ifndef USE_BE_CAIRO
if (NILP (new_value))
{
#endif
@@ -1543,8 +1710,8 @@ haiku_set_inhibit_double_buffering (struct frame *f,
}
else
EmacsView_disable_double_buffering (FRAME_HAIKU_VIEW (f));
- }
#endif
+ }
unblock_input ();
}
@@ -1709,7 +1876,7 @@ DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
int width, height;
BScreen_px_dim (&width, &height);
- return make_fixnum (height / (dpyinfo->resy / 25.4));
+ return make_fixnum (width / (dpyinfo->resx / 25.4));
}
DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
@@ -1717,7 +1884,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
doc: /* SKIP: real doc in xfns.c. */)
(Lisp_Object parms)
{
- return haiku_create_frame (parms, 0);
+ return haiku_create_frame (parms);
}
DEFUN ("x-display-visual-class", Fx_display_visual_class,
@@ -1752,12 +1919,13 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
ptrdiff_t count = SPECPDL_INDEX ();
ptrdiff_t count_1;
Lisp_Object window, size, tip_buf;
-
AUTO_STRING (tip, " *tip*");
specbind (Qinhibit_redisplay, Qt);
CHECK_STRING (string);
+ if (SCHARS (string) == 0)
+ string = make_unibyte_string (" ", 1);
if (NILP (frame))
frame = selected_frame;
@@ -1778,7 +1946,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
else
CHECK_FIXNUM (dy);
- if (haiku_use_system_tooltips)
+ if (use_system_tooltips)
{
int root_x, root_y;
CHECK_STRING (string);
@@ -1821,24 +1989,21 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
{
if (FRAME_VISIBLE_P (XFRAME (tip_frame))
&& EQ (frame, tip_last_frame)
- && !NILP (Fequal_including_properties (string, tip_last_string))
- && !NILP (Fequal (parms, tip_last_parms)))
+ && !NILP (Fequal_including_properties (tip_last_string, string))
+ && !NILP (Fequal (tip_last_parms, parms)))
{
/* Only DX and DY have changed. */
tip_f = XFRAME (tip_frame);
if (!NILP (tip_timer))
{
- Lisp_Object timer = tip_timer;
-
+ call1 (Qcancel_timer, tip_timer);
tip_timer = Qnil;
- call1 (Qcancel_timer, timer);
}
block_input ();
compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
- haiku_set_offset (tip_f, root_x, root_y, 1);
- haiku_visualize_frame (tip_f);
+ BWindow_set_offset (FRAME_HAIKU_WINDOW (tip_f), root_x, root_y);
unblock_input ();
goto start_timer;
@@ -1849,8 +2014,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
Lisp_Object tail, elt, parm, last;
/* Check if every parameter in PARMS has the same value in
- tip_last_parms. This may destruct tip_last_parms
- which, however, will be recreated below. */
+ tip_last_parms. This may destruct tip_last_parms which,
+ however, will be recreated below. */
for (tail = parms; CONSP (tail); tail = XCDR (tail))
{
elt = XCAR (tail);
@@ -1876,8 +2041,9 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
call2 (Qassq_delete_all, parm, tip_last_parms);
}
- /* Now check if there's a parameter left in tip_last_parms with a
- non-nil value. */
+ /* Now check if every parameter in what is left of
+ tip_last_parms with a non-nil value has an association in
+ PARMS. */
for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
{
elt = XCAR (tail);
@@ -1903,10 +2069,6 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
tip_last_string = string;
tip_last_parms = parms;
- /* Block input until the tip has been fully drawn, to avoid crashes
- when drawing tips in menus. */
- block_input ();
-
if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
{
/* Add default values to frame parameters. */
@@ -1917,21 +2079,16 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
if (NILP (Fassq (Qborder_width, parms)))
parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
if (NILP (Fassq (Qborder_color, parms)))
- parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
- parms);
+ parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
if (NILP (Fassq (Qbackground_color, parms)))
parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
parms);
- /* Create a frame for the tooltip and record it in the global
+ /* Create a frame for the tooltip, and record it in the global
variable tip_frame. */
-
- if (NILP (tip_frame = haiku_create_frame (parms, 1)))
- {
- /* Creating the tip frame failed. */
- unblock_input ();
- return unbind_to (count, Qnil);
- }
+ if (NILP (tip_frame = haiku_create_tip_frame (parms)))
+ /* Creating the tip frame failed. */
+ return unbind_to (count, Qnil);
}
tip_f = XFRAME (tip_frame);
@@ -1971,11 +2128,11 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
- FRAME_TOTAL_COLS (tip_f) = WINDOW_TOTAL_COLS (w);
+ FRAME_TOTAL_COLS (tip_f) = w->total_cols;
adjust_frame_glyphs (tip_f);
- /* Insert STRING into the root window's buffer and fit the frame to
- the buffer. */
+ /* Insert STRING into root window's buffer and fit the frame to the
+ buffer. */
count_1 = SPECPDL_INDEX ();
old_buffer = current_buffer;
set_buffer_internal_1 (XBUFFER (w->contents));
@@ -1996,22 +2153,28 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
/* Add the frame's internal border to calculated size. */
width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+
/* Calculate position of tooltip frame. */
compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
- BWindow_resize (FRAME_HAIKU_WINDOW (tip_f), width, height);
- haiku_set_offset (tip_f, root_x, root_y, 1);
- BWindow_set_tooltip_decoration (FRAME_HAIKU_WINDOW (tip_f));
- BView_set_view_cursor (FRAME_HAIKU_VIEW (tip_f),
- FRAME_OUTPUT_DATA (XFRAME (frame))->current_cursor);
- SET_FRAME_VISIBLE (tip_f, 1);
- BWindow_set_visible (FRAME_HAIKU_WINDOW (tip_f), 1);
+
+ /* Show tooltip frame. */
+ block_input ();
+ void *wnd = FRAME_HAIKU_WINDOW (tip_f);
+ BWindow_resize (wnd, width, height);
+ BView_resize_to (FRAME_HAIKU_VIEW (tip_f), width, height);
+ BWindow_set_offset (wnd, root_x, root_y);
+ BWindow_set_visible (wnd, true);
+ SET_FRAME_VISIBLE (tip_f, true);
+ FRAME_PIXEL_WIDTH (tip_f) = width;
+ FRAME_PIXEL_HEIGHT (tip_f) = height;
+ BWindow_sync (wnd);
+ unblock_input ();
w->must_be_updated_p = true;
- flush_frame (tip_f);
update_single_window (w);
+ flush_frame (tip_f);
set_buffer_internal_1 (old_buffer);
unbind_to (count_1, Qnil);
- unblock_input ();
windows_or_buffers_changed = old_windows_or_buffers_changed;
start_timer:
@@ -2459,6 +2622,7 @@ syms_of_haikufns (void)
DEFSYM (Qalways, "always");
DEFSYM (Qnot_useful, "not-useful");
DEFSYM (Qwhen_mapped, "when-mapped");
+ DEFSYM (Qtooltip_reuse_hidden_frame, "tooltip-reuse-hidden-frame");
defsubr (&Sx_hide_tip);
defsubr (&Sxw_display_color_p);
@@ -2508,14 +2672,6 @@ syms_of_haikufns (void)
doc: /* SKIP: real doc in xfns.c. */);
Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40));
- DEFVAR_BOOL ("haiku-use-system-tooltips", haiku_use_system_tooltips,
- doc: /* When non-nil, Emacs will display tooltips using the App Kit.
-This can avoid a great deal of consing that does not play
-well with the Haiku memory allocator, but comes with the
-disadvantage of not being able to use special display properties
-within tooltips. */);
- haiku_use_system_tooltips = 1;
-
#ifdef USE_BE_CAIRO
DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
doc: /* Version info for cairo. */);
diff --git a/src/haikumenu.c b/src/haikumenu.c
index f335bdacb40..2922981cb3b 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -142,10 +142,7 @@ digest_menu_items (void *first_menu, int start, int menu_items_used,
}
if (STRINGP (help) && STRING_MULTIBYTE (help))
- {
- help = ENCODE_UTF_8 (help);
- ASET (menu_items, i + MENU_ITEMS_ITEM_HELP, help);
- }
+ help = ENCODE_UTF_8 (help);
if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
@@ -158,6 +155,12 @@ digest_menu_items (void *first_menu, int start, int menu_items_used,
!NILP (enable), !NILP (selected), 0, window,
!NILP (descrip) ? SSDATA (descrip) : NULL,
STRINGP (help) ? SSDATA (help) : NULL);
+ else if (!use_system_tooltips || NILP (Fsymbol_value (Qtooltip_mode)))
+ BMenu_add_item (menu, SSDATA (item_name),
+ !NILP (def) ? (void *) (intptr_t) i : NULL,
+ !NILP (enable), !NILP (selected), 1, window,
+ !NILP (descrip) ? SSDATA (descrip) : NULL,
+ NULL);
else
BMenu_add_item (menu, SSDATA (item_name),
!NILP (def) ? (void *) (intptr_t) i : NULL,
@@ -664,6 +667,7 @@ syms_of_haikumenu (void)
DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
DEFSYM (Qpopup_menu, "popup-menu");
DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map");
+ DEFSYM (Qtooltip_mode, "tooltip-mode");
defsubr (&Smenu_or_popup_active_p);
defsubr (&Shaiku_menu_bar_open);
diff --git a/src/haikuselect.c b/src/haikuselect.c
index 2e619c69f7a..e65ab827c51 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -166,6 +166,36 @@ clipboard. */)
return Qnil;
}
+DEFUN ("haiku-selection-owner-p", Fhaiku_selection_owner_p, Shaiku_selection_owner_p,
+ 0, 1, 0,
+ doc: /* Whether the current Emacs process owns the given SELECTION.
+The arg should be the name of the selection in question, typically one
+of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. For
+convenience, the symbol nil is the same as `PRIMARY', and t is the
+same as `SECONDARY'. */)
+ (Lisp_Object selection)
+{
+ bool value;
+
+ if (NILP (selection))
+ selection = QPRIMARY;
+ else if (EQ (selection, Qt))
+ selection = QSECONDARY;
+
+ block_input ();
+ if (EQ (selection, QPRIMARY))
+ value = BClipboard_owns_primary ();
+ else if (EQ (selection, QSECONDARY))
+ value = BClipboard_owns_secondary ();
+ else if (EQ (selection, QCLIPBOARD))
+ value = BClipboard_owns_clipboard ();
+ else
+ value = false;
+ unblock_input ();
+
+ return value ? Qt : Qnil;
+}
+
void
syms_of_haikuselect (void)
{
@@ -179,4 +209,5 @@ syms_of_haikuselect (void)
defsubr (&Shaiku_selection_data);
defsubr (&Shaiku_selection_put);
defsubr (&Shaiku_selection_targets);
+ defsubr (&Shaiku_selection_owner_p);
}
diff --git a/src/haikuselect.h b/src/haikuselect.h
index 80f33c6ed25..566aae596f6 100644
--- a/src/haikuselect.h
+++ b/src/haikuselect.h
@@ -66,6 +66,15 @@ extern "C"
extern void
BClipboard_secondary_targets (char **buf, int len);
+ extern bool
+ BClipboard_owns_clipboard (void);
+
+ extern bool
+ BClipboard_owns_primary (void);
+
+ extern bool
+ BClipboard_owns_secondary (void);
+
/* Free the returned data. */
extern void BClipboard_free_data (void *ptr);
#ifdef __cplusplus
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 3e99cc1c8d9..93ba088f5b1 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -55,6 +55,8 @@ struct unhandled_event
uint8_t buffer[200];
};
+static bool any_help_event_p = false;
+
char *
get_keysym_name (int keysym)
{
@@ -281,7 +283,7 @@ haiku_new_font (struct frame *f, Lisp_Object font_object, int fontset)
else
FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
- if (FRAME_HAIKU_WINDOW (f))
+ if (FRAME_HAIKU_WINDOW (f) && !FRAME_TOOLTIP_P (f))
{
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
FRAME_LINES (f) * FRAME_LINE_HEIGHT (f),
@@ -370,6 +372,13 @@ haiku_frame_raise_lower (struct frame *f, bool raise_p)
BWindow_sync (FRAME_HAIKU_WINDOW (f));
unblock_input ();
}
+ else
+ {
+ block_input ();
+ BWindow_send_behind (FRAME_HAIKU_WINDOW (f), NULL);
+ BWindow_sync (FRAME_HAIKU_WINDOW (f));
+ unblock_input ();
+ }
}
/* Unfortunately, NOACTIVATE is not implementable on Haiku. */
@@ -2472,10 +2481,7 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
struct haiku_font_pattern ptn;
ptn.specified = 0;
- if (f->tooltip)
- BFont_populate_plain_family (&ptn);
- else
- BFont_populate_fixed_family (&ptn);
+ BFont_populate_fixed_family (&ptn);
if (ptn.specified & FSPEC_FAMILY)
font = font_open_by_name (f, build_unibyte_string (ptn.family));
@@ -2590,6 +2596,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
struct unhandled_event *unhandled_events = NULL;
int button_or_motion_p;
int need_flush = 0;
+ int do_help = 0;
if (!buf)
buf = xmalloc (200);
@@ -2638,9 +2645,19 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
int width = lrint (b->px_widthf);
int height = lrint (b->px_heightf);
+ if (FRAME_TOOLTIP_P (f))
+ {
+ FRAME_PIXEL_WIDTH (f) = width;
+ FRAME_PIXEL_HEIGHT (f) = height;
+
+ haiku_clear_under_internal_border (f);
+ continue;
+ }
+
BView_draw_lock (FRAME_HAIKU_VIEW (f));
BView_resize_to (FRAME_HAIKU_VIEW (f), width, height);
BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+
if (width != FRAME_PIXEL_WIDTH (f)
|| height != FRAME_PIXEL_HEIGHT (f)
|| (f->new_size_p
@@ -2708,6 +2725,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
inev.kind = inev.code > 127 ? MULTIBYTE_CHAR_KEYSTROKE_EVENT :
ASCII_KEYSTROKE_EVENT;
+ inev.timestamp = b->time / 1000;
inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
XSETFRAME (inev.frame_or_window, f);
break;
@@ -2746,7 +2764,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
Lisp_Object frame;
XSETFRAME (frame, f);
- x_display_list->last_mouse_movement_time = time (NULL);
+ x_display_list->last_mouse_movement_time = b->time / 1000;
button_or_motion_p = 1;
if (hlinfo->mouse_face_hidden)
@@ -2770,14 +2788,25 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
}
haiku_new_focus_frame (x_display_list->focused_frame);
- help_echo_string = Qnil;
- gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+
+ if (any_help_event_p)
+ do_help = -1;
}
else
{
struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
struct haiku_rect r = dpyinfo->last_mouse_glyph;
+ /* For an unknown reason Haiku sends phantom motion events when a
+ tooltip frame is visible. FIXME */
+ if (FRAMEP (tip_frame)
+ && FRAME_LIVE_P (XFRAME (tip_frame))
+ && FRAME_VISIBLE_P (XFRAME (tip_frame))
+ && f == dpyinfo->last_mouse_motion_frame
+ && b->x == dpyinfo->last_mouse_motion_x
+ && b->y == dpyinfo->last_mouse_motion_y)
+ continue;
+
dpyinfo->last_mouse_motion_x = b->x;
dpyinfo->last_mouse_motion_y = b->y;
dpyinfo->last_mouse_motion_frame = f;
@@ -2816,9 +2845,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
remember_mouse_glyph (f, b->x, b->y,
&FRAME_DISPLAY_INFO (f)->last_mouse_glyph);
dpyinfo->last_mouse_glyph_frame = f;
- gen_help_event (help_echo_string, frame, help_echo_window,
- help_echo_object, help_echo_pos);
}
+ else
+ help_echo_string = previous_help_echo_string;
if (!NILP (Vmouse_autoselect_window))
{
@@ -2838,6 +2867,10 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
last_mouse_window = window;
}
+
+ if (!NILP (help_echo_string)
+ || !NILP (previous_help_echo_string))
+ do_help = 1;
}
break;
}
@@ -2857,7 +2890,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
x_display_list->last_mouse_glyph_frame = 0;
- x_display_list->last_mouse_movement_time = time (NULL);
+ x_display_list->last_mouse_movement_time = b->time / 1000;
button_or_motion_p = 1;
/* Is this in the tab-bar? */
@@ -3262,20 +3295,20 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
if (inev.kind != NO_EVENT)
{
- if (inev.kind != HELP_EVENT)
+ if (inev.kind != HELP_EVENT && !inev.timestamp)
inev.timestamp = (button_or_motion_p
? x_display_list->last_mouse_movement_time
- : time (NULL));
+ : system_time () / 1000);
kbd_buffer_store_event_hold (&inev, hold_quit);
++message_count;
}
if (inev2.kind != NO_EVENT)
{
- if (inev2.kind != HELP_EVENT)
+ if (inev2.kind != HELP_EVENT && !inev.timestamp)
inev2.timestamp = (button_or_motion_p
? x_display_list->last_mouse_movement_time
- : time (NULL));
+ : system_time () / 1000);
kbd_buffer_store_event_hold (&inev2, hold_quit);
++message_count;
}
@@ -3289,6 +3322,28 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
xfree (old);
}
+ if (do_help && !(hold_quit && hold_quit->kind != NO_EVENT))
+ {
+ Lisp_Object help_frame = Qnil;
+
+ if (x_display_list->last_mouse_frame)
+ XSETFRAME (help_frame,
+ x_display_list->last_mouse_frame);
+
+ if (do_help > 0)
+ {
+ any_help_event_p = true;
+ gen_help_event (help_echo_string, help_frame,
+ help_echo_window, help_echo_object,
+ help_echo_pos);
+ }
+ else
+ {
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, help_frame, Qnil, Qnil, 0);
+ }
+ }
+
if (need_flush)
flush_dirty_back_buffers ();
@@ -3507,7 +3562,10 @@ put_xrm_resource (Lisp_Object name, Lisp_Object val)
void
haiku_clear_under_internal_border (struct frame *f)
{
- if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+ if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
+ /* This is needed because tooltip frames set up the internal
+ border before init_frame_faces. */
+ && FRAME_FACE_CACHE (f))
{
int border = FRAME_INTERNAL_BORDER_WIDTH (f);
int width = FRAME_PIXEL_WIDTH (f);
diff --git a/src/haikuterm.h b/src/haikuterm.h
index 3e39403ab4d..de302883e48 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -178,6 +178,8 @@ struct x_output
extern struct haiku_display_info *x_display_list;
extern struct font_driver const haikufont_driver;
+extern Lisp_Object tip_frame;
+
struct scroll_bar
{
/* These fields are shared by all vectors. */
diff --git a/src/image.c b/src/image.c
index a4976caba86..ce9af2dd677 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2906,9 +2906,8 @@ x_create_xrender_picture (struct frame *f, Emacs_Pixmap pixmap, int depth)
{
Picture p;
Display *display = FRAME_X_DISPLAY (f);
- int event_basep, error_basep;
- if (XRenderQueryExtension (display, &event_basep, &error_basep))
+ if (FRAME_DISPLAY_INFO (f)->xrender_supported_p)
{
if (depth <= 0)
depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
@@ -11198,8 +11197,7 @@ The list of capabilities can include one or more of the following:
# elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
int event_basep, error_basep;
- if (XRenderQueryExtension (FRAME_X_DISPLAY (f),
- &event_basep, &error_basep))
+ if (FRAME_DISPLAY_INFO (f)->xrender_supported_p)
return list2 (Qscale, Qrotate90);
# elif defined (HAVE_NTGUI)
return (w32_image_rotations_p ()
diff --git a/src/keyboard.c b/src/keyboard.c
index d2ab3a80249..441c23e10c7 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1897,6 +1897,9 @@ int poll_suppress_count;
static struct atimer *poll_timer;
+/* The poll period that constructed this timer. */
+static Lisp_Object poll_timer_time;
+
#if defined CYGWIN || defined DOS_NT
/* Poll for input, so that we catch a C-g if it comes in. */
void
@@ -1938,17 +1941,18 @@ start_polling (void)
/* If poll timer doesn't exist, or we need one with
a different interval, start a new one. */
- if (poll_timer == NULL
- || poll_timer->interval.tv_sec != polling_period)
+ if (NUMBERP (Vpolling_period)
+ && (poll_timer == NULL
+ || NILP (Fequal (Vpolling_period, poll_timer_time))))
{
- time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
- struct timespec interval = make_timespec (period, 0);
+ struct timespec interval = dtotimespec (XFLOATINT (Vpolling_period));
if (poll_timer)
cancel_atimer (poll_timer);
poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
poll_for_input, NULL);
+ poll_timer_time = Vpolling_period;
}
/* Let the timer's callback function poll for input
@@ -2016,14 +2020,28 @@ void
bind_polling_period (int n)
{
#ifdef POLL_FOR_INPUT
- intmax_t new = polling_period;
+ if (FIXNUMP (Vpolling_period))
+ {
+ intmax_t new = XFIXNUM (Vpolling_period);
+
+ if (n > new)
+ new = n;
+
+ stop_other_atimers (poll_timer);
+ stop_polling ();
+ specbind (Qpolling_period, make_int (new));
+ }
+ else if (FLOATP (Vpolling_period))
+ {
+ double new = XFLOAT_DATA (Vpolling_period);
- if (n > new)
- new = n;
+ stop_other_atimers (poll_timer);
+ stop_polling ();
+ specbind (Qpolling_period, (n > new
+ ? make_int (n)
+ : Vpolling_period));
+ }
- stop_other_atimers (poll_timer);
- stop_polling ();
- specbind (Qpolling_period, make_int (new));
/* Start a new alarm with the new period. */
start_polling ();
#endif
@@ -12066,6 +12084,11 @@ syms_of_keyboard (void)
help_form_saved_window_configs = Qnil;
staticpro (&help_form_saved_window_configs);
+#ifdef POLL_FOR_INPUT
+ poll_timer_time = Qnil;
+ staticpro (&poll_timer_time);
+#endif
+
defsubr (&Scurrent_idle_time);
defsubr (&Sevent_symbol_parse_modifiers);
defsubr (&Sevent_convert_list);
@@ -12223,12 +12246,12 @@ The value may be integer or floating point.
If the value is zero, don't echo at all. */);
Vecho_keystrokes = make_fixnum (1);
- DEFVAR_INT ("polling-period", polling_period,
+ DEFVAR_LISP ("polling-period", Vpolling_period,
doc: /* Interval between polling for input during Lisp execution.
The reason for polling is to make C-g work to stop a running program.
Polling is needed only when using X windows and SIGIO does not work.
Polling is automatically disabled in all other cases. */);
- polling_period = 2;
+ Vpolling_period = make_float (2.0);
DEFVAR_LISP ("double-click-time", Vdouble_click_time,
doc: /* Maximum time between mouse clicks to make a double-click.
diff --git a/src/nsterm.m b/src/nsterm.m
index 4f60cc737da..a3c7b55218c 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7071,6 +7071,9 @@ not_in_argv (NSString *arg)
{
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
struct frame *old_focus = dpyinfo->ns_focus_frame;
+ struct input_event event;
+
+ EVENT_INIT (event);
NSTRACE ("[EmacsView windowDidBecomeKey]");
@@ -7079,11 +7082,9 @@ not_in_argv (NSString *arg)
ns_frame_rehighlight (emacsframe);
- if (emacs_event)
- {
- emacs_event->kind = FOCUS_IN_EVENT;
- EV_TRAILER ((id)nil);
- }
+ event.kind = FOCUS_IN_EVENT;
+ XSETFRAME (event.frame_or_window, emacsframe);
+ kbd_buffer_store_event (&event);
}
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index c604e2f1002..9c37c04810c 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -3128,7 +3128,7 @@ x_hide_tip (bool delete)
value of x_gtk_use_system_tooltips might not be the same as used
for the tooltip we have to hide, see Bug#30399. */
if ((NILP (tip_last_frame) && NILP (tip_frame))
- || (!x_gtk_use_system_tooltips
+ || (!use_system_tooltips
&& !delete
&& FRAMEP (tip_frame)
&& FRAME_LIVE_P (XFRAME (tip_frame))
@@ -3161,7 +3161,7 @@ x_hide_tip (bool delete)
/* When using GTK+ system tooltips (compare Bug#41200) reset
tip_last_frame. It will be reassigned when showing the next
GTK+ system tooltip. */
- if (x_gtk_use_system_tooltips)
+ if (use_system_tooltips)
tip_last_frame = Qnil;
/* Now look whether there's an Emacs tip around. */
@@ -3171,7 +3171,7 @@ x_hide_tip (bool delete)
if (FRAME_LIVE_P (f))
{
- if (delete || x_gtk_use_system_tooltips)
+ if (delete || use_system_tooltips)
{
/* Delete the Emacs tooltip frame when DELETE is true
or we change the tooltip type from an Emacs one to
@@ -3267,7 +3267,7 @@ Text larger than the specified size is clipped. */)
else
CHECK_FIXNUM (dy);
- if (x_gtk_use_system_tooltips)
+ if (use_system_tooltips)
{
bool ok;
@@ -4068,12 +4068,6 @@ If more space for files in the file chooser dialog is wanted, set this to nil
to turn the additional text off. */);
x_gtk_file_dialog_help_text = true;
- DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
- doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
-Otherwise use Emacs own tooltip implementation.
-When using Gtk+ tooltips, the tooltip face is not used. */);
- x_gtk_use_system_tooltips = true;
-
DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
doc: /* Maximum size for tooltips.
Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 0155ae991d3..8073f51c610 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -153,10 +153,24 @@ static int
evq_flush (struct input_event *hold_quit)
{
struct event_queue_t *evq = &event_q;
- int i, n = evq->nr;
- for (i = 0; i < n; i++)
- kbd_buffer_store_buffered_event (&evq->q[i], hold_quit);
- evq->nr = 0;
+ int n = 0;
+
+ while (evq->nr > 0)
+ {
+ /* kbd_buffer_store_buffered_event may do longjmp, so
+ we need to shift event queue first and pass the event
+ to kbd_buffer_store_buffered_event so that events in
+ queue are not processed twice. Bug#52941 */
+ union buffered_input_event ev = evq->q[0];
+ int i;
+ for (i = 1; i < evq->nr; i++)
+ evq->q[i - 1] = evq->q[i];
+ evq->nr--;
+
+ kbd_buffer_store_buffered_event (&ev, hold_quit);
+ n++;
+ }
+
return n;
}
@@ -3720,6 +3734,9 @@ pgtk_flash (struct frame *f)
block_input ();
{
+ if (!FRAME_CR_CONTEXT (f))
+ return;
+
cairo_surface_t *surface_orig = FRAME_CR_SURFACE (f);
int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
@@ -7027,13 +7044,12 @@ If set to a non-float value, there will be no wait at all. */);
}
/* Cairo does not allow resizing a surface/context after it is
- * created, so we need to trash the old context, create a new context
- * on the next cr_clip_begin with the new dimensions and request a
- * re-draw.
- *
- * This Will leave the active context available to present on screen
- * until a redrawn frame is completed.
- */
+ created, so we need to trash the old context, create a new context
+ on the next cr_clip_begin with the new dimensions and request a
+ re-draw.
+
+ This will leave the active context available to present on screen
+ until a redrawn frame is completed. */
void
pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height, bool force)
{
diff --git a/src/syntax.c b/src/syntax.c
index 9df878b8edf..13c36fdf3cd 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1101,10 +1101,11 @@ this is probably the wrong function to use, because it can't take
`syntax-after' instead. */)
(Lisp_Object character)
{
- int char_int;
CHECK_CHARACTER (character);
- char_int = XFIXNUM (character);
+ int char_int = XFIXNAT (character);
SETUP_BUFFER_SYNTAX_TABLE ();
+ if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
+ char_int = make_char_multibyte (char_int);
return make_fixnum (syntax_code_spec[SYNTAX (char_int)]);
}
diff --git a/src/verbose.mk.in b/src/verbose.mk.in
index e3f56783031..eb99e426958 100644
--- a/src/verbose.mk.in
+++ b/src/verbose.mk.in
@@ -33,24 +33,45 @@ AM_V_GLOBALS =
AM_V_NO_PD =
AM_V_RC =
else
+
+# Whether $(info ...) works. This is to work around a bug in GNU Make
+# 4.3 and earlier, which implements $(info MSG) via two system calls
+# { write (..., "MSG", 3); write (..., "\n", 1); }
+# which looks bad when make -j interleaves two of these at about the same time.
+#
+# Later versions of GNU Make have the 'notintermediate' feature,
+# so assume that $(info ...) works if this feature is present.
+#
+have_working_info = $(filter notintermediate,$(value .FEATURES))
+#
+# The workaround is to use the shell and 'echo' rather than $(info ...).
+# The workaround is done only for AM_V_ELC and AM_V_ELN,
+# since the bug is not annoying elsewhere.
+
AM_V_AR = @$(info $ AR $@)
AM_V_at = @
AM_V_CC = @$(info $ CC $@)
AM_V_CXX = @$(info $ CXX $@)
AM_V_CCLD = @$(info $ CCLD $@)
AM_V_CXXLD = @$(info $ CXXLD $@)
-ifeq ($(HAVE_NATIVE_COMP),yes)
-ifeq ($(NATIVE_DISABLED),1)
-AM_V_ELC = @$(info $ ELC $@)
-AM_V_ELN =
-else
+
+ifeq ($(HAVE_NATIVE_COMP)-$(NATIVE_DISABLED)-$(ANCIENT),yes--)
+ifdef have_working_info
AM_V_ELC = @$(info $ ELC+ELN $@)
AM_V_ELN = @$(info $ ELN $@)
+else
+AM_V_ELC = @echo " ELC+ELN " $@;
+AM_V_ELN = @echo " ELN " $@;
endif
else
+ifdef have_working_info
AM_V_ELC = @$(info $ ELC $@)
+else
+AM_V_ELC = @echo " ELC " $@;
+endif
AM_V_ELN =
endif
+
AM_V_GEN = @$(info $ GEN $@)
AM_V_GLOBALS = @$(info $ GEN globals.h)
AM_V_NO_PD = --no-print-directory
diff --git a/src/w32font.c b/src/w32font.c
index 0495099db5c..c4a89446b98 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -2385,7 +2385,6 @@ font_supported_scripts (FONTSIGNATURE * sig)
SUBRANGE (108, Qkharoshthi);
SUBRANGE (109, Qtai_xuan_jing_symbol);
SUBRANGE (110, Qcuneiform);
- SUBRANGE (111, Qcuneiform_numbers_and_punctuation);
SUBRANGE (111, Qcounting_rod_numeral);
SUBRANGE (112, Qsundanese);
SUBRANGE (113, Qlepcha);
@@ -2828,8 +2827,6 @@ syms_of_w32font (void)
DEFSYM (Qbuginese, "buginese");
DEFSYM (Qbuhid, "buhid");
DEFSYM (Qcuneiform, "cuneiform");
- DEFSYM (Qcuneiform_numbers_and_punctuation,
- "cuneiform-numbers-and-punctuation");
DEFSYM (Qcypriot, "cypriot");
DEFSYM (Qdeseret, "deseret");
DEFSYM (Qglagolitic, "glagolitic");
diff --git a/src/xdisp.c b/src/xdisp.c
index 977d31703fb..c695e466e78 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -19157,7 +19157,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
struct glyph_row *row;
row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
- while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
+ while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos
+ && !row->ends_at_zv_p)
++row;
TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
diff --git a/src/xfaces.c b/src/xfaces.c
index 8064d47c947..6a279f87192 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3165,14 +3165,15 @@ FRAME 0 means change the face on all frames, and change the default
*/
valid_p = true;
- while (!NILP (CAR_SAFE(list)))
+ while (!NILP (CAR_SAFE (list)))
{
key = CAR_SAFE (list);
list = CDR_SAFE (list);
val = CAR_SAFE (list);
list = CDR_SAFE (list);
- if (NILP (key) || NILP (val))
+ if (NILP (key) || (NILP (val)
+ && !EQ (key, QCposition)))
{
valid_p = false;
break;
@@ -6423,8 +6424,12 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
cached faces since we've looked up these faces, we need to look
them up again. */
if (!default_face)
- default_face = FACE_FROM_ID (f,
- lookup_basic_face (w, f, DEFAULT_FACE_ID));
+ {
+ if (FRAME_FACE_CACHE (f)->used == 0)
+ recompute_basic_faces (f);
+ default_face = FACE_FROM_ID (f,
+ lookup_basic_face (w, f, DEFAULT_FACE_ID));
+ }
}
/* Optimize common cases where we can use the default face. */
diff --git a/src/xfns.c b/src/xfns.c
index ffad0bc3d1a..7123198724a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -40,6 +40,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef USE_XCB
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_aux.h>
+#endif
+
#include "bitmaps/gray.xbm"
#include "xsettings.h"
@@ -2643,11 +2649,7 @@ best_xim_style (struct x_display_info *dpyinfo,
int nr_supported = ARRAYELTS (supported_xim_styles);
if (dpyinfo->preferred_xim_style)
- {
- for (j = 0; j < xim->count_styles; ++j)
- if (dpyinfo->preferred_xim_style == xim->supported_styles[j])
- return dpyinfo->preferred_xim_style;
- }
+ return dpyinfo->preferred_xim_style;
for (i = 0; i < nr_supported; ++i)
for (j = 0; j < xim->count_styles; ++j)
@@ -3049,7 +3051,7 @@ x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length)
}
nbytes = strlen (text->string.multi_byte);
- setup_coding_system (Qutf_8_unix, &coding);
+ setup_coding_system (Vlocale_coding_system, &coding);
coding.mode |= (CODING_MODE_LAST_BLOCK
| CODING_MODE_SAFE_ENCODING);
coding.source = (const unsigned char *) text->string.multi_byte;
@@ -6486,7 +6488,11 @@ void
x_sync (struct frame *f)
{
block_input ();
+#ifndef USE_XCB
XSync (FRAME_X_DISPLAY (f), False);
+#else
+ xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
+#endif
unblock_input ();
}
@@ -7107,6 +7113,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
gui_figure_window_size (f, parms, false, false);
{
+#ifndef USE_XCB
XSetWindowAttributes attrs;
unsigned long mask;
Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
@@ -7143,6 +7150,47 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
XA_ATOM, 32, PropModeReplace,
(unsigned char *)&type, 1);
unblock_input ();
+#else
+ uint32_t value_list[4];
+ xcb_atom_t net_wm_window_type_tooltip
+ = (xcb_atom_t) dpyinfo->Xatom_net_window_type_tooltip;
+
+ f->output_data.x->current_cursor = f->output_data.x->text_cursor;
+ /* Values are set in the order of their enumeration in `enum
+ xcb_cw_t'. */
+ value_list[0] = FRAME_BACKGROUND_PIXEL (f);
+ value_list[1] = true;
+ value_list[2] = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+ value_list[3] = (xcb_cursor_t) f->output_data.x->text_cursor;
+
+ block_input ();
+ tip_window
+ = FRAME_X_WINDOW (f)
+ = (Window) xcb_generate_id (dpyinfo->xcb_connection);
+
+ xcb_create_window (dpyinfo->xcb_connection,
+ XCB_COPY_FROM_PARENT,
+ (xcb_window_t) tip_window,
+ (xcb_window_t) dpyinfo->root_window,
+ 0, 0, 1, 1, f->border_width,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ XCB_COPY_FROM_PARENT,
+ (XCB_CW_BACK_PIXEL
+ | XCB_CW_OVERRIDE_REDIRECT
+ | XCB_CW_EVENT_MASK
+ | XCB_CW_CURSOR),
+ &value_list);
+
+ xcb_change_property (dpyinfo->xcb_connection,
+ XCB_PROP_MODE_REPLACE,
+ (xcb_window_t) tip_window,
+ (xcb_atom_t) dpyinfo->Xatom_net_window_type,
+ (xcb_atom_t) dpyinfo->Xatom_ATOM,
+ 32, 1, &net_wm_window_type_tooltip);
+
+ initial_set_up_x_back_buffer (f);
+ unblock_input ();
+#endif
}
x_make_gc (f);
@@ -7361,13 +7409,13 @@ x_hide_tip (bool delete)
}
#ifdef USE_GTK
- /* Any GTK+ system tooltip can be found via the x_output structure of
- tip_last_frame, provided that frame is still live. Any Emacs
- tooltip is found via the tip_frame variable. Note that the current
- value of x_gtk_use_system_tooltips might not be the same as used
- for the tooltip we have to hide, see Bug#30399. */
+ /* Any GTK+ system tooltip can be found via the x_output structure
+ of tip_last_frame, provided that frame is still live. Any Emacs
+ tooltip is found via the tip_frame variable. Note that the
+ current value of use_system_tooltips might not be the same as
+ used for the tooltip we have to hide, see Bug#30399. */
if ((NILP (tip_last_frame) && NILP (tip_frame))
- || (!x_gtk_use_system_tooltips
+ || (!use_system_tooltips
&& !delete
&& !NILP (tip_frame)
&& FRAME_LIVE_P (XFRAME (tip_frame))
@@ -7400,7 +7448,7 @@ x_hide_tip (bool delete)
/* When using GTK+ system tooltips (compare Bug#41200) reset
tip_last_frame. It will be reassigned when showing the next
GTK+ system tooltip. */
- if (x_gtk_use_system_tooltips)
+ if (use_system_tooltips)
tip_last_frame = Qnil;
/* Now look whether there's an Emacs tip around. */
@@ -7410,7 +7458,7 @@ x_hide_tip (bool delete)
if (FRAME_LIVE_P (f))
{
- if (delete || x_gtk_use_system_tooltips)
+ if (delete || use_system_tooltips)
{
/* Delete the Emacs tooltip frame when DELETE is true
or we change the tooltip type from an Emacs one to
@@ -7569,7 +7617,7 @@ Text larger than the specified size is clipped. */)
CHECK_FIXNUM (dy);
#ifdef USE_GTK
- if (x_gtk_use_system_tooltips)
+ if (use_system_tooltips)
{
bool ok;
@@ -7765,9 +7813,23 @@ Text larger than the specified size is clipped. */)
/* Show tooltip frame. */
block_input ();
+#ifndef USE_XCB
XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
root_x, root_y, width, height);
XMapRaised (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f));
+#else
+ uint32_t values[] = { root_x, root_y, width, height, XCB_STACK_MODE_ABOVE };
+
+ xcb_configure_window (FRAME_DISPLAY_INFO (tip_f)->xcb_connection,
+ (xcb_window_t) FRAME_X_WINDOW (tip_f),
+ (XCB_CONFIG_WINDOW_X
+ | XCB_CONFIG_WINDOW_Y
+ | XCB_CONFIG_WINDOW_WIDTH
+ | XCB_CONFIG_WINDOW_HEIGHT
+ | XCB_CONFIG_WINDOW_STACK_MODE), &values);
+ xcb_map_window (FRAME_DISPLAY_INFO (tip_f)->xcb_connection,
+ (xcb_window_t) FRAME_X_WINDOW (tip_f));
+#endif
unblock_input ();
#ifdef USE_CAIRO
@@ -8651,12 +8713,6 @@ If more space for files in the file chooser dialog is wanted, set this to nil
to turn the additional text off. */);
x_gtk_file_dialog_help_text = true;
- DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
- doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
-Otherwise use Emacs own tooltip implementation.
-When using Gtk+ tooltips, the tooltip face is not used. */);
- x_gtk_use_system_tooltips = true;
-
DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
doc: /* If non-nil, resize child frames specially with GTK builds.
If this is nil, resize child frames like any other frames. This is the
diff --git a/src/xsettings.h b/src/xsettings.h
index 266526df101..ccaa36489d0 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -21,15 +21,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define XSETTINGS_H
#ifndef HAVE_PGTK
+#include "dispextern.h"
#include <X11/Xlib.h>
#endif
struct x_display_info;
struct pgtk_display_info;
-#ifndef HAVE_PGTK
-typedef struct x_display_info Display_Info;
-#else
+#ifdef HAVE_PGTK
typedef struct pgtk_display_info Display_Info;
#endif
diff --git a/src/xterm.c b/src/xterm.c
index ec415f5ffaf..36e0045d2ed 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -99,6 +99,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "xterm.h"
#include <X11/cursorfont.h>
+#ifdef USE_XCB
+#include <xcb/xproto.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#endif
+
/* If we have Xfixes extension, use it for pointer blanking. */
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
@@ -167,6 +173,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "../lwlib/xlwmenu.h"
#endif
+#ifdef HAVE_XWIDGETS
+#include <cairo-xlib.h>
+#endif
+
#ifdef USE_X_TOOLKIT
/* Include toolkit specific headers for the scroll bar widget. */
@@ -206,6 +216,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <X11/XKBlib.h>
#endif
+#if defined USE_XCB && defined USE_CAIRO_XCB
+#define USE_CAIRO_XCB_SURFACE
+#endif
+
/* Default to using XIM if available. */
#ifdef USE_XIM
bool use_xim = true;
@@ -777,11 +791,19 @@ x_begin_cr_clip (struct frame *f, GC gc)
{
int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
- cairo_surface_t *surface
- = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
- FRAME_X_RAW_DRAWABLE (f),
- FRAME_X_VISUAL (f),
- width, height);
+ cairo_surface_t *surface;
+#ifdef USE_CAIRO_XCB_SURFACE
+ if (FRAME_DISPLAY_INFO (f)->xcb_visual)
+ surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f),
+ FRAME_DISPLAY_INFO (f)->xcb_visual,
+ width, height);
+ else
+#endif
+ surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
+ FRAME_X_RAW_DRAWABLE (f),
+ FRAME_X_VISUAL (f),
+ width, height);
cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
cairo_surface_destroy (surface);
@@ -850,6 +872,9 @@ x_try_cr_xlib_drawable (struct frame *f, GC gc)
switch (cairo_surface_get_type (surface))
{
case CAIRO_SURFACE_TYPE_XLIB:
+#ifdef USE_CAIRO_XCB_SURFACE
+ case CAIRO_SURFACE_TYPE_XCB:
+#endif
cairo_surface_flush (surface);
return true;
@@ -1262,11 +1287,15 @@ x_clear_window (struct frame *f)
cairo_paint (cr);
x_end_cr_clip (f);
#else
+#ifndef USE_GTK
if (FRAME_X_DOUBLE_BUFFERED_P (f))
+#endif
x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+#ifndef USE_GTK
else
XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif
+#endif
}
#ifdef USE_CAIRO
@@ -2768,8 +2797,9 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
and names we've actually looked up; list-colors-display is probably
the most color-intensive case we're likely to hit. */
-Status x_parse_color (struct frame *f, const char *color_name,
- XColor *color)
+Status
+x_parse_color (struct frame *f, const char *color_name,
+ XColor *color)
{
/* Don't pass #RGB strings directly to XParseColor, because that
follows the X convention of zero-extending each channel
@@ -2798,6 +2828,10 @@ Status x_parse_color (struct frame *f, const char *color_name,
}
}
+ /* Some X servers send BadValue on empty color names. */
+ if (!strlen (color_name))
+ return 0;
+
if (XParseColor (dpy, cmap, color_name, color) == 0)
/* No caching of negative results, currently. */
return 0;
@@ -4473,15 +4507,19 @@ x_clear_area (struct frame *f, int x, int y, int width, int height)
cairo_fill (cr);
x_end_cr_clip (f);
#else
+#ifndef USE_GTK
if (FRAME_X_DOUBLE_BUFFERED_P (f))
+#endif
XFillRectangle (FRAME_X_DISPLAY (f),
FRAME_X_DRAWABLE (f),
f->output_data.x->reverse_gc,
x, y, width, height);
+#ifndef USE_GTK
else
x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
x, y, width, height, False);
#endif
+#endif
}
@@ -4528,6 +4566,7 @@ x_show_hourglass (struct frame *f)
if (!x->hourglass_window)
{
+#ifndef USE_XCB
unsigned long mask = CWCursor;
XSetWindowAttributes attrs;
#ifdef USE_GTK
@@ -4540,12 +4579,41 @@ x_show_hourglass (struct frame *f)
x->hourglass_window = XCreateWindow
(dpy, parent, 0, 0, 32000, 32000, 0, 0,
InputOnly, CopyFromParent, mask, &attrs);
+#else
+ uint32_t cursor = (uint32_t) x->hourglass_cursor;
+#ifdef USE_GTK
+ xcb_window_t parent = (xcb_window_t) FRAME_X_WINDOW (f);
+#else
+ xcb_window_t parent = (xcb_window_t) FRAME_OUTER_WINDOW (f);
+#endif
+ x->hourglass_window
+ = (Window) xcb_generate_id (FRAME_DISPLAY_INFO (f)->xcb_connection);
+
+ xcb_create_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ XCB_COPY_FROM_PARENT,
+ (xcb_window_t) x->hourglass_window,
+ parent, 0, 0, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f), 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ XCB_COPY_FROM_PARENT, XCB_CW_CURSOR,
+ &cursor);
+#endif
}
+#ifndef USE_XCB
XMapRaised (dpy, x->hourglass_window);
- XFlush (dpy);
/* Ensure that the spinning hourglass is shown. */
flush_frame (f);
+#else
+ uint32_t value = XCB_STACK_MODE_ABOVE;
+
+ xcb_configure_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_window_t) x->hourglass_window,
+ XCB_CONFIG_WINDOW_STACK_MODE, &value);
+ xcb_map_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_window_t) x->hourglass_window);
+ xcb_flush (FRAME_DISPLAY_INFO (f)->xcb_connection);
+#endif
}
}
}
@@ -4560,10 +4628,16 @@ x_hide_hourglass (struct frame *f)
/* Watch out for newly created frames. */
if (x->hourglass_window)
{
+#ifndef USE_XCB
XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
/* Sync here because XTread_socket looks at the
hourglass_p flag that is reset to zero below. */
XSync (FRAME_X_DISPLAY (f), False);
+#else
+ xcb_unmap_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_window_t) x->hourglass_window);
+ xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
+#endif
x->hourglass_p = false;
}
}
@@ -4576,38 +4650,6 @@ XTflash (struct frame *f)
block_input ();
{
-#ifdef USE_GTK
- /* Use Gdk routines to draw. This way, we won't draw over scroll bars
- when the scroll bars and the edit widget share the same X window. */
- GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
-#ifdef HAVE_GTK3
-#if GTK_CHECK_VERSION (3, 22, 0)
- cairo_region_t *region = gdk_window_get_visible_region (window);
- GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
- cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
-#else
- cairo_t *cr = gdk_cairo_create (window);
-#endif
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
-#define XFillRectangle(d, win, gc, x, y, w, h) \
- do { \
- cairo_rectangle (cr, x, y, w, h); \
- cairo_fill (cr); \
- } \
- while (false)
-#else /* ! HAVE_GTK3 */
- GdkGCValues vals;
- GdkGC *gc;
- vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
- ^ FRAME_BACKGROUND_PIXEL (f));
- vals.function = GDK_XOR;
- gc = gdk_gc_new_with_values (window,
- &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
-#define XFillRectangle(d, win, gc, x, y, w, h) \
- gdk_draw_rectangle (window, gc, true, x, y, w, h)
-#endif /* ! HAVE_GTK3 */
-#else /* ! USE_GTK */
GC gc;
/* Create a GC that will use the GXxor function to flip foreground
@@ -4622,7 +4664,6 @@ XTflash (struct frame *f)
gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCFunction | GCForeground, &values);
}
-#endif
{
/* Get the height not including a menu bar widget. */
int height = FRAME_PIXEL_HEIGHT (f);
@@ -4698,22 +4739,7 @@ XTflash (struct frame *f)
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
-
-#ifdef USE_GTK
-#ifdef HAVE_GTK3
-#if GTK_CHECK_VERSION (3, 22, 0)
- gdk_window_end_draw_frame (window, context);
- cairo_region_destroy (region);
-#else
- cairo_destroy (cr);
-#endif
-#else
- g_object_unref (G_OBJECT (gc));
-#endif
-#undef XFillRectangle
-#else
XFreeGC (FRAME_X_DISPLAY (f), gc);
-#endif
x_flush (f);
}
}
@@ -4921,6 +4947,18 @@ x_scroll_run (struct window *w, struct run *run)
x, to_y);
cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
}
+#ifdef USE_CAIRO_XCB_SURFACE
+ else if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XCB)
+ {
+ cairo_surface_flush (surface);
+ xcb_copy_area (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_drawable_t) FRAME_X_DRAWABLE (f),
+ (xcb_drawable_t) FRAME_X_DRAWABLE (f),
+ (xcb_gcontext_t) XGContextFromGC (f->output_data.x->normal_gc),
+ x, from_y, x, to_y, width, height);
+ cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
+ }
+#endif
else
{
cairo_surface_t *s
@@ -5436,11 +5474,6 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
int syms_per_code;
XModifierKeymap *mods;
#ifdef HAVE_XKB
- Atom meta;
- Atom super;
- Atom hyper;
- Atom shiftlock;
- Atom alt;
int i;
int found_meta_p = false;
#endif
@@ -5454,28 +5487,22 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
#ifdef HAVE_XKB
if (dpyinfo->xkb_desc)
{
- meta = XInternAtom (dpyinfo->display, "Meta", False);
- super = XInternAtom (dpyinfo->display, "Super", False);
- hyper = XInternAtom (dpyinfo->display, "Hyper", False);
- shiftlock = XInternAtom (dpyinfo->display, "ShiftLock", False);
- alt = XInternAtom (dpyinfo->display, "Alt", False);
-
for (i = 0; i < XkbNumVirtualMods; i++)
{
uint vmodmask = dpyinfo->xkb_desc->server->vmods[i];
- if (dpyinfo->xkb_desc->names->vmods[i] == meta)
+ if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Meta)
{
dpyinfo->meta_mod_mask |= vmodmask;
found_meta_p = vmodmask;
}
- else if (dpyinfo->xkb_desc->names->vmods[i] == alt)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Alt)
dpyinfo->alt_mod_mask |= vmodmask;
- else if (dpyinfo->xkb_desc->names->vmods[i] == super)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Super)
dpyinfo->super_mod_mask |= vmodmask;
- else if (dpyinfo->xkb_desc->names->vmods[i] == hyper)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Hyper)
dpyinfo->hyper_mod_mask |= vmodmask;
- else if (dpyinfo->xkb_desc->names->vmods[i] == shiftlock)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_ShiftLock)
dpyinfo->shift_lock_mask |= vmodmask;
}
@@ -8373,6 +8400,7 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
#ifdef USE_GTK
}
else if (f1 && (event->type == KeyPress
+ || event->type == KeyRelease
#ifdef HAVE_XINPUT2
|| xinput_event
#endif
@@ -8384,6 +8412,11 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
result = xg_filter_key (f1, event);
unblock_input ();
+ if (result && f1)
+ /* There will probably be a GDK event generated soon, so
+ exercise the wire to make pselect return. */
+ XNoOp (FRAME_X_DISPLAY (f1));
+
return result;
}
@@ -8434,8 +8467,10 @@ event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
&& xev->type == GenericEvent
&& (xev->xgeneric.extension
== dpyinfo->xi2_opcode)
- && (xev->xgeneric.evtype
- == XI_KeyPress))
+ && ((xev->xgeneric.evtype
+ == XI_KeyPress)
+ || (xev->xgeneric.evtype
+ == XI_KeyRelease)))
#endif
))
{
@@ -8947,12 +8982,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (!FRAME_VISIBLE_P (f))
{
block_input ();
- /* The following two are commented out to avoid that a
- plain invisible frame gets reported as iconified. That
- problem occurred first for Emacs 26 and is described in
- https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. */
-/** SET_FRAME_VISIBLE (f, 1); **/
-/** SET_FRAME_ICONIFIED (f, false); **/
+ /* By default, do not set the frame's visibility here, see
+ https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
+ The default behavior can be overridden by setting
+ 'x-set-frame-visibility-more-laxly' (Bug#49955,
+ Bug#53298). */
+ if (EQ (x_set_frame_visibility_more_laxly, Qexpose)
+ || EQ (x_set_frame_visibility_more_laxly, Qt))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ }
if (FRAME_X_DOUBLE_BUFFERED_P (f))
font_drop_xrender_surfaces (f);
@@ -9236,7 +9276,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
int modifiers;
Lisp_Object coding_system = Qlatin_1;
Lisp_Object c;
- /* Event will be modified. */
+ /* `xkey' will be modified, but it's not important to modify
+ `event' itself. */
XKeyEvent xkey = event->xkey;
#ifdef USE_GTK
@@ -9498,8 +9539,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (keysym == NoSymbol)
break;
}
- /* FIXME: check side effects and remove this. */
- ((XEvent *) event)->xkey = xkey;
}
done_keysym:
#ifdef HAVE_X_I18N
@@ -9571,26 +9610,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
goto OTHER;
case FocusIn:
-#ifndef USE_GTK
+#ifdef USE_GTK
/* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
minimized/iconified windows; thus, for those WMs we won't get
- a MapNotify when unminimizing/deconifying. Check here if we
+ a MapNotify when unminimizing/deiconifying. Check here if we
are deiconizing a window (Bug42655).
- But don't do that on GTK since it may cause a plain invisible
- frame get reported as iconified, compare
+ But don't do that by default on GTK since it may cause a plain
+ invisible frame get reported as iconified, compare
https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
- That is fixed above but bites us here again. */
- f = any;
- if (f && FRAME_ICONIFIED_P (f))
- {
- SET_FRAME_VISIBLE (f, 1);
- SET_FRAME_ICONIFIED (f, false);
- f->output_data.x->has_been_visible = true;
- inev.ie.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.ie.frame_or_window, f);
- }
+ That is fixed above but bites us here again.
+
+ The option x_set_frame_visibility_more_laxly allows to override
+ the default behavior (Bug#49955, Bug#53298). */
+ if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
+ || EQ (x_set_frame_visibility_more_laxly, Qt))
#endif /* USE_GTK */
+ {
+ f = any;
+ if (f && FRAME_ICONIFIED_P (f))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ f->output_data.x->has_been_visible = true;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+ }
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
goto OTHER;
@@ -10194,26 +10240,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
case XI_FocusIn:
any = x_any_window_to_frame (dpyinfo, focusin->event);
-#ifndef USE_GTK
+#ifdef USE_GTK
/* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
minimized/iconified windows; thus, for those WMs we won't get
- a MapNotify when unminimizing/deconifying. Check here if we
+ a MapNotify when unminimizing/deiconifying. Check here if we
are deiconizing a window (Bug42655).
- But don't do that on GTK since it may cause a plain invisible
- frame get reported as iconified, compare
+ But don't do that by default on GTK since it may cause a plain
+ invisible frame get reported as iconified, compare
https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
- That is fixed above but bites us here again. */
- f = any;
- if (f && FRAME_ICONIFIED_P (f))
+ That is fixed above but bites us here again.
+
+ The option x_set_frame_visibility_more_laxly allows to override
+ the default behavior (Bug#49955, Bug#53298). */
+ if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
+ || EQ (x_set_frame_visibility_more_laxly, Qt))
+#endif /* USE_GTK */
{
- SET_FRAME_VISIBLE (f, 1);
- SET_FRAME_ICONIFIED (f, false);
- f->output_data.x->has_been_visible = true;
- inev.ie.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.ie.frame_or_window, f);
+ f = any;
+ if (f && FRAME_ICONIFIED_P (f))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ f->output_data.x->has_been_visible = true;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
}
-#endif /* USE_GTK */
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
goto XI_OTHER;
case XI_FocusOut:
@@ -10708,7 +10761,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (f && xev->evtype == XI_ButtonPress
&& !popup_activated ()
- && !x_window_to_scroll_bar (xev->display, xev->event, 2)
+ && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
&& !FRAME_NO_ACCEPT_FOCUS (f))
{
/* When clicking into a child frame or when clicking
@@ -10881,7 +10934,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xkey.type = KeyPress;
xkey.serial = xev->serial;
xkey.send_event = xev->send_event;
- xkey.display = xev->display;
+ xkey.display = dpyinfo->display;
xkey.window = xev->event;
xkey.root = xev->root;
xkey.subwindow = xev->child;
@@ -11227,7 +11280,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xkey.type = KeyRelease;
xkey.serial = xev->serial;
xkey.send_event = xev->send_event;
- xkey.display = xev->display;
+ xkey.display = dpyinfo->display;
xkey.window = xev->event;
xkey.root = xev->root;
xkey.subwindow = xev->child;
@@ -11523,8 +11576,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
dpyinfo->xkb_desc = NULL;
}
-
- x_find_modifier_meanings (dpyinfo);
}
else
{
@@ -11542,6 +11593,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
XkbRefreshKeyboardMapping (&xkbevent->map);
+ x_find_modifier_meanings (dpyinfo);
}
}
#endif
@@ -12698,9 +12750,11 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
ret = XRegisterIMInstantiateCallback
(dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
emacs_class, xim_instantiate_callback,
- /* This is XPointer in XFree86 but (XPointer *)
- on Tru64, at least, hence the configure test. */
- (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ /* This is XPointer in XFree86 but (XPointer *) on Tru64, at
+ least, but the configure test doesn't work because
+ xim_instantiate_callback can either be XIMProc or
+ XIDProc, so just cast to void *. */
+ (void *) xim_inst);
eassert (ret == True);
#else /* not HAVE_X11R6_XIM */
xim_open_dpy (dpyinfo, resource_name);
@@ -12725,8 +12779,7 @@ xim_close_dpy (struct x_display_info *dpyinfo)
{
Bool ret = XUnregisterIMInstantiateCallback
(dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
- emacs_class, xim_instantiate_callback,
- (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ emacs_class, xim_instantiate_callback, (void *) xim_inst);
eassert (ret == True);
}
xfree (xim_inst->resource_name);
@@ -15261,6 +15314,40 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
dpyinfo->supports_xdbe = true;
#endif
+#ifdef USE_XCB
+ xcb_screen_t *xcb_screen = NULL;
+ xcb_screen_iterator_t iter;
+ xcb_visualid_t wanted = { XVisualIDFromVisual (dpyinfo->visual) };
+ xcb_depth_iterator_t depth_iter;
+ xcb_visualtype_iterator_t visual_iter;
+
+ int screen = DefaultScreen (dpyinfo->display);
+
+ iter = xcb_setup_roots_iterator (xcb_get_setup (dpyinfo->xcb_connection));
+ for (; iter.rem; --screen, xcb_screen_next (&iter))
+ {
+ if (!screen)
+ xcb_screen = iter.data;
+ }
+
+ if (xcb_screen)
+ {
+ depth_iter = xcb_screen_allowed_depths_iterator (xcb_screen);
+ for (; depth_iter.rem; xcb_depth_next (&depth_iter))
+ {
+ visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
+ for (; visual_iter.rem; xcb_visualtype_next (&visual_iter))
+ {
+ if (wanted == visual_iter.data->visual_id)
+ {
+ dpyinfo->xcb_visual = visual_iter.data;
+ break;
+ }
+ }
+ }
+ }
+#endif
+
#ifdef HAVE_XINPUT2
dpyinfo->supports_xi2 = false;
int rc;
@@ -15329,9 +15416,19 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
}
+#endif
- /* Figure out which modifier bits mean what. */
- x_find_modifier_meanings (dpyinfo);
+#ifdef HAVE_XRENDER
+ int event_base, error_base;
+ dpyinfo->xrender_supported_p
+ = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
+
+ if (dpyinfo->xrender_supported_p)
+ {
+ if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
+ &dpyinfo->xrender_minor))
+ dpyinfo->xrender_supported_p = false;
+ }
#endif
#if defined USE_CAIRO || defined HAVE_XFT
@@ -15350,11 +15447,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
or larger than other for other applications, even if it is the same
font name (monospace-10 for example). */
-# ifdef HAVE_XRENDER
- int event_base, error_base;
- XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
-# endif
-
char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
double d;
if (v != NULL && sscanf (v, "%lf", &d) == 1)
@@ -15447,6 +15539,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar)
ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
+#ifdef HAVE_XKB
+ ATOM_REFS_INIT ("Meta", Xatom_Meta)
+ ATOM_REFS_INIT ("Super", Xatom_Super)
+ ATOM_REFS_INIT ("Hyper", Xatom_Hyper)
+ ATOM_REFS_INIT ("ShiftLock", Xatom_ShiftLock)
+ ATOM_REFS_INIT ("Alt", Xatom_Alt)
+#endif
};
int i;
@@ -15477,6 +15576,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
dpyinfo->Xatom_xsettings_sel = atoms_return[i];
}
+#ifdef HAVE_XKB
+ /* Figure out which modifier bits mean what. */
+ x_find_modifier_meanings (dpyinfo);
+#endif
+
dpyinfo->x_dnd_atoms_size = 8;
dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
* dpyinfo->x_dnd_atoms_size);
@@ -16128,6 +16232,7 @@ always uses gtk_window_move and ignores the value of this variable. */);
This option is only effective when Emacs is built with XInput 2
support. */);
Vx_scroll_event_delta_factor = make_float (1.0);
+ DEFSYM (Qexpose, "expose");
DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input,
doc: /* Non-nil means to use GTK for input method support.
@@ -16135,6 +16240,21 @@ This provides better support for some modern input methods, and is
only effective when Emacs is built with GTK. */);
x_gtk_use_native_input = false;
+ DEFVAR_LISP ("x-set-frame-visibility-more-laxly",
+ x_set_frame_visibility_more_laxly,
+ doc: /* Non-nil means set frame visibility more laxly.
+If this is nil, Emacs is more strict when marking a frame as visible.
+Since this may cause problems on some window managers, this variable can
+be also set as follows: The value `focus-in' means to mark a frame as
+visible also when a FocusIn event is received for it on GTK builds. The
+value `expose' means to mark a frame as visible also when an Expose
+event is received for it on any X build. The value `t' means to mark a
+frame as visible in either of these two cases.
+
+Note that any non-nil setting may cause invisible frames get erroneously
+reported as iconified. */);
+ x_set_frame_visibility_more_laxly = Qnil;
+
DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events,
doc: /* Non-nil means to actively grab touch events.
This means touch sequences that started on an Emacs frame will
diff --git a/src/xterm.h b/src/xterm.h
index 664db48392d..26b2851590d 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -78,6 +78,9 @@ typedef GtkWidget *xt_or_gtk_widget;
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
#endif
+#ifdef USE_CAIRO_XCB
+#include <cairo-xcb.h>
+#endif
#endif
#ifdef HAVE_X_I18N
@@ -496,6 +499,11 @@ struct x_display_info
/* SM */
Atom Xatom_SM_CLIENT_ID;
+#ifdef HAVE_XKB
+ /* Virtual modifiers */
+ Atom Xatom_Meta, Xatom_Super, Xatom_Hyper, Xatom_ShiftLock, Xatom_Alt;
+#endif
+
#ifdef HAVE_XRANDR
int xrandr_major_version;
int xrandr_minor_version;
@@ -507,6 +515,7 @@ struct x_display_info
#ifdef USE_XCB
xcb_connection_t *xcb_connection;
+ xcb_visualtype_t *xcb_visual;
#endif
#ifdef HAVE_XDBE
@@ -531,6 +540,12 @@ struct x_display_info
#ifdef USE_GTK
bool prefer_native_input;
#endif
+
+#ifdef HAVE_XRENDER
+ bool xrender_supported_p;
+ int xrender_major;
+ int xrender_minor;
+#endif
};
#ifdef HAVE_X_I18N
diff --git a/src/xwidget.c b/src/xwidget.c
index 45879b15cbe..fb66a17acd8 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <webkit2/webkit2.h>
#include <JavaScriptCore/JavaScript.h>
#include <cairo.h>
+#include <cairo-xlib.h>
#ifndef HAVE_PGTK
#include <X11/Xlib.h>
#else
@@ -1855,7 +1856,7 @@ webkit_js_to_lisp (JSCValue *value)
const gint32 dlen = jsc_value_to_int32 (len);
Lisp_Object obj;
- if (! (0 <= dlen && dlen < PTRDIFF_MAX + 1.0))
+ if (! (0 <= dlen && dlen < G_MAXINT32))
memory_full (SIZE_MAX);
ptrdiff_t n = dlen;