static int toolkit_scroll_bar_interaction;
+/* Non-zero means to not move point as a result of clicking on a
+ frame to focus it (when focus-follows-mouse is nil). */
+
+int x_mouse_click_focus_ignore_position;
+
+/* Non-zero timeout value means ignore next mouse click if it arrives
+ before that timeout elapses (i.e. as part of the same sequence of
+ events resulting from clicking on a frame to select it). */
+
+static unsigned long ignore_next_mouse_click_timeout;
+
/* Mouse movement.
Formerly, we used PointerMotionHintMask (in standard_event_mask)
if (p->overlay_p)
{
- clipmask = XCreatePixmapFromBitmapData (display,
+ clipmask = XCreatePixmapFromBitmapData (display,
FRAME_X_DISPLAY_INFO (f)->root_window,
- bits, p->wd, p->h,
+ bits, p->wd, p->h,
1, 0, 1);
gcv.clip_mask = clipmask;
gcv.clip_x_origin = p->x;
- gcv.clip_y_origin = p->y;
+ gcv.clip_y_origin = p->y;
XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
}
else
{
current_count +=
- handle_one_xevent (dpyinfo, xev, ¤t_finish,
+ handle_one_xevent (dpyinfo, xev, ¤t_finish,
current_hold_quit);
}
}
case KeyPress:
+ ignore_next_mouse_click_timeout = 0;
+
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Dispatch KeyPress events when in menu. */
if (popup_activated ())
if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
{
- dpyinfo->mouse_face_hidden = 1;
clear_mouse_face (dpyinfo);
+ dpyinfo->mouse_face_hidden = 1;
}
#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
Lisp_Object coding_system = Qlatin_1;
Lisp_Object c;
+#ifdef USE_GTK
+ /* Don't pass keys to GTK. A Tab will shift focus to the
+ tool bar in GTK 2.4. Keys will still go to menus and
+ dialogs because in that case popup_activated is TRUE
+ (see above). */
+ *finish = X_EVENT_DROP;
+#endif
+
event.xkey.state
|= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
extra_keyboard_modifiers);
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
+ if (f && x_mouse_click_focus_ignore_position)
+ ignore_next_mouse_click_timeout = event.xmotion.time + 200;
+
#if 0
if (event.xcrossing.focus)
{
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (! popup_activated ())
#endif
- construct_mouse_click (&inev, &event, f);
+ {
+ if (ignore_next_mouse_click_timeout)
+ {
+ if (event.type == ButtonPress
+ && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
+ {
+ ignore_next_mouse_click_timeout = 0;
+ construct_mouse_click (&inev, &event, f);
+ }
+ if (event.type == ButtonRelease)
+ ignore_next_mouse_click_timeout = 0;
+ }
+ else
+ construct_mouse_click (&inev, &event, f);
+ }
}
}
else
any_help_event_p = 1;
gen_help_event (help_echo_string, frame, help_echo_window,
help_echo_object, help_echo_pos);
- }
+ }
else
{
help_echo_string = Qnil;
Window child;
int win_x = 0, win_y = 0;
int flags = f->size_hint_flags;
- int this_window;
/* We have nothing to do if the current position
is already for the top-left corner. */
if (! ((flags & XNegative) || (flags & YNegative)))
return;
- this_window = FRAME_OUTER_WINDOW (f);
-
- /* Find the position of the outside upper-left corner of
+ /* Find the offsets of the outside upper-left corner of
the inner window, with respect to the outer window.
But do this only if we will need the results. */
if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
- {
- int count;
-
- BLOCK_INPUT;
- count = x_catch_errors (FRAME_X_DISPLAY (f));
- while (1)
- {
- x_clear_errors (FRAME_X_DISPLAY (f));
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
-
- /* From-window, to-window. */
- this_window,
- f->output_data.x->parent_desc,
-
- /* From-position, to-position. */
- 0, 0, &win_x, &win_y,
-
- /* Child of win. */
- &child);
- if (x_had_errors_p (FRAME_X_DISPLAY (f)))
- {
- Window newroot, newparent = 0xdeadbeef;
- Window *newchildren;
- unsigned int nchildren;
-
- if (! XQueryTree (FRAME_X_DISPLAY (f), this_window, &newroot,
- &newparent, &newchildren, &nchildren))
- break;
-
- XFree ((char *) newchildren);
-
- f->output_data.x->parent_desc = newparent;
- }
- else
- break;
- }
-
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
- UNBLOCK_INPUT;
- }
+ /* This is to get *_pixels_outer_diff. */
+ x_real_positions (f, &win_x, &win_y);
/* Treat negative positions as relative to the leftmost bottommost
position that fits on the screen. */
if (flags & XNegative)
f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
- - 2 * f->border_width - win_x
+ - 2 * FRAME_X_OUTPUT (f)->x_pixels_outer_diff
- FRAME_PIXEL_WIDTH (f)
+ f->left_pos);
if (flags & YNegative)
f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
- - 2 * f->border_width
- - win_y
+ - FRAME_X_OUTPUT (f)->y_pixels_outer_diff
+
+ /* Assume the window manager decorations are the same size on
+ three sides, i.e. left, right and bottom. This is to
+ compensate for the bottom part. */
+ - FRAME_X_OUTPUT (f)->x_pixels_outer_diff
- height
+ f->top_pos);
}
f->win_gravity = NorthWestGravity;
}
x_calc_absolute_position (f);
-
+
BLOCK_INPUT;
x_wm_set_size_hint (f, (long) 0, 0);
modified_left = f->left_pos;
modified_top = f->top_pos;
-#if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
- this seems to be unnecessary and incorrect. rms, 4/17/97. */
- /* It is a mystery why we need to add the border_width here
- when the frame is already visible, but experiment says we do. */
- if (change_gravity != 0)
- {
- modified_left += f->border_width;
- modified_top += f->border_width;
- }
-#endif
-
if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
{
/* Some WMs (twm, wmaker at least) has an offset that is smaller
get_bits_and_offset (dpyinfo->visual->green_mask,
&dpyinfo->green_bits, &dpyinfo->green_offset);
}
-
+
/* See if a private colormap is requested. */
if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
{
x_noop_count = 0;
last_tool_bar_item = -1;
any_help_event_p = 0;
+ ignore_next_mouse_click_timeout = 0;
#ifdef USE_GTK
current_count = -1;
to 4.1, set this to nil. */);
x_use_underline_position_properties = 1;
+ DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",
+ &x_mouse_click_focus_ignore_position,
+ doc: /* Non-nil means that a mouse click to focus a frame does not move point.
+This variable is only used when the window manager requires that you
+click on a frame to select it (give it focus). In that case, a value
+of nil, means that the selected window and cursor position changes to
+reflect the mouse click position, while a non-nil value means that the
+selected window or cursor position is preserved. */);
+ x_mouse_click_focus_ignore_position = 0;
+
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
doc: /* What X toolkit scroll bars Emacs uses.
A value of nil means Emacs doesn't use X toolkit scroll bars.