(list :extend (cadr tail))))))
(setq face-attrs (face-spec-choose (get face 'face-override-spec) frame))
(face-spec-set-2 face frame face-attrs)
- (when (and (fboundp 'set-frame-parameter) ; This isn't available
+ (when (and (not (eq (framep frame) t))
+ (fboundp 'set-frame-parameter) ; This isn't available
; during loadup.
(eq face 'scroll-bar))
;; Set the `scroll-bar-foreground' and `scroll-bar-background'
(drag-bottom (memq part '(bottom-right bottom bottom-left)))
;; Initial "first" mouse position. While dragging we base all
;; calculations against that position.
- (first-x-y (mouse-absolute-pixel-position))
+ (tty (tty-type frame))
+ (first-x-y (if tty
+ (mouse-position-in-root-frame)
+ (mouse-absolute-pixel-position)))
(first-x (car first-x-y))
(first-y (cdr first-x-y))
(exitfun nil)
(lambda (event)
(interactive "e")
(when (consp event)
- (let* ((last-x-y (mouse-absolute-pixel-position))
+ (let* ((last-x-y (if tty
+ (mouse-position-in-root-frame)
+ (mouse-absolute-pixel-position)))
(last-x (car last-x-y))
(last-y (cdr last-x-y))
(left (- last-x first-x))
(parent-bottom (and parent-edges (nth 3 parent-edges)))
;; Initial "first" mouse position. While dragging we base all
;; calculations against that position.
- (first-x-y (mouse-absolute-pixel-position))
- (first-x (car first-x-y))
- (first-y (cdr first-x-y))
- ;; `snap-width' (maybe also a yet to be provided `snap-height')
+ (tty (tty-type frame))
+ (first-x-y (if tty
+ (mouse-position-in-root-frame)
+ (mouse-absolute-pixel-position)))
+ (first-x (car first-x-y))
+ (first-y (cdr first-x-y))
+ ;; `snap-width' (maybe also a yet to be provided `snap-height')
;; could become floats to handle proportionality wrt PARENT.
;; We don't do any checks on this parameter so far.
(snap-width (frame-parameter frame 'snap-width))
(lambda (event)
(interactive "e")
(when (consp event)
- (let* ((last-x-y (mouse-absolute-pixel-position))
+ (let* ((last-x-y (if tty
+ (mouse-position-in-root-frame)
+ (mouse-absolute-pixel-position)))
(last-x (car last-x-y))
(last-y (cdr last-x-y))
(left (- last-x first-x))
(x (or (nth 1 frame-and-xy) x))
(y (or (nth 2 frame-and-xy) y))
(w (window-at x y frame))
- (ltrb (window-edges w))
- (left (nth 0 ltrb))
- (top (nth 1 ltrb))
- (posn (if w
- (posn-at-x-y (- x left) (- y top) w t)
- (append (list nil (if (and tab-bar-mode
- (or (not menu-bar-mode)
- ;; The tab-bar is on the
- ;; second row below menu-bar
- (eq y 1)))
- 'tab-bar
- 'menu-bar))
- (nthcdr 2 (posn-at-x-y x y (selected-frame))))))
+ (posn
+ (if w
+ (let* ((ltrb (window-edges w))
+ (left (nth 0 ltrb))
+ (top (nth 1 ltrb)))
+ (posn-at-x-y (- x left) (- y top) w t))
+ (let* ((frame-has-menu-bar
+ (not (zerop (frame-parameter frame 'menu-bar-lines))))
+ (frame-has-tab-bar
+ (not (zerop (frame-parameter frame 'tab-bar-lines))))
+ (item
+ (cond
+ ((and frame-has-menu-bar (eq y 0))
+ 'menu-bar)
+ ((and frame-has-tab-bar
+ (or (and frame-has-menu-bar
+ (eq y 1))
+ (eq y 0)))
+ 'tab-bar)
+ ((eq x -1)
+ (cond
+ ((eq y -1) 'top-left-corner)
+ ((eq y (frame-height frame)) 'bottom-left-corner)
+ (t 'left-edge)))
+ ((eq x (frame-width frame))
+ (cond
+ ((eq y -1) 'top-right-corner)
+ ((eq y (frame-height frame)) 'bottom-right-corner)
+ (t 'right-edge)))
+ ((eq y -1) 'top-edge)
+ (t 'bottom-edge))))
+ (append (list (unless (memq item '(menu-bar tab-bar))
+ frame)
+ item)
+ (nthcdr 2 (posn-at-x-y x y (selected-frame)))))))
(event (list type posn)))
(setcar (nthcdr 3 posn) timestamp)
return delete_frame (frame, !NILP (force) ? Qt : Qnil);
}
\f
-#ifdef HAVE_WINDOW_SYSTEM
+
/**
* frame_internal_border_part:
*
enum internal_border_part
frame_internal_border_part (struct frame *f, int x, int y)
{
- int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int border = (FRAME_INTERNAL_BORDER_WIDTH (f)
+ ? FRAME_INTERNAL_BORDER_WIDTH (f)
+ : (is_tty_child_frame (f) && !FRAME_UNDECORATED (f))
+ ? 1
+ : 0);
int offset = FRAME_LINE_HEIGHT (f);
int width = FRAME_PIXEL_WIDTH (f);
int height = FRAME_PIXEL_HEIGHT (f);
return part;
}
-#endif
+
/* Return mouse position in character cell units. */
return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
}
+DEFUN ("mouse-position-in-root-frame", Fmouse_position_in_root_frame,
+ Smouse_position_in_root_frame, 0, 0, 0,
+ doc: /* Return mouse position in selected frame's root frame.
+Return the position of `mouse-position' in coordinates of the root frame
+of the frame returned by 'mouse-position'. */)
+ (void)
+{
+ Lisp_Object pos = mouse_position (true);
+ Lisp_Object frame = XCAR (pos);
+ struct frame *f = XFRAME (frame);
+ int x = XFIXNUM (XCAR (XCDR (pos))) + f->left_pos;
+ int y = XFIXNUM (XCDR (XCDR (pos))) + f->top_pos;
+
+ if (!FRAMEP (frame))
+ return Qnil;
+ else
+ {
+ f = FRAME_PARENT_FRAME (f);
+
+ while (f)
+ {
+ x = x + f->left_pos;
+ y = y + f->top_pos;
+ f = FRAME_PARENT_FRAME (f);
+ }
+
+ return Fcons (make_fixnum (x), make_fixnum (y));
+ }
+}
+
DEFUN ("frame--set-was-invisible", Fframe__set_was_invisible,
Sframe__set_was_invisible, 2, 2, 0,
doc: /* Set FRAME's was-invisible flag if WAS-INVISIBLE is non-nil.
defsubr (&Sframe_position);
defsubr (&Sset_frame_position);
defsubr (&Sframe_pointer_visible_p);
+ defsubr (&Smouse_position_in_root_frame);
defsubr (&Sframe__set_was_invisible);
defsubr (&Sframe_window_state_change);
defsubr (&Sset_frame_window_state_change);
vertical_scroll_bar_right
};
+enum internal_border_part
+ {
+ INTERNAL_BORDER_NONE,
+ INTERNAL_BORDER_LEFT_EDGE,
+ INTERNAL_BORDER_TOP_LEFT_CORNER,
+ INTERNAL_BORDER_TOP_EDGE,
+ INTERNAL_BORDER_TOP_RIGHT_CORNER,
+ INTERNAL_BORDER_RIGHT_EDGE,
+ INTERNAL_BORDER_BOTTOM_RIGHT_CORNER,
+ INTERNAL_BORDER_BOTTOM_EDGE,
+ INTERNAL_BORDER_BOTTOM_LEFT_CORNER,
+ };
+
#ifdef HAVE_WINDOW_SYSTEM
enum fullscreen_type
z_group_above_suspended,
};
-enum internal_border_part
- {
- INTERNAL_BORDER_NONE,
- INTERNAL_BORDER_LEFT_EDGE,
- INTERNAL_BORDER_TOP_LEFT_CORNER,
- INTERNAL_BORDER_TOP_EDGE,
- INTERNAL_BORDER_TOP_RIGHT_CORNER,
- INTERNAL_BORDER_RIGHT_EDGE,
- INTERNAL_BORDER_BOTTOM_RIGHT_CORNER,
- INTERNAL_BORDER_BOTTOM_EDGE,
- INTERNAL_BORDER_BOTTOM_LEFT_CORNER,
- };
-
#ifdef NS_IMPL_COCOA
enum ns_appearance_type
{
extern void set_frame_menubar (struct frame *f, bool deep_p);
extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
extern void free_frame_menubar (struct frame *);
-extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y);
#if defined HAVE_X_WINDOWS
extern void x_wm_set_icon_position (struct frame *, int, int);
#endif /* !HAVE_NS */
#endif /* HAVE_WINDOW_SYSTEM */
+extern enum internal_border_part frame_internal_border_part (struct frame *f,
+ int x, int y);
extern bool frame_ancestor_p (struct frame *af, struct frame *df);
INLINE void
SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
};
-#ifdef HAVE_WINDOW_SYSTEM
/* An array of symbol indexes of internal border parts, indexed by an enum
internal_border_part value. Note that Qnil corresponds to
internal_border_part_none and should not appear in Lisp events. */
SYMBOL_INDEX (Qbottom_right_corner), SYMBOL_INDEX (Qbottom_edge),
SYMBOL_INDEX (Qbottom_left_corner)
};
-#endif
/* A vector, indexed by button number, giving the down-going location
of currently depressed buttons, both scroll bar and non-scroll bar.
static int double_click_count;
+enum frame_border_side
+{
+ ON_LEFT,
+ ON_TOP,
+ ON_RIGHT,
+ ON_BOTTOM,
+ ON_NONE
+};
+
+/* Handle make_lispy_event when a tty child frame's decorations shall be
+ used in lieu of internal borders. R denotes the root frame under
+ investigation, MX and MY are the positions of the mouse relative to
+ R. WINDOW_OR_FRAME denotes the frame previously reported as the
+ frame under (MX, MY). Note: The decorations of a child frame are
+ always drawn outside the child frame, so WINDOW_OR_FRAME is certainly
+ not the frame we are looking for. Neither is R. A candidate frame
+ is any frame but WINDOW_OR_FRAME and R whose root is R, which is not
+ decorated and has a 'drag-internal-border' parameter. If we find a
+ suitable frame, set WINDOW_OR_FRAME to it and POSN to the part of the
+ internal border corresponding to (MX, MY) on the frame found. */
+
+static void
+make_lispy_tty_position (struct frame *r, int mx, int my,
+ Lisp_Object *window_or_frame, Lisp_Object *posn)
+{
+ enum frame_border_side side = ON_NONE;
+ struct frame *f = NULL;
+ Lisp_Object tail, frame;
+ int ix, iy = 0;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ f = XFRAME (frame);
+
+ int left = f->left_pos;
+ int top = f->top_pos;
+ int right = left + f->pixel_width;
+ int bottom = top + f->pixel_height;
+
+ if (root_frame (f) == r && f != r
+ && !FRAME_UNDECORATED (f)
+ && !NILP (get_frame_param (f, Qdrag_internal_border)))
+ {
+ if (left == mx + 1 && my >= top && my <= bottom)
+ {
+ side = ON_LEFT;
+ ix = -1;
+ iy = my - top + 1;
+ break;
+ }
+ else if (right == mx && my >= top && my <= bottom)
+ {
+ side = ON_RIGHT;
+ ix = f->pixel_width;
+ iy = my - top + 1;
+ break;
+ }
+ else if (top == my + 1 && mx >= left && mx <= right)
+ {
+ side = ON_TOP;
+ ix = mx - left + 1;
+ iy = -1;
+ break;
+ }
+ else if (bottom == my && mx >= left && mx <= right)
+ {
+ side = ON_BOTTOM;
+ ix = mx - left + 1;
+ iy = f->pixel_height;
+ break;
+ }
+ }
+ }
+
+ if (side != ON_NONE)
+ {
+ enum internal_border_part part
+ = frame_internal_border_part (f, ix, iy);
+
+ XSETFRAME (*window_or_frame, f);
+ *posn = builtin_lisp_symbol (internal_border_parts[part]);
+ }
+}
+
/* X and Y are frame-relative coordinates for a click or wheel event.
Return a Lisp-style event list. */
window_or_frame = Qnil; /* see above */
}
- if (WINDOWP (window_or_frame))
+ if (WINDOWP (window_or_frame) && is_tty_frame (f)
+ && (is_tty_root_frame_with_visible_child (f)
+ || is_tty_child_frame (f)))
+ make_lispy_tty_position (root_frame (f), mx, my, &window_or_frame, &posn);
+
+ if (!NILP (posn))
+ ;
+ else if (WINDOWP (window_or_frame))
{
/* It's a click in window WINDOW at frame coordinates (X,Y) */
struct window *w = XWINDOW (window_or_frame);
xret = mx;
yret = my;
-#ifdef HAVE_WINDOW_SYSTEM
- if (FRAME_WINDOW_P (f)
- && FRAME_LIVE_P (f)
+ if (FRAME_LIVE_P (f)
&& NILP (posn)
&& FRAME_INTERNAL_BORDER_WIDTH (f) > 0
&& !NILP (get_frame_param (f, Qdrag_internal_border)))
posn = builtin_lisp_symbol (internal_border_parts[part]);
}
-#endif
}
else
{
into the left fringe. */
if (XFIXNUM (x) != -1)
CHECK_FIXNAT (x);
- CHECK_FIXNAT (y);
+ CHECK_FIXNUM (y);
+ if (XFIXNUM (y) != -1)
+ CHECK_FIXNAT (y);
if (NILP (frame_or_window))
frame_or_window = selected_window;
Lisp_Object frame = Fcar (frames);
struct frame *f = XFRAME (frame);
int fx, fy;
+ bool on_border = false;
+
root_xy (f, 0, 0, &fx, &fy);
- if ((fx <= x && x < fx + f->pixel_width)
- && (fy <= y && y < fy + f->pixel_height))
+ if (!FRAME_UNDECORATED (f) && FRAME_PARENT_FRAME (f))
+ {
+ if (fy - 1 <= y && y <= fy + f->pixel_height + 1)
+ {
+ if (fx == x + 1)
+ {
+ *cx = -1;
+ on_border = true;
+ }
+ else if (fx + f->pixel_width == x)
+ {
+ *cx = f->pixel_width;
+ on_border = true;
+ }
+
+ if (on_border)
+ {
+ *cy = y - fy;
+
+ return frame;
+ }
+ }
+
+ if (fx - 1 <= x && x <= fx + f->pixel_width + 1)
+ {
+ if (fy == y + 1)
+ {
+ *cy = -1;
+ on_border = true;
+ }
+ else if (fy + f->pixel_height == y)
+ {
+ *cy = f->pixel_height;
+ on_border = true;
+ }
+
+ if (on_border)
+ {
+ *cx = x - fx;
+
+ return frame;
+ }
+ }
+
+
+ if ((fx <= x && x <= fx + f->pixel_width)
+ && (fy <= y && y <= fy + f->pixel_height))
+ {
+ child_xy (XFRAME (frame), x, y, cx, cy);
+
+ return frame;
+ }
+ }
+ else if ((fx <= x && x <= fx + f->pixel_width)
+ && (fy <= y && y <= fy + f->pixel_height))
{
child_xy (XFRAME (frame), x, y, cx, cy);
+
return frame;
}
}
Lisp_Object frame = tty_frame_at (XFIXNUM (x), XFIXNUM (y), &cx, &cy);
if (NILP (frame))
return Qnil;
+
return list3 (frame, make_fixnum (cx), make_fixnum (cy));
}
{
struct frame *f = decode_live_frame (frame);
+ CHECK_INTEGER (x);
+ CHECK_INTEGER (y);
+
+ if (XFIXNUM (x) < 0 || XFIXNUM (x) > FRAME_PIXEL_WIDTH (f)
+ || XFIXNUM (y) < 0 || XFIXNUM (y) > FRAME_PIXEL_HEIGHT (f))
+ return Qnil;
+
CHECK_NUMBER (x);
CHECK_NUMBER (y);