diff options
| author | Martin Rudalics | 2017-04-12 10:38:25 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2017-04-12 10:38:25 +0200 |
| commit | 3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422 (patch) | |
| tree | a0b8f5e431ba812b4fe69261a8515e973a3e7ed3 | |
| parent | 449bc49c768a4733411c7e05186be7efc163cd7c (diff) | |
| download | emacs-3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422.tar.gz emacs-3fdd3bb56c006a2a24761b8fcea0cbd9b0cba422.zip | |
Add new frame parameters and associated functions
Add new frame parameters `undecorated', `override-redirect',
`parent-frame', `skip-taskbar', `no-focus-on-map',
`no-accept-focus', `z-group', `delete-before', `no-other-frame',
`mouse-wheel-frame', `min-width', `min-height'. Add new
functions `frame-restack' and `frame-list-z-order'.
* lisp/cus-start.el (focus-follows-mouse): Adapt customization
type.
* lisp/frame.el (handle-delete-frame): Handle child and
`delete-before' frames.
(other-frame): Stop looking for other frame after one round.
(frame-list-z-order, frame-restack): New functions.
(delete-other-frames): Handle child frames.
* lisp/frameset.el (frameset-persistent-filter-alist)
(frameset--record-relationships): Handle `delete-before',
`parent-frame' and `mouse-wheel-frame' parameters. Rename
latter from `frameset--record-minibuffer-relationships'.
(frameset--restore-frame): Handle ‘parent-frame’ parameter
specially.
(frameset-restore): Handle `delete-before', `parent-frame' and
`mouse-wheel-frame' parameters.
* lisp/mwheel.el (mwheel-scroll): Handle `mouse-wheel-frame'
parameter.
* lisp/window.el (window--min-size-ignore-p): Fix doc-string.
(mouse-autoselect-window-select, handle-select-window): Major
rewrite. Try to not ignore errors. Handle auto-selection of
child frames and different values of `focus-follows-mouse'.
* src/frame.c (frame_windows_min_size): Handle new `min-width'
and `min-height' frame parameters.
(make_frame): Initialize new frame structure members.
(do_switch_frame): Don't reset internal_last_event_frame for
descendant frames.
(Fframe_parent, frame_ancestor_p, Fframe_ancestor_p): New
functions.
(candidate_frame): Don't return `no-other-frame' frame.
(other_frames): New function replacing other_visible_frames.
(delete_frame): Rewrite. Handle child and `delete-before' frames.
(Fmake_frame_invisible): Call other_frames.
(store_frame_param): Check `delete-before' and `parent-frame'
parameters for circular dependencies.
(frame_parms, syms_of_frame): Add entries for and define new
frame parameters.
(focus_follows_mouse): New meaningful value `auto-raise'.
* src/frame.h (z_group): New enumeration type.
(frame): New slots parent_frame, undecorated, override_redirect,
skip_taskbar, no_focus_on_map, no_accept_focus, z_group.
(fset_parent_frame): New inlined function.
(FRAME_UNDECORATED, FRAME_OVERRIDE_REDIRECT)
(FRAME_PARENT_FRAME, FRAME_SKIP_TASKBAR, FRAME_NO_FOCUS_ON_MAP)
(FRAME_NO_ACCEPT_FOCUS, FRAME_Z_GROUP, FRAME_Z_GROUP_NONE)
(FRAME_Z_GROUP_ABOVE, FRAME_Z_GROUP_ABOVE_SUSPENDED)
(FRAME_Z_GROUP_BELOW): New macros.
(frame_ancestor_p): Add declaration.
* src/gtkutil.c (xg_create_frame_widgets): Handle
`undecorated' and `override-redirect' frame parameters.
(x_wm_set_size_hint): None for child frames.
(xg_set_undecorated, xg_frame_restack, xg_set_skip_taskbar)
(xg_set_no_focus_on_map, xg_set_no_accept_focus)
(xg_set_override_redirect): New functions.
(xg_update_scrollbar_pos, xg_update_horizontal_scrollbar_pos):
Don't let scrollbars obscure child frames.
* src/gtkutil.h: (xg_set_undecorated, xg_frame_restack)
(xg_set_skip_taskbar, xg_set_no_focus_on_map)
(xg_set_no_accept_focus, xg_set_override_redirect): Add extern
declarations.
* src/nsfns.m (ns_frame_parm_handlers): Add entries for new
frame parameters.
(Fx_create_frame): Install `min-width' and `min-height' frame
parameters.
* src/nsterm.m (mouseMoved:): Handle focus_follows_mouse change.
* src/w32fns.c (WS_EX_NOACTIVATE): Define if necessary.
(x_real_positions): Handle child frames.
(x_set_menu_bar_lines): Don't for child frames.
(x_set_undecorated, x_set_parent_frame, x_set_skip_taskbar)
(x_set_no_focus_on_map, x_set_no_accept_focus)
(x_set_z_group): New functions.
(w32_createvscrollbar, w32_createhscrollbar): Don't draw
scroll bars over child frames.
(w32_createwindow): Handle new frame parameters and child frames.
(w32_wnd_proc): Let mouse clicks into a child frame activate
the frame. Try to handle the `no-accept-focus' parameter. Do
SetFocus when our window is brought to top or becomes the
foreground window.
(w32_window): Don't initialize menu bar for child frames.
(Fx_create_frame): Handle new frame parameters.
(x_create_tip_frame): Set explicit_parent slot.
(w32_dialog_in_progress): New function.
(Fx_file_dialog): Handle `z-group-above' frames.
(w32_frame_list_z_order, Fw32_frame_list_z_order)
(w32_frame_restack, Fw32_frame_restack): New functions.
(w32_frame_parm_handlers): Add entries for new frame
parameters.
* src/w32font.c (Fx_select_font): Handle `z-group-above'
frames during font selection dialogue.
* src/w32term.c (construct_mouse_wheel): Construct mouse wheel
event from F's w32 window.
(w32_mouse_position): Handle child frames.
(w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar):
Don't draw scroll bars over child frames.
(w32_read_socket): Always erase background of child frames.
When generating SELECT_WINDOW_EVENTs handle new value of
`focus-follows-mouse' and handle `no-accept-focus' parameter.
Handle `mouse-wheel-frame' parameter.
(x_calc_absolute_position, x_set_offset, x_set_window_size):
Handle child frames.
(x_make_frame_visible): Handle child frames specially. Handle
`no-focus-on-map' parameter.
* src/w32term.h (w32_dialog_in_progress): Add external
declaration.
* src/xdisp.c (x_consider_frame_title, prepare_menu_bars): Not
for child frames.
* src/xfns.c (Xm/MwmUtil.h): Include for WM hints.
(PropMotifWmHints, PROP_MOTIF_WM_HINTS_ELEMENTS): Define for
non-Motif, non-GTK case.
(x_real_pos_and_offsets): Handle child frames.
(x_set_undecorated, x_set_parent_frame)
(x_set_no_focus_on_map, x_set_no_accept_focus)
(x_set_override_redirect): New functions.
(x_set_menu_bar_lines): Not for child frames.
(x_window): Handle `undecorated' and `override_redirect' cases.
(Fx_create_frame): Handle new frame parameters.
(frame_geometry): Handle child frames and outer border.
(x_frame_list_z_order, Fx_frame_list_z_order)
(x_frame_restack, Fx_frame_restack): New functions.
(Fx_file_dialog, Fx_select_font): Set x_menu_set_in_use.
(x_frame_parm_handlers): Add entries for new frame parameters.
* src/xmenu.c (x_menu_set_in_use): Handle `z-group-above'
frames.
* src/xterm.c (x_set_frame_alpha): Don't set alpha of parent
for child frames.
(XTmouse_position): Handle child frames.
(x_scroll_bar_create, x_scroll_bar_expose): Don't let scroll
bars obscure child frames.
(handle_one_xevent): Handle child frame positions. If necessary
set `skip-taskbar' and reassign proper `z-group' when we are
mapped. When generating SELECT_WINDOW_EVENTs handle new value
of `focus-follows-mouse'. Handle `mouse-wheel-frame' parameter.
Let mouse clicks into a child frame activate the frame.
(x_calc_absolute_position, x_set_offset): Handle child frames
specially.
(x_set_skip_taskbar, x_set_z_group): New functions.
(x_make_frame_visible): Handle child frames.
(ATOM_REFS_INIT): Add entries for
Xatom_net_wm_state_skip_taskbar, Xatom_net_wm_state_above,
Xatom_net_wm_state_below.
* src/xterm.h (top-level): Declare Xatom_net_wm_state_above,
Xatom_net_wm_state_below and Xatom_net_wm_state_skip_taskbar.
(x_set_skip_taskbar, x_set_z_group): Add extern declarations.
| -rw-r--r-- | lisp/cus-start.el | 6 | ||||
| -rw-r--r-- | lisp/frame.el | 117 | ||||
| -rw-r--r-- | lisp/frameset.el | 100 | ||||
| -rw-r--r-- | lisp/mwheel.el | 59 | ||||
| -rw-r--r-- | lisp/window.el | 169 | ||||
| -rw-r--r-- | src/frame.c | 402 | ||||
| -rw-r--r-- | src/frame.h | 86 | ||||
| -rw-r--r-- | src/gtkutil.c | 135 | ||||
| -rw-r--r-- | src/gtkutil.h | 7 | ||||
| -rw-r--r-- | src/nsfns.m | 13 | ||||
| -rw-r--r-- | src/nsterm.m | 2 | ||||
| -rw-r--r-- | src/w32fns.c | 659 | ||||
| -rw-r--r-- | src/w32font.c | 19 | ||||
| -rw-r--r-- | src/w32term.c | 200 | ||||
| -rw-r--r-- | src/w32term.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 6 | ||||
| -rw-r--r-- | src/xfns.c | 605 | ||||
| -rw-r--r-- | src/xmenu.c | 14 | ||||
| -rw-r--r-- | src/xterm.c | 389 | ||||
| -rw-r--r-- | src/xterm.h | 8 |
20 files changed, 2543 insertions, 454 deletions
diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 51c43c7d21a..a507e30ca9c 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el | |||
| @@ -286,7 +286,11 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of | |||
| 286 | ;; fns.c | 286 | ;; fns.c |
| 287 | (use-dialog-box menu boolean "21.1") | 287 | (use-dialog-box menu boolean "21.1") |
| 288 | (use-file-dialog menu boolean "22.1") | 288 | (use-file-dialog menu boolean "22.1") |
| 289 | (focus-follows-mouse frames boolean "20.3") | 289 | (focus-follows-mouse |
| 290 | frames (choice | ||
| 291 | (const :tag "Off (nil)" :value nil) | ||
| 292 | (const :tag "On (t)" :value t) | ||
| 293 | (const :tag "Auto-raise" :value auto-raise)) "26.1") | ||
| 290 | ;; fontset.c | 294 | ;; fontset.c |
| 291 | ;; FIXME nil is the initial value, fontset.el setqs it. | 295 | ;; FIXME nil is the initial value, fontset.el setqs it. |
| 292 | (vertical-centering-font-regexp display | 296 | (vertical-centering-font-regexp display |
diff --git a/lisp/frame.el b/lisp/frame.el index 4768b5be002..86a0e26e393 100644 --- a/lisp/frame.el +++ b/lisp/frame.el | |||
| @@ -115,15 +115,19 @@ appended when the minibuffer frame is created." | |||
| 115 | (defun handle-delete-frame (event) | 115 | (defun handle-delete-frame (event) |
| 116 | "Handle delete-frame events from the X server." | 116 | "Handle delete-frame events from the X server." |
| 117 | (interactive "e") | 117 | (interactive "e") |
| 118 | (let ((frame (posn-window (event-start event))) | 118 | (let* ((frame (posn-window (event-start event)))) |
| 119 | (i 0) | 119 | (if (catch 'other-frame |
| 120 | (tail (frame-list))) | 120 | (dolist (frame-1 (frame-list)) |
| 121 | (while tail | 121 | ;; A valid "other" frame is visible, owns its minibuffer |
| 122 | (and (frame-visible-p (car tail)) | 122 | ;; window, has its `delete-before' parameter unset and is |
| 123 | (not (eq (car tail) frame)) | 123 | ;; not a child frame. |
| 124 | (setq i (1+ i))) | 124 | (when (and (not (eq frame-1 frame)) |
| 125 | (setq tail (cdr tail))) | 125 | (frame-visible-p frame-1) |
| 126 | (if (> i 0) | 126 | (window-live-p (minibuffer-window frame-1)) |
| 127 | (eq (window-frame (minibuffer-window frame-1)) frame-1) | ||
| 128 | (not (frame-parent frame-1)) | ||
| 129 | (not (frame-parameter frame-1 'delete-before))) | ||
| 130 | (throw 'other-frame t)))) | ||
| 127 | (delete-frame frame t) | 131 | (delete-frame frame t) |
| 128 | ;; Gildea@x.org says it is ok to ask questions before terminating. | 132 | ;; Gildea@x.org says it is ok to ask questions before terminating. |
| 129 | (save-buffers-kill-emacs)))) | 133 | (save-buffers-kill-emacs)))) |
| @@ -834,21 +838,24 @@ All frames are arranged in a cyclic order. | |||
| 834 | This command selects the frame ARG steps away in that order. | 838 | This command selects the frame ARG steps away in that order. |
| 835 | A negative ARG moves in the opposite order. | 839 | A negative ARG moves in the opposite order. |
| 836 | 840 | ||
| 837 | To make this command work properly, you must tell Emacs | 841 | To make this command work properly, you must tell Emacs how the |
| 838 | how the system (or the window manager) generally handles | 842 | system (or the window manager) generally handles focus-switching |
| 839 | focus-switching between windows. If moving the mouse onto a window | 843 | between windows. If moving the mouse onto a window selects |
| 840 | selects it (gives it focus), set `focus-follows-mouse' to t. | 844 | it (gives it focus), set `focus-follows-mouse' to t. Otherwise, |
| 841 | Otherwise, that variable should be nil." | 845 | that variable should be nil." |
| 842 | (interactive "p") | 846 | (interactive "p") |
| 843 | (let ((frame (selected-frame))) | 847 | (let ((sframe (selected-frame)) |
| 848 | (frame (selected-frame))) | ||
| 844 | (while (> arg 0) | 849 | (while (> arg 0) |
| 845 | (setq frame (next-frame frame)) | 850 | (setq frame (next-frame frame)) |
| 846 | (while (not (eq (frame-visible-p frame) t)) | 851 | (while (and (not (eq frame sframe)) |
| 852 | (not (eq (frame-visible-p frame) t))) | ||
| 847 | (setq frame (next-frame frame))) | 853 | (setq frame (next-frame frame))) |
| 848 | (setq arg (1- arg))) | 854 | (setq arg (1- arg))) |
| 849 | (while (< arg 0) | 855 | (while (< arg 0) |
| 850 | (setq frame (previous-frame frame)) | 856 | (setq frame (previous-frame frame)) |
| 851 | (while (not (eq (frame-visible-p frame) t)) | 857 | (while (and (not (eq frame sframe)) |
| 858 | (not (eq (frame-visible-p frame) t))) | ||
| 852 | (setq frame (previous-frame frame))) | 859 | (setq frame (previous-frame frame))) |
| 853 | (setq arg (1+ arg))) | 860 | (setq arg (1+ arg))) |
| 854 | (select-frame-set-input-focus frame))) | 861 | (select-frame-set-input-focus frame))) |
| @@ -1380,6 +1387,7 @@ and width values are in pixels. | |||
| 1380 | '(outer-position 0 . 0) | 1387 | '(outer-position 0 . 0) |
| 1381 | (cons 'outer-size (cons (frame-width frame) (frame-height frame))) | 1388 | (cons 'outer-size (cons (frame-width frame) (frame-height frame))) |
| 1382 | '(external-border-size 0 . 0) | 1389 | '(external-border-size 0 . 0) |
| 1390 | '(outer-border-width . 0) | ||
| 1383 | '(title-bar-size 0 . 0) | 1391 | '(title-bar-size 0 . 0) |
| 1384 | '(menu-bar-external . nil) | 1392 | '(menu-bar-external . nil) |
| 1385 | (let ((menu-bar-lines (frame-parameter frame 'menu-bar-lines))) | 1393 | (let ((menu-bar-lines (frame-parameter frame 'menu-bar-lines))) |
| @@ -1490,6 +1498,59 @@ keys and their meanings." | |||
| 1490 | for frames = (cdr (assq 'frames attributes)) | 1498 | for frames = (cdr (assq 'frames attributes)) |
| 1491 | if (memq frame frames) return attributes)) | 1499 | if (memq frame frames) return attributes)) |
| 1492 | 1500 | ||
| 1501 | (declare-function x-frame-list-z-order "xfns.c" (&optional display)) | ||
| 1502 | (declare-function w32-frame-list-z-order "w32fns.c" (&optional display)) | ||
| 1503 | |||
| 1504 | (defun frame-list-z-order (&optional display) | ||
| 1505 | "Return list of Emacs' frames, in Z (stacking) order. | ||
| 1506 | The optional argument DISPLAY specifies which display to poll. | ||
| 1507 | DISPLAY should be either a frame or a display name (a string). | ||
| 1508 | If omitted or nil, that stands for the selected frame's display. | ||
| 1509 | |||
| 1510 | Frames are listed from topmost (first) to bottommost (last). As | ||
| 1511 | a special case, if DISPLAY is non-nil and specifies a live frame, | ||
| 1512 | return the child frames of that frame in Z (stacking) order. | ||
| 1513 | |||
| 1514 | Return nil if DISPLAY contains no Emacs frame." | ||
| 1515 | (let ((frame-type (framep-on-display display))) | ||
| 1516 | (cond | ||
| 1517 | ((eq frame-type 'x) | ||
| 1518 | (x-frame-list-z-order display)) | ||
| 1519 | ((eq frame-type 'w32) | ||
| 1520 | (w32-frame-list-z-order display))))) | ||
| 1521 | |||
| 1522 | (declare-function x-frame-restack "xfns.c" (frame1 frame2 &optional above)) | ||
| 1523 | (declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above)) | ||
| 1524 | |||
| 1525 | (defun frame-restack (frame1 frame2 &optional above) | ||
| 1526 | "Restack FRAME1 below FRAME2. | ||
| 1527 | This implies that if both frames are visible and the display | ||
| 1528 | areas of these frames overlap, FRAME2 will (partially) obscure | ||
| 1529 | FRAME1. If the optional third argument ABOVE is non-nil, restack | ||
| 1530 | FRAME1 above FRAME2. This means that if both frames are visible | ||
| 1531 | and the display areas of these frames overlap, FRAME1 will | ||
| 1532 | \(partially) obscure FRAME2. | ||
| 1533 | |||
| 1534 | This may be thought of as an atomic action performed in two | ||
| 1535 | steps: The first step removes FRAME1's window-system window from | ||
| 1536 | the display. The second step reinserts FRAME1's window | ||
| 1537 | below (above if ABOVE is true) that of FRAME2. Hence the | ||
| 1538 | position of FRAME2 in its display's Z (stacking) order relative | ||
| 1539 | to all other frames excluding FRAME1 remains unaltered. | ||
| 1540 | |||
| 1541 | Some window managers may refuse to restack windows. " | ||
| 1542 | (if (and (frame-live-p frame1) | ||
| 1543 | (frame-live-p frame2) | ||
| 1544 | (equal (frame-parameter frame1 'display) | ||
| 1545 | (frame-parameter frame2 'display))) | ||
| 1546 | (let ((frame-type (framep-on-display frame1))) | ||
| 1547 | (cond | ||
| 1548 | ((eq frame-type 'x) | ||
| 1549 | (x-frame-restack frame1 frame2 above)) | ||
| 1550 | ((eq frame-type 'w32) | ||
| 1551 | (w32-frame-restack frame1 frame2 above)))) | ||
| 1552 | (error "Cannot restack frames"))) | ||
| 1553 | |||
| 1493 | (defun frame-size-changed-p (&optional frame) | 1554 | (defun frame-size-changed-p (&optional frame) |
| 1494 | "Return non-nil when the size of FRAME has changed. | 1555 | "Return non-nil when the size of FRAME has changed. |
| 1495 | More precisely, return non-nil when the inner width or height of | 1556 | More precisely, return non-nil when the inner width or height of |
| @@ -1886,7 +1947,7 @@ A geometry specification equivalent to SPEC for FRAME is returned, | |||
| 1886 | where the value is a cons with car `+', not numeric. | 1947 | where the value is a cons with car `+', not numeric. |
| 1887 | SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE). | 1948 | SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE). |
| 1888 | If VALUE is a number, then it is converted to a cons value, perhaps | 1949 | If VALUE is a number, then it is converted to a cons value, perhaps |
| 1889 | relative to the opposite frame edge from that in the original spec. | 1950 | relative to the opposite frame edge from that in the original spec. |
| 1890 | FRAME defaults to the selected frame. | 1951 | FRAME defaults to the selected frame. |
| 1891 | 1952 | ||
| 1892 | Examples (measures in pixels) - | 1953 | Examples (measures in pixels) - |
| @@ -1907,24 +1968,36 @@ the opposite frame edge from the edge indicated in the input spec." | |||
| 1907 | (defun delete-other-frames (&optional frame) | 1968 | (defun delete-other-frames (&optional frame) |
| 1908 | "Delete all frames on FRAME's terminal, except FRAME. | 1969 | "Delete all frames on FRAME's terminal, except FRAME. |
| 1909 | If FRAME uses another frame's minibuffer, the minibuffer frame is | 1970 | If FRAME uses another frame's minibuffer, the minibuffer frame is |
| 1910 | left untouched. FRAME must be a live frame and defaults to the | 1971 | left untouched. Do not delete any of FRAME's child frames. If |
| 1911 | selected one." | 1972 | FRAME is a child frame, delete its siblings only. FRAME must be |
| 1973 | a live frame and defaults to the selected one." | ||
| 1912 | (interactive) | 1974 | (interactive) |
| 1913 | (setq frame (window-normalize-frame frame)) | 1975 | (setq frame (window-normalize-frame frame)) |
| 1914 | (let ((minibuffer-frame (window-frame (minibuffer-window frame))) | 1976 | (let ((minibuffer-frame (window-frame (minibuffer-window frame))) |
| 1915 | (this (next-frame frame t)) | 1977 | (this (next-frame frame t)) |
| 1978 | (parent (frame-parent frame)) | ||
| 1916 | next) | 1979 | next) |
| 1917 | ;; In a first round consider minibuffer-less frames only. | 1980 | ;; In a first round consider minibuffer-less frames only. |
| 1918 | (while (not (eq this frame)) | 1981 | (while (not (eq this frame)) |
| 1919 | (setq next (next-frame this t)) | 1982 | (setq next (next-frame this t)) |
| 1920 | (unless (eq (window-frame (minibuffer-window this)) this) | 1983 | (unless (or (eq (window-frame (minibuffer-window this)) this) |
| 1984 | ;; When FRAME is a child frame, delete its siblings | ||
| 1985 | ;; only. | ||
| 1986 | (and parent (not (eq (frame-parent this) parent))) | ||
| 1987 | ;; Do not delete a child frame of FRAME. | ||
| 1988 | (eq (frame-parent this) frame)) | ||
| 1921 | (delete-frame this)) | 1989 | (delete-frame this)) |
| 1922 | (setq this next)) | 1990 | (setq this next)) |
| 1923 | ;; In a second round consider all remaining frames. | 1991 | ;; In a second round consider all remaining frames. |
| 1924 | (setq this (next-frame frame t)) | 1992 | (setq this (next-frame frame t)) |
| 1925 | (while (not (eq this frame)) | 1993 | (while (not (eq this frame)) |
| 1926 | (setq next (next-frame this t)) | 1994 | (setq next (next-frame this t)) |
| 1927 | (unless (eq this minibuffer-frame) | 1995 | (unless (or (eq this minibuffer-frame) |
| 1996 | ;; When FRAME is a child frame, delete its siblings | ||
| 1997 | ;; only. | ||
| 1998 | (and parent (not (eq (frame-parent this) parent))) | ||
| 1999 | ;; Do not delete a child frame of FRAME. | ||
| 2000 | (eq (frame-parent this) frame)) | ||
| 1928 | (delete-frame this)) | 2001 | (delete-frame this)) |
| 1929 | (setq this next)))) | 2002 | (setq this next)))) |
| 1930 | 2003 | ||
diff --git a/lisp/frameset.el b/lisp/frameset.el index 2dd3050ef76..ebf09d3ab5c 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el | |||
| @@ -446,6 +446,7 @@ DO NOT MODIFY. See `frameset-filter-alist' for a full description.") | |||
| 446 | (buffer-list . :never) | 446 | (buffer-list . :never) |
| 447 | (buffer-predicate . :never) | 447 | (buffer-predicate . :never) |
| 448 | (buried-buffer-list . :never) | 448 | (buried-buffer-list . :never) |
| 449 | (delete-before . :never) | ||
| 449 | (font . frameset-filter-shelve-param) | 450 | (font . frameset-filter-shelve-param) |
| 450 | (foreground-color . frameset-filter-sanitize-color) | 451 | (foreground-color . frameset-filter-sanitize-color) |
| 451 | (fullscreen . frameset-filter-shelve-param) | 452 | (fullscreen . frameset-filter-shelve-param) |
| @@ -455,7 +456,9 @@ DO NOT MODIFY. See `frameset-filter-alist' for a full description.") | |||
| 455 | (GUI:width . frameset-filter-unshelve-param) | 456 | (GUI:width . frameset-filter-unshelve-param) |
| 456 | (height . frameset-filter-shelve-param) | 457 | (height . frameset-filter-shelve-param) |
| 457 | (outer-window-id . :never) | 458 | (outer-window-id . :never) |
| 459 | (parent-frame . :never) | ||
| 458 | (parent-id . :never) | 460 | (parent-id . :never) |
| 461 | (mouse-wheel-frame . :never) | ||
| 459 | (tty . frameset-filter-tty-to-GUI) | 462 | (tty . frameset-filter-tty-to-GUI) |
| 460 | (tty-type . frameset-filter-tty-to-GUI) | 463 | (tty-type . frameset-filter-tty-to-GUI) |
| 461 | (width . frameset-filter-shelve-param) | 464 | (width . frameset-filter-shelve-param) |
| @@ -717,9 +720,18 @@ If nil, check all live frames." | |||
| 717 | 720 | ||
| 718 | ;; Saving framesets | 721 | ;; Saving framesets |
| 719 | 722 | ||
| 720 | (defun frameset--record-minibuffer-relationships (frame-list) | 723 | (defun frameset--record-relationships (frame-list) |
| 721 | "Process FRAME-LIST and record minibuffer relationships. | 724 | "Process FRAME-LIST and record relationships. |
| 722 | FRAME-LIST is a list of frames. Internal use only." | 725 | FRAME-LIST is a list of frames. |
| 726 | |||
| 727 | The relationships recorded for each frame are | ||
| 728 | |||
| 729 | - `minibuffer' via `frameset--mini' | ||
| 730 | - `delete-before' via `frameset--delete-before' | ||
| 731 | - `parent-frame' via `frameset--parent-frame' | ||
| 732 | - `mouse-wheel-frame' via `frameset--mouse-wheel-frame' | ||
| 733 | |||
| 734 | Internal use only." | ||
| 723 | ;; Record frames with their own minibuffer | 735 | ;; Record frames with their own minibuffer |
| 724 | (dolist (frame (minibuffer-frame-list)) | 736 | (dolist (frame (minibuffer-frame-list)) |
| 725 | (when (memq frame frame-list) | 737 | (when (memq frame frame-list) |
| @@ -730,22 +742,41 @@ FRAME-LIST is a list of frames. Internal use only." | |||
| 730 | (set-frame-parameter frame | 742 | (set-frame-parameter frame |
| 731 | 'frameset--mini | 743 | 'frameset--mini |
| 732 | (cons t (eq frame default-minibuffer-frame))))) | 744 | (cons t (eq frame default-minibuffer-frame))))) |
| 733 | ;; Now link minibufferless frames with their minibuffer frames | 745 | ;; Now link minibufferless frames with their minibuffer frames and |
| 746 | ;; store `parent-frame', `delete-before' and `mouse-wheel-frame' | ||
| 747 | ;; relationships in a similar way. | ||
| 734 | (dolist (frame frame-list) | 748 | (dolist (frame frame-list) |
| 735 | (unless (frame-parameter frame 'frameset--mini) | 749 | (let ((parent-frame (frame-parent frame)) |
| 736 | (frameset--set-id frame) | 750 | (delete-before (frame-parameter frame 'delete-before)) |
| 737 | (let ((mb-frame (window-frame (minibuffer-window frame)))) | 751 | (mouse-wheel-frame (frame-parameter frame 'mouse-wheel-frame)) |
| 738 | ;; For minibufferless frames, frameset--mini is a cons | 752 | (nomini (not (frame-parameter frame 'frameset--mini)))) |
| 739 | ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id of | 753 | (when (or nomini parent-frame delete-before mouse-wheel-frame) |
| 740 | ;; the frame containing its minibuffer window. | 754 | (when nomini |
| 741 | ;; FRAME-ID can be set to nil, if FRAME-LIST doesn't contain | 755 | (frameset--set-id frame)) |
| 742 | ;; the minibuffer frame of a minibufferless frame; we allow | 756 | (when parent-frame |
| 743 | ;; it without trying to second-guess the user. | 757 | (set-frame-parameter |
| 744 | (set-frame-parameter frame | 758 | frame 'frameset--parent-frame (frameset-frame-id parent-frame))) |
| 745 | 'frameset--mini | 759 | (when delete-before |
| 746 | (cons nil | 760 | (set-frame-parameter |
| 747 | (and mb-frame | 761 | frame 'frameset--delete-before (frameset-frame-id delete-before))) |
| 748 | (frameset-frame-id mb-frame)))))))) | 762 | (when mouse-wheel-frame |
| 763 | (set-frame-parameter | ||
| 764 | frame 'frameset--mouse-wheel-frame | ||
| 765 | (frameset-frame-id mouse-wheel-frame))) | ||
| 766 | (when nomini | ||
| 767 | (let ((mb-frame (window-frame (minibuffer-window frame)))) | ||
| 768 | ;; For minibufferless frames, frameset--mini is a cons | ||
| 769 | ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id of | ||
| 770 | ;; the frame containing its minibuffer window. | ||
| 771 | ;; FRAME-ID can be set to nil, if FRAME-LIST doesn't contain | ||
| 772 | ;; the minibuffer frame of a minibufferless frame; we allow | ||
| 773 | ;; it without trying to second-guess the user. | ||
| 774 | (set-frame-parameter | ||
| 775 | frame | ||
| 776 | 'frameset--mini | ||
| 777 | (cons nil | ||
| 778 | (and mb-frame | ||
| 779 | (frameset-frame-id mb-frame)))))))))) | ||
| 749 | 780 | ||
| 750 | ;;;###autoload | 781 | ;;;###autoload |
| 751 | (cl-defun frameset-save (frame-list | 782 | (cl-defun frameset-save (frame-list |
| @@ -768,7 +799,7 @@ PROPERTIES is a user-defined property list to add to the frameset." | |||
| 768 | (cl-delete-if-not predicate list) | 799 | (cl-delete-if-not predicate list) |
| 769 | list))) | 800 | list))) |
| 770 | fs) | 801 | fs) |
| 771 | (frameset--record-minibuffer-relationships frames) | 802 | (frameset--record-relationships frames) |
| 772 | (setq fs (frameset--make | 803 | (setq fs (frameset--make |
| 773 | :app app | 804 | :app app |
| 774 | :name name | 805 | :name name |
| @@ -993,6 +1024,14 @@ Internal use only." | |||
| 993 | (frameset--initial-params filtered-cfg)))) | 1024 | (frameset--initial-params filtered-cfg)))) |
| 994 | (puthash frame :created frameset--action-map)) | 1025 | (puthash frame :created frameset--action-map)) |
| 995 | 1026 | ||
| 1027 | ;; Try to assign parent-frame right here - it will improve things | ||
| 1028 | ;; for minibuffer-less child frames. | ||
| 1029 | (let* ((frame-id (frame-parameter frame 'frameset--parent-frame)) | ||
| 1030 | (parent-frame | ||
| 1031 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1032 | (when (frame-live-p parent-frame) | ||
| 1033 | (set-frame-parameter frame 'parent-frame parent-frame))) | ||
| 1034 | |||
| 996 | (modify-frame-parameters frame | 1035 | (modify-frame-parameters frame |
| 997 | (if (eq (frame-parameter frame 'fullscreen) fullscreen) | 1036 | (if (eq (frame-parameter frame 'fullscreen) fullscreen) |
| 998 | ;; Workaround for bug#14949 | 1037 | ;; Workaround for bug#14949 |
| @@ -1205,6 +1244,29 @@ All keyword parameters default to nil." | |||
| 1205 | (error | 1244 | (error |
| 1206 | (delay-warning 'frameset (error-message-string err) :error)))))) | 1245 | (delay-warning 'frameset (error-message-string err) :error)))))) |
| 1207 | 1246 | ||
| 1247 | ;; Setting the parent frame after the frame has been created is a | ||
| 1248 | ;; pain because one can see the frame move on the screen. Ideally, | ||
| 1249 | ;; we would restore minibuffer equipped child frames after their | ||
| 1250 | ;; respective parents have been made but this might interfere with | ||
| 1251 | ;; the reordering of minibuffer frames. Left to the experts ... | ||
| 1252 | (dolist (frame (frame-list)) | ||
| 1253 | (let* ((frame-id (frame-parameter frame 'frameset--parent-frame)) | ||
| 1254 | (parent-frame | ||
| 1255 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1256 | (when (and (not (eq (frame-parameter frame 'parent-frame) parent-frame)) | ||
| 1257 | (frame-live-p parent-frame)) | ||
| 1258 | (set-frame-parameter frame 'parent-frame parent-frame))) | ||
| 1259 | (let* ((frame-id (frame-parameter frame 'frameset--delete-before)) | ||
| 1260 | (delete-before | ||
| 1261 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1262 | (when (frame-live-p delete-before) | ||
| 1263 | (set-frame-parameter frame 'delete-before delete-before))) | ||
| 1264 | (let* ((frame-id (frame-parameter frame 'frameset--mouse-wheel-frame)) | ||
| 1265 | (mouse-wheel-frame | ||
| 1266 | (and frame-id (frameset-frame-with-id frame-id)))) | ||
| 1267 | (when (frame-live-p mouse-wheel-frame) | ||
| 1268 | (set-frame-parameter frame 'mouse-wheel-frame mouse-wheel-frame)))) | ||
| 1269 | |||
| 1208 | ;; In case we try to delete the initial frame, we want to make sure that | 1270 | ;; In case we try to delete the initial frame, we want to make sure that |
| 1209 | ;; other frames are already visible (discussed in thread for bug#14841). | 1271 | ;; other frames are already visible (discussed in thread for bug#14841). |
| 1210 | (sit-for 0 t) | 1272 | (sit-for 0 t) |
diff --git a/lisp/mwheel.el b/lisp/mwheel.el index eaeb831e844..958c6e831b7 100644 --- a/lisp/mwheel.el +++ b/lisp/mwheel.el | |||
| @@ -190,14 +190,33 @@ This can be slightly disconcerting, but some people prefer it." | |||
| 190 | This should be bound only to mouse buttons 4 and 5 on non-Windows | 190 | This should be bound only to mouse buttons 4 and 5 on non-Windows |
| 191 | systems." | 191 | systems." |
| 192 | (interactive (list last-input-event)) | 192 | (interactive (list last-input-event)) |
| 193 | (let* ((curwin (if mouse-wheel-follow-mouse | 193 | (let* ((selected-window (selected-window)) |
| 194 | (prog1 | 194 | (scroll-window |
| 195 | (selected-window) | 195 | (or (catch 'found |
| 196 | (select-window (mwheel-event-window event))))) | 196 | (let* ((window (if mouse-wheel-follow-mouse |
| 197 | (buffer (window-buffer curwin)) | 197 | (mwheel-event-window event) |
| 198 | (opoint (with-current-buffer buffer | 198 | (selected-window))) |
| 199 | (when (eq (car-safe transient-mark-mode) 'only) | 199 | (frame (when (window-live-p window) |
| 200 | (point)))) | 200 | (frame-parameter |
| 201 | (window-frame window) 'mouse-wheel-frame)))) | ||
| 202 | (when (frame-live-p frame) | ||
| 203 | (let* ((pos (mouse-absolute-pixel-position)) | ||
| 204 | (pos-x (car pos)) | ||
| 205 | (pos-y (cdr pos))) | ||
| 206 | (walk-window-tree | ||
| 207 | (lambda (window-1) | ||
| 208 | (let ((edges (window-edges window-1 nil t t))) | ||
| 209 | (when (and (<= (nth 0 edges) pos-x) | ||
| 210 | (<= pos-x (nth 2 edges)) | ||
| 211 | (<= (nth 1 edges) pos-y) | ||
| 212 | (<= pos-y (nth 3 edges))) | ||
| 213 | (throw 'found window-1)))) | ||
| 214 | frame nil t))))) | ||
| 215 | (mwheel-event-window event))) | ||
| 216 | (old-point | ||
| 217 | (and (eq scroll-window selected-window) | ||
| 218 | (eq (car-safe transient-mark-mode) 'only) | ||
| 219 | (window-point))) | ||
| 201 | (mods | 220 | (mods |
| 202 | (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) | 221 | (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) |
| 203 | (amt (assoc mods mouse-wheel-scroll-amount))) | 222 | (amt (assoc mods mouse-wheel-scroll-amount))) |
| @@ -232,18 +251,18 @@ systems." | |||
| 232 | ;; Make sure we do indeed scroll to the end of the buffer. | 251 | ;; Make sure we do indeed scroll to the end of the buffer. |
| 233 | (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) | 252 | (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) |
| 234 | (t (error "Bad binding in mwheel-scroll")))) | 253 | (t (error "Bad binding in mwheel-scroll")))) |
| 235 | (if curwin (select-window curwin))) | 254 | (if (eq scroll-window selected-window) |
| 236 | ;; If there is a temporarily active region, deactivate it if | 255 | ;; If there is a temporarily active region, deactivate it if |
| 237 | ;; scrolling moves point. | 256 | ;; scrolling moved point. |
| 238 | (when opoint | 257 | (when (and old-point (/= old-point (window-point))) |
| 239 | (with-current-buffer buffer | 258 | ;; Call `deactivate-mark' at the original position, so that |
| 240 | (when (/= opoint (point)) | 259 | ;; the original region is saved to the X selection. |
| 241 | ;; Call `deactivate-mark' at the original position, so that | 260 | (let ((new-point (window-point))) |
| 242 | ;; the original region is saved to the X selection. | 261 | (goto-char old-point) |
| 243 | (let ((newpoint (point))) | 262 | (deactivate-mark) |
| 244 | (goto-char opoint) | 263 | (goto-char new-point))) |
| 245 | (deactivate-mark) | 264 | (select-window selected-window t)))) |
| 246 | (goto-char newpoint)))))) | 265 | |
| 247 | (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time) | 266 | (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time) |
| 248 | (if mwheel-inhibit-click-event-timer | 267 | (if mwheel-inhibit-click-event-timer |
| 249 | (cancel-timer mwheel-inhibit-click-event-timer) | 268 | (cancel-timer mwheel-inhibit-click-event-timer) |
diff --git a/lisp/window.el b/lisp/window.el index 505024342ed..bea8383fcde 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -1533,7 +1533,7 @@ return the minimum pixel-size of WINDOW." | |||
| 1533 | (window-normalize-window window) horizontal ignore pixelwise)) | 1533 | (window-normalize-window window) horizontal ignore pixelwise)) |
| 1534 | 1534 | ||
| 1535 | (defun window--min-size-ignore-p (window ignore) | 1535 | (defun window--min-size-ignore-p (window ignore) |
| 1536 | "Return non-nil if IGNORE says to ignore height restrictions for WINDOW." | 1536 | "Return non-nil if IGNORE says to ignore size restrictions for WINDOW." |
| 1537 | (if (window-valid-p ignore) | 1537 | (if (window-valid-p ignore) |
| 1538 | (eq window ignore) | 1538 | (eq window ignore) |
| 1539 | (not (memq ignore '(nil preserved))))) | 1539 | (not (memq ignore '(nil preserved))))) |
| @@ -8735,13 +8735,14 @@ means suspend autoselection." | |||
| 8735 | If the mouse position has stabilized in a non-selected window, select | 8735 | If the mouse position has stabilized in a non-selected window, select |
| 8736 | that window. The minibuffer window is selected only if the minibuffer | 8736 | that window. The minibuffer window is selected only if the minibuffer |
| 8737 | is active. This function is run by `mouse-autoselect-window-timer'." | 8737 | is active. This function is run by `mouse-autoselect-window-timer'." |
| 8738 | (ignore-errors | 8738 | (let* ((mouse-position (mouse-position)) |
| 8739 | (let* ((mouse-position (mouse-position)) | 8739 | (mouse-x (and (numberp (cadr mouse-position)) |
| 8740 | (window | 8740 | (cadr mouse-position))) |
| 8741 | (ignore-errors | 8741 | (mouse-y (and (numberp (cddr mouse-position)) |
| 8742 | (window-at (cadr mouse-position) (cddr mouse-position) | 8742 | (cddr mouse-position))) |
| 8743 | (car mouse-position))))) | 8743 | (frame (and mouse-x mouse-y (car mouse-position))) |
| 8744 | (cond | 8744 | (window (and frame (window-at mouse-x mouse-y frame)))) |
| 8745 | (cond | ||
| 8745 | ((or (and (fboundp 'menu-or-popup-active-p) (menu-or-popup-active-p)) | 8746 | ((or (and (fboundp 'menu-or-popup-active-p) (menu-or-popup-active-p)) |
| 8746 | (and window | 8747 | (and window |
| 8747 | (let ((coords (coordinates-in-window-p | 8748 | (let ((coords (coordinates-in-window-p |
| @@ -8752,72 +8753,63 @@ is active. This function is run by `mouse-autoselect-window-timer'." | |||
| 8752 | ;; text region of WINDOW: Suspend autoselection temporarily. | 8753 | ;; text region of WINDOW: Suspend autoselection temporarily. |
| 8753 | (mouse-autoselect-window-start mouse-position nil t)) | 8754 | (mouse-autoselect-window-start mouse-position nil t)) |
| 8754 | ((or (eq mouse-autoselect-window-state 'suspend) | 8755 | ((or (eq mouse-autoselect-window-state 'suspend) |
| 8755 | ;; When the mouse is at its first recorded position, restart | 8756 | ;; When the mouse is at its first recorded position, restart |
| 8756 | ;; delayed autoselection. This works around a scenario with | 8757 | ;; delayed autoselection. This works around a scenario with |
| 8757 | ;; two two-window frames with identical dimensions: select the | 8758 | ;; two two-window frames with identical dimensions: select the |
| 8758 | ;; first window of the first frame, switch to the second | 8759 | ;; first window of the first frame, switch to the second |
| 8759 | ;; frame, move the mouse to its second window, minimize the | 8760 | ;; frame, move the mouse to its second window, minimize the |
| 8760 | ;; second frame. Now the second window of the first frame | 8761 | ;; second frame. Now the second window of the first frame |
| 8761 | ;; gets selected although the mouse never really "moved" into | 8762 | ;; gets selected although the mouse never really "moved" into |
| 8762 | ;; that window. | 8763 | ;; that window. |
| 8763 | (and (numberp mouse-autoselect-window) | 8764 | (and (numberp mouse-autoselect-window) |
| 8764 | (equal (mouse-position) mouse-autoselect-window-position-1))) | 8765 | (equal (mouse-position) mouse-autoselect-window-position-1))) |
| 8765 | ;; Delayed autoselection was temporarily suspended, reenable it. | 8766 | ;; Delayed autoselection was temporarily suspended, reenable it. |
| 8766 | (mouse-autoselect-window-start mouse-position)) | 8767 | (mouse-autoselect-window-start mouse-position)) |
| 8767 | ((and window (not (eq window (selected-window))) | 8768 | ((and window |
| 8768 | (or (not (numberp mouse-autoselect-window)) | 8769 | (or (not (numberp mouse-autoselect-window)) |
| 8769 | (and (>= mouse-autoselect-window 0) | 8770 | (and (>= mouse-autoselect-window 0) |
| 8770 | ;; If `mouse-autoselect-window' is non-negative, | 8771 | ;; If `mouse-autoselect-window' is non-negative, |
| 8771 | ;; select window if it's the same as before. | 8772 | ;; select window if it's the same as before. |
| 8772 | (eq window mouse-autoselect-window-window)) | 8773 | (eq window mouse-autoselect-window-window)) |
| 8773 | ;; Otherwise select window iff the mouse is at the same | 8774 | ;; Otherwise select window iff the mouse is at the same |
| 8774 | ;; position as before. Observe that the first test | 8775 | ;; position as before. Observe that the first test |
| 8775 | ;; after starting autoselection usually fails since the | 8776 | ;; after starting autoselection usually fails since the |
| 8776 | ;; value of `mouse-autoselect-window-position' recorded | 8777 | ;; value of `mouse-autoselect-window-position' recorded |
| 8777 | ;; there is the position where the mouse has entered the | 8778 | ;; there is the position where the mouse has entered the |
| 8778 | ;; new window and not necessarily where the mouse has | 8779 | ;; new window and not necessarily where the mouse has |
| 8779 | ;; stopped moving. | 8780 | ;; stopped moving. |
| 8780 | (equal mouse-position mouse-autoselect-window-position)) | 8781 | (equal mouse-position mouse-autoselect-window-position)) |
| 8781 | ;; The minibuffer is a candidate window if it's active. | 8782 | ;; The minibuffer is a candidate window if it's active. |
| 8782 | (or (not (window-minibuffer-p window)) | 8783 | (or (not (window-minibuffer-p window)) |
| 8783 | (eq window (active-minibuffer-window)))) | 8784 | (eq window (active-minibuffer-window)))) |
| 8784 | ;; Mouse position has stabilized in non-selected window: Cancel | 8785 | ;; Mouse position has stabilized in non-selected window: Cancel |
| 8785 | ;; delayed autoselection and try to select that window. | 8786 | ;; delayed autoselection and try to select that window. |
| 8786 | (mouse-autoselect-window-cancel t) | 8787 | (mouse-autoselect-window-cancel t) |
| 8787 | ;; Select window where mouse appears unless the selected window is the | 8788 | ;; Use `unread-command-events' in order to execute pre- and |
| 8788 | ;; minibuffer. Use `unread-command-events' in order to execute pre- | 8789 | ;; post-command hooks and trigger idle timers. To avoid delaying |
| 8789 | ;; and post-command hooks and trigger idle timers. To avoid delaying | 8790 | ;; autoselection again, set `mouse-autoselect-window-state'." |
| 8790 | ;; autoselection again, set `mouse-autoselect-window-state'." | 8791 | (setq mouse-autoselect-window-state 'select) |
| 8791 | (unless (window-minibuffer-p) | 8792 | (setq unread-command-events |
| 8792 | (setq mouse-autoselect-window-state 'select) | 8793 | (cons (list 'select-window (list window)) |
| 8793 | (setq unread-command-events | 8794 | unread-command-events))) |
| 8794 | (cons (list 'select-window (list window)) | 8795 | ((or (not (numberp mouse-autoselect-window)) |
| 8795 | unread-command-events)))) | 8796 | (equal mouse-position mouse-autoselect-window-position)) |
| 8796 | ((or (and window (eq window (selected-window))) | 8797 | ;; Mouse position has stabilized at |
| 8797 | (not (numberp mouse-autoselect-window)) | 8798 | ;; `mouse-autoselect-window-position': Cancel delayed |
| 8798 | (equal mouse-position mouse-autoselect-window-position)) | 8799 | ;; autoselection. |
| 8799 | ;; Mouse position has either stabilized in the selected window or at | 8800 | (mouse-autoselect-window-cancel t)) |
| 8800 | ;; `mouse-autoselect-window-position': Cancel delayed autoselection. | 8801 | (window |
| 8801 | (mouse-autoselect-window-cancel t)) | 8802 | ;; Mouse position has not stabilized yet, resume delayed |
| 8802 | (t | 8803 | ;; autoselection. |
| 8803 | ;; Mouse position has not stabilized yet, resume delayed | 8804 | (mouse-autoselect-window-start mouse-position window))))) |
| 8804 | ;; autoselection. | ||
| 8805 | (mouse-autoselect-window-start mouse-position window)))))) | ||
| 8806 | 8805 | ||
| 8807 | (defun handle-select-window (event) | 8806 | (defun handle-select-window (event) |
| 8808 | "Handle select-window events." | 8807 | "Handle select-window events." |
| 8809 | (interactive "^e") | 8808 | (interactive "^e") |
| 8810 | (let ((window (posn-window (event-start event)))) | 8809 | (let* ((window (posn-window (event-start event))) |
| 8810 | (frame (and (window-live-p window) (window-frame window))) | ||
| 8811 | (old-frame (selected-frame))) | ||
| 8811 | (unless (or (not (window-live-p window)) | 8812 | (unless (or (not (window-live-p window)) |
| 8812 | ;; Don't switch if we're currently in the minibuffer. | ||
| 8813 | ;; This tries to work around problems where the | ||
| 8814 | ;; minibuffer gets unselected unexpectedly, and where | ||
| 8815 | ;; you then have to move your mouse all the way down to | ||
| 8816 | ;; the minibuffer to select it. | ||
| 8817 | (window-minibuffer-p) | ||
| 8818 | ;; Don't switch to minibuffer window unless it's active. | ||
| 8819 | (and (window-minibuffer-p window) | ||
| 8820 | (not (minibuffer-window-active-p window))) | ||
| 8821 | ;; Don't switch when autoselection shall be delayed. | 8813 | ;; Don't switch when autoselection shall be delayed. |
| 8822 | (and (numberp mouse-autoselect-window) | 8814 | (and (numberp mouse-autoselect-window) |
| 8823 | (not (eq mouse-autoselect-window-state 'select)) | 8815 | (not (eq mouse-autoselect-window-state 'select)) |
| @@ -8830,15 +8822,40 @@ is active. This function is run by `mouse-autoselect-window-timer'." | |||
| 8830 | (mouse-autoselect-window-start position window) | 8822 | (mouse-autoselect-window-start position window) |
| 8831 | ;; Executing a command cancels delayed autoselection. | 8823 | ;; Executing a command cancels delayed autoselection. |
| 8832 | (add-hook | 8824 | (add-hook |
| 8833 | 'pre-command-hook 'mouse-autoselect-window-cancel)))) | 8825 | 'pre-command-hook 'mouse-autoselect-window-cancel))) |
| 8834 | (when mouse-autoselect-window | 8826 | ;; Don't switch to a `no-accept-focus' frame unless it's |
| 8835 | ;; Reset state of delayed autoselection. | 8827 | ;; already selected. |
| 8836 | (setq mouse-autoselect-window-state nil) | 8828 | (and (not (eq frame (selected-frame))) |
| 8837 | ;; Run `mouse-leave-buffer-hook' when autoselecting window. | 8829 | (frame-parameter frame 'no-accept-focus)) |
| 8838 | (run-hooks 'mouse-leave-buffer-hook)) | 8830 | ;; Don't switch to minibuffer window unless it's active. |
| 8831 | (and (window-minibuffer-p window) | ||
| 8832 | (not (minibuffer-window-active-p window)))) | ||
| 8833 | ;; Reset state of delayed autoselection. | ||
| 8834 | (setq mouse-autoselect-window-state nil) | ||
| 8835 | ;; Run `mouse-leave-buffer-hook' when autoselecting window. | ||
| 8836 | (run-hooks 'mouse-leave-buffer-hook) | ||
| 8839 | ;; Clear echo area. | 8837 | ;; Clear echo area. |
| 8840 | (message nil) | 8838 | (message nil) |
| 8841 | (select-window window)))) | 8839 | ;; Select the window before giving the frame focus since otherwise |
| 8840 | ;; we might get two windows with an active cursor. | ||
| 8841 | (select-window window) | ||
| 8842 | (cond | ||
| 8843 | ((or (not (memq (window-system frame) '(x w32 ns))) | ||
| 8844 | (not focus-follows-mouse) | ||
| 8845 | ;; Focus FRAME if it's either a child frame or an ancestor | ||
| 8846 | ;; of the frame switched from. | ||
| 8847 | (and (not (frame-parameter frame 'parent-frame)) | ||
| 8848 | (not (frame-ancestor-p frame old-frame))))) | ||
| 8849 | ((eq focus-follows-mouse 'auto-raise) | ||
| 8850 | ;; Focus and auto-raise frame. | ||
| 8851 | (x-focus-frame frame) | ||
| 8852 | ;; This doesn't seem to work when we move from a normal frame | ||
| 8853 | ;; right into the child frame of another frame - we should raise | ||
| 8854 | ;; that child frame's ancestor frame first ... | ||
| 8855 | (raise-frame frame)) | ||
| 8856 | (t | ||
| 8857 | ;; Just focus frame. | ||
| 8858 | (x-focus-frame frame)))))) | ||
| 8842 | 8859 | ||
| 8843 | (defun truncated-partial-width-window-p (&optional window) | 8860 | (defun truncated-partial-width-window-p (&optional window) |
| 8844 | "Return non-nil if lines in WINDOW are specifically truncated due to its width. | 8861 | "Return non-nil if lines in WINDOW are specifically truncated due to its width. |
diff --git a/src/frame.c b/src/frame.c index 5f57d4a0c24..ed6c527d4d8 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -324,11 +324,51 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size, | |||
| 324 | return make_number (0); | 324 | return make_number (0); |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | /** | ||
| 328 | * frame_windows_min_size: | ||
| 329 | * | ||
| 330 | * Return the minimum number of lines (columns if HORIZONTAL is non-nil) | ||
| 331 | * of FRAME. If PIXELWISE is non-nil, return the minimum height (width) | ||
| 332 | * in pixels. | ||
| 333 | * | ||
| 334 | * This value is calculated by the function `frame-windows-min-size' in | ||
| 335 | * window.el unless the `min-height' (`min-width' if HORIZONTAL is | ||
| 336 | * non-nil) parameter of FRAME is non-nil thus explicitly specifying the | ||
| 337 | * value to be returned. In that latter case IGNORE is ignored. | ||
| 338 | * | ||
| 339 | * If `frame-windows-min-size' is called, it will make sure that the | ||
| 340 | * return value accomodates all windows of FRAME respecting the values | ||
| 341 | * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil). | ||
| 342 | * With IGNORE non-nil the values of these variables are ignored. | ||
| 343 | * | ||
| 344 | * In either case never return a value less than 1. | ||
| 345 | */ | ||
| 327 | static int | 346 | static int |
| 328 | frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, | 347 | frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, |
| 329 | Lisp_Object ignore, Lisp_Object pixelwise) | 348 | Lisp_Object ignore, Lisp_Object pixelwise) |
| 330 | { | 349 | { |
| 331 | return XINT (call4 (Qframe_windows_min_size, frame, horizontal, | 350 | struct frame *f = XFRAME (frame); |
| 351 | Lisp_Object par_size; | ||
| 352 | |||
| 353 | if ((!NILP (horizontal) | ||
| 354 | && NUMBERP (par_size = get_frame_param (f, Qmin_width))) | ||
| 355 | || (NILP (horizontal) | ||
| 356 | && NUMBERP (par_size = get_frame_param (f, Qmin_height)))) | ||
| 357 | { | ||
| 358 | int min_size = XINT (par_size); | ||
| 359 | |||
| 360 | /* Don't allow phantom frames. */ | ||
| 361 | if (min_size < 1) | ||
| 362 | min_size = 1; | ||
| 363 | |||
| 364 | return (NILP (pixelwise) | ||
| 365 | ? min_size | ||
| 366 | : min_size * (NILP (horizontal) | ||
| 367 | ? FRAME_LINE_HEIGHT (f) | ||
| 368 | : FRAME_COLUMN_WIDTH (f))); | ||
| 369 | } | ||
| 370 | else | ||
| 371 | return XINT (call4 (Qframe_windows_min_size, frame, horizontal, | ||
| 332 | ignore, pixelwise)); | 372 | ignore, pixelwise)); |
| 333 | } | 373 | } |
| 334 | 374 | ||
| @@ -643,6 +683,16 @@ make_frame (bool mini_p) | |||
| 643 | f->vertical_scroll_bar_type = vertical_scroll_bar_none; | 683 | f->vertical_scroll_bar_type = vertical_scroll_bar_none; |
| 644 | f->horizontal_scroll_bars = false; | 684 | f->horizontal_scroll_bars = false; |
| 645 | f->want_fullscreen = FULLSCREEN_NONE; | 685 | f->want_fullscreen = FULLSCREEN_NONE; |
| 686 | #if ! defined (HAVE_NS) | ||
| 687 | f->undecorated = false; | ||
| 688 | #ifndef HAVE_NTGUI | ||
| 689 | f->override_redirect = false; | ||
| 690 | #endif | ||
| 691 | f->skip_taskbar = false; | ||
| 692 | f->no_focus_on_map = false; | ||
| 693 | f->no_accept_focus = false; | ||
| 694 | f->z_group = z_group_none; | ||
| 695 | #endif | ||
| 646 | #if ! defined (USE_GTK) && ! defined (HAVE_NS) | 696 | #if ! defined (USE_GTK) && ! defined (HAVE_NS) |
| 647 | f->last_tool_bar_item = -1; | 697 | f->last_tool_bar_item = -1; |
| 648 | #endif | 698 | #endif |
| @@ -1215,7 +1265,10 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor | |||
| 1215 | (select-window (frame-root-window (new-frame))) doesn't end up | 1265 | (select-window (frame-root-window (new-frame))) doesn't end up |
| 1216 | with your typing being interpreted in the new frame instead of | 1266 | with your typing being interpreted in the new frame instead of |
| 1217 | the one you're actually typing in. */ | 1267 | the one you're actually typing in. */ |
| 1218 | internal_last_event_frame = Qnil; | 1268 | #ifdef HAVE_WINDOW_SYSTEM |
| 1269 | if (!frame_ancestor_p (f, sf)) | ||
| 1270 | #endif | ||
| 1271 | internal_last_event_frame = Qnil; | ||
| 1219 | 1272 | ||
| 1220 | return frame; | 1273 | return frame; |
| 1221 | } | 1274 | } |
| @@ -1283,6 +1336,72 @@ DEFUN ("frame-list", Fframe_list, Sframe_list, | |||
| 1283 | return frames; | 1336 | return frames; |
| 1284 | } | 1337 | } |
| 1285 | 1338 | ||
| 1339 | DEFUN ("frame-parent", Fframe_parent, Sframe_parent, | ||
| 1340 | 0, 1, 0, | ||
| 1341 | doc: /* Return the parent frame of FRAME. | ||
| 1342 | The parent frame of FRAME is the Emacs frame whose window-system window | ||
| 1343 | is the parent window of FRAME's window-system window. When such a frame | ||
| 1344 | exists, FRAME is considered a child frame of that frame. | ||
| 1345 | |||
| 1346 | Return nil if FRAME has no parent frame. This means that FRAME's | ||
| 1347 | window-system window is either a "top-level" window (a window whose | ||
| 1348 | parent window is the window-system's root window) or an embedded window | ||
| 1349 | \(a window whose parent window is owned by some other application). */) | ||
| 1350 | (Lisp_Object frame) | ||
| 1351 | { | ||
| 1352 | struct frame *f = decode_live_frame (frame); | ||
| 1353 | struct frame *p = FRAME_PARENT_FRAME (f); | ||
| 1354 | Lisp_Object parent; | ||
| 1355 | |||
| 1356 | /* Can't return f->parent_frame directly since it might not be defined | ||
| 1357 | for this platform. */ | ||
| 1358 | if (p) | ||
| 1359 | { | ||
| 1360 | XSETFRAME (parent, p); | ||
| 1361 | |||
| 1362 | return parent; | ||
| 1363 | } | ||
| 1364 | else | ||
| 1365 | return Qnil; | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 1369 | bool | ||
| 1370 | frame_ancestor_p (struct frame *af, struct frame *df) | ||
| 1371 | { | ||
| 1372 | struct frame *pf = FRAME_PARENT_FRAME (df); | ||
| 1373 | |||
| 1374 | while (pf) | ||
| 1375 | { | ||
| 1376 | if (pf == af) | ||
| 1377 | return true; | ||
| 1378 | else | ||
| 1379 | pf = FRAME_PARENT_FRAME (pf); | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | return false; | ||
| 1383 | } | ||
| 1384 | #endif | ||
| 1385 | |||
| 1386 | DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p, | ||
| 1387 | 2, 2, 0, | ||
| 1388 | doc: /* Return non-nil if ANCESTOR is an ancestor of DESCENDANT. | ||
| 1389 | ANCESTOR is an ancestor of DESCENDANT when it is either DESCENDANT's | ||
| 1390 | parent frame or it is an ancestor of DESCENDANT's parent frame. Both, | ||
| 1391 | ANCESTOR and DESCENDANT must be live frames and default to the selected | ||
| 1392 | frame. */) | ||
| 1393 | (Lisp_Object ancestor, Lisp_Object descendant) | ||
| 1394 | { | ||
| 1395 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 1396 | struct frame *af = decode_live_frame (ancestor); | ||
| 1397 | struct frame *df = decode_live_frame (descendant); | ||
| 1398 | |||
| 1399 | return frame_ancestor_p (af, df) ? Qt : Qnil; | ||
| 1400 | #else | ||
| 1401 | return Qnil; | ||
| 1402 | #endif | ||
| 1403 | } | ||
| 1404 | |||
| 1286 | /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the | 1405 | /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the |
| 1287 | same tty (for tty frames) or among frames which uses FRAME's keyboard. | 1406 | same tty (for tty frames) or among frames which uses FRAME's keyboard. |
| 1288 | If MINIBUF is nil, do not consider minibuffer-only candidate. | 1407 | If MINIBUF is nil, do not consider minibuffer-only candidate. |
| @@ -1303,7 +1422,9 @@ candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf) | |||
| 1303 | || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f) | 1422 | || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f) |
| 1304 | && FRAME_TTY (c) == FRAME_TTY (f))) | 1423 | && FRAME_TTY (c) == FRAME_TTY (f))) |
| 1305 | { | 1424 | { |
| 1306 | if (NILP (minibuf)) | 1425 | if (!NILP (get_frame_param (c, Qno_other_frame))) |
| 1426 | return Qnil; | ||
| 1427 | else if (NILP (minibuf)) | ||
| 1307 | { | 1428 | { |
| 1308 | if (!FRAME_MINIBUF_ONLY_P (c)) | 1429 | if (!FRAME_MINIBUF_ONLY_P (c)) |
| 1309 | return candidate; | 1430 | return candidate; |
| @@ -1441,35 +1562,65 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, | |||
| 1441 | return frame; | 1562 | return frame; |
| 1442 | } | 1563 | } |
| 1443 | 1564 | ||
| 1444 | /* Return 1 if it is ok to delete frame F; | 1565 | /** |
| 1445 | 0 if all frames aside from F are invisible. | 1566 | * other_frames: |
| 1446 | (Exception: if F is the terminal frame, and we are using X, return 1.) */ | 1567 | * |
| 1568 | * Return true if there exists at least one visible or iconified frame | ||
| 1569 | * but F. Return false otherwise. | ||
| 1570 | * | ||
| 1571 | * Always return false when all remaining frames are either tooltip or | ||
| 1572 | * child frames or frames with a non-nil `delete-before' parameter. If | ||
| 1573 | * INVISIBLE is false, also return false when the minibuffer window of | ||
| 1574 | * all remaining frames is on F. | ||
| 1575 | |||
| 1576 | * If F is the terminal frame and we are using X, return true if at | ||
| 1577 | * least one X frame exists. */ | ||
| 1578 | static bool | ||
| 1579 | other_frames (struct frame *f, bool invisible) | ||
| 1580 | { | ||
| 1581 | Lisp_Object frames, frame, frame1; | ||
| 1582 | struct frame *f1; | ||
| 1583 | Lisp_Object minibuffer_window = FRAME_MINIBUF_WINDOW (f); | ||
| 1447 | 1584 | ||
| 1448 | static int | 1585 | XSETFRAME (frame, f); |
| 1449 | other_visible_frames (struct frame *f) | 1586 | if (WINDOWP (minibuffer_window) |
| 1450 | { | 1587 | && !EQ (frame, WINDOW_FRAME (XWINDOW (minibuffer_window)))) |
| 1451 | Lisp_Object frames, this; | 1588 | minibuffer_window = Qnil; |
| 1452 | 1589 | ||
| 1453 | FOR_EACH_FRAME (frames, this) | 1590 | FOR_EACH_FRAME (frames, frame1) |
| 1454 | { | 1591 | { |
| 1455 | if (f == XFRAME (this)) | 1592 | f1 = XFRAME (frame1); |
| 1456 | continue; | 1593 | if (f != f1) |
| 1457 | 1594 | { | |
| 1458 | /* Verify that we can still talk to the frame's X window, | 1595 | /* Verify that we can still talk to the frame's X window, and |
| 1459 | and note any recent change in visibility. */ | 1596 | note any recent change in visibility. */ |
| 1460 | #ifdef HAVE_X_WINDOWS | 1597 | #ifdef HAVE_X_WINDOWS |
| 1461 | if (FRAME_WINDOW_P (XFRAME (this))) | 1598 | if (FRAME_WINDOW_P (f1)) |
| 1462 | x_sync (XFRAME (this)); | 1599 | x_sync (f1); |
| 1463 | #endif | 1600 | #endif |
| 1464 | 1601 | if (NILP (Fframe_parameter (frame1, Qtooltip)) | |
| 1465 | if (FRAME_VISIBLE_P (XFRAME (this)) | 1602 | /* Tooltips and child frames don't count. */ |
| 1466 | || FRAME_ICONIFIED_P (XFRAME (this)) | 1603 | && !FRAME_PARENT_FRAME (f1) |
| 1467 | /* Allow deleting the terminal frame when at least one X | 1604 | /* Frames with a non-nil `delete-before' parameter don't |
| 1468 | frame exists. */ | 1605 | count - either they depend on us or they depend on a |
| 1469 | || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f))) | 1606 | frame that we will have to find right here. */ |
| 1470 | return 1; | 1607 | && NILP (get_frame_param (f1, Qdelete_before)) |
| 1608 | /* Frames whose minibuffer window is on F don't count | ||
| 1609 | unless INVISIBLE is set - in that case F is either made | ||
| 1610 | invisible and may be autoraised from such a frame or | ||
| 1611 | the FORCE argument of delete_frame was non-nil. */ | ||
| 1612 | && (invisible || NILP (minibuffer_window) | ||
| 1613 | || !EQ (FRAME_MINIBUF_WINDOW (f1), minibuffer_window)) | ||
| 1614 | /* At least one visible/iconified frame must remain. */ | ||
| 1615 | && (FRAME_VISIBLE_P (f1) || FRAME_ICONIFIED_P (f1) | ||
| 1616 | /* Allow deleting the terminal frame when at least one | ||
| 1617 | X frame exists. */ | ||
| 1618 | || (FRAME_WINDOW_P (f1) && !FRAME_WINDOW_P (f)))) | ||
| 1619 | return true; | ||
| 1620 | } | ||
| 1471 | } | 1621 | } |
| 1472 | return 0; | 1622 | |
| 1623 | return false; | ||
| 1473 | } | 1624 | } |
| 1474 | 1625 | ||
| 1475 | /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer | 1626 | /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer |
| @@ -1518,53 +1669,65 @@ check_minibuf_window (Lisp_Object frame, int select) | |||
| 1518 | } | 1669 | } |
| 1519 | 1670 | ||
| 1520 | 1671 | ||
| 1521 | /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME | 1672 | /** |
| 1522 | unconditionally. x_connection_closed and delete_terminal use | 1673 | * delete_frame: |
| 1523 | this. Any other value of FORCE implements the semantics | 1674 | * |
| 1524 | described for Fdelete_frame. */ | 1675 | * Delete FRAME. When FORCE equals Qnoelisp, delete FRAME |
| 1676 | * unconditionally. x_connection_closed and delete_terminal use this. | ||
| 1677 | * Any other value of FORCE implements the semantics described for | ||
| 1678 | * Fdelete_frame. */ | ||
| 1525 | Lisp_Object | 1679 | Lisp_Object |
| 1526 | delete_frame (Lisp_Object frame, Lisp_Object force) | 1680 | delete_frame (Lisp_Object frame, Lisp_Object force) |
| 1527 | { | 1681 | { |
| 1528 | struct frame *f = decode_any_frame (frame); | 1682 | struct frame *f = decode_any_frame (frame); |
| 1529 | struct frame *sf; | 1683 | struct frame *sf; |
| 1530 | struct kboard *kb; | 1684 | struct kboard *kb; |
| 1531 | 1685 | Lisp_Object frames, frame1; | |
| 1532 | int minibuffer_selected, is_tooltip_frame; | 1686 | int minibuffer_selected, is_tooltip_frame; |
| 1687 | bool nochild = !FRAME_PARENT_FRAME (f); | ||
| 1533 | 1688 | ||
| 1534 | if (! FRAME_LIVE_P (f)) | 1689 | if (!FRAME_LIVE_P (f)) |
| 1535 | return Qnil; | 1690 | return Qnil; |
| 1536 | 1691 | else if (!EQ (force, Qnoelisp) && !other_frames (f, !NILP (force))) | |
| 1537 | if (NILP (force) && !other_visible_frames (f)) | 1692 | { |
| 1538 | error ("Attempt to delete the sole visible or iconified frame"); | 1693 | if (NILP (force)) |
| 1539 | 1694 | error ("Attempt to delete the sole visible or iconified frame"); | |
| 1540 | /* x_connection_closed must have set FORCE to `noelisp' in order | 1695 | else |
| 1541 | to delete the last frame, if it is gone. */ | 1696 | error ("Attempt to delete the only frame"); |
| 1542 | if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp)) | 1697 | } |
| 1543 | error ("Attempt to delete the only frame"); | ||
| 1544 | 1698 | ||
| 1545 | XSETFRAME (frame, f); | 1699 | XSETFRAME (frame, f); |
| 1546 | 1700 | ||
| 1701 | /* Softly delete all frames with this frame as their parent frame or | ||
| 1702 | as their `delete-before' frame parameter value. */ | ||
| 1703 | FOR_EACH_FRAME (frames, frame1) | ||
| 1704 | if (FRAME_PARENT_FRAME (XFRAME (frame1)) == f | ||
| 1705 | /* Process `delete-before' parameter iff FRAME is not a child | ||
| 1706 | frame. This avoids that we enter an infinite chain of mixed | ||
| 1707 | dependencies. */ | ||
| 1708 | || (nochild | ||
| 1709 | && EQ (get_frame_param (XFRAME (frame1), Qdelete_before), frame))) | ||
| 1710 | delete_frame (frame1, Qnil); | ||
| 1711 | |||
| 1547 | /* Does this frame have a minibuffer, and is it the surrogate | 1712 | /* Does this frame have a minibuffer, and is it the surrogate |
| 1548 | minibuffer for any other frame? */ | 1713 | minibuffer for any other frame? */ |
| 1549 | if (FRAME_HAS_MINIBUF_P (f)) | 1714 | if (FRAME_HAS_MINIBUF_P (f)) |
| 1550 | { | 1715 | { |
| 1551 | Lisp_Object frames, this; | 1716 | FOR_EACH_FRAME (frames, frame1) |
| 1552 | |||
| 1553 | FOR_EACH_FRAME (frames, this) | ||
| 1554 | { | 1717 | { |
| 1555 | Lisp_Object fminiw; | 1718 | Lisp_Object fminiw; |
| 1556 | 1719 | ||
| 1557 | if (EQ (this, frame)) | 1720 | if (EQ (frame1, frame)) |
| 1558 | continue; | 1721 | continue; |
| 1559 | 1722 | ||
| 1560 | fminiw = FRAME_MINIBUF_WINDOW (XFRAME (this)); | 1723 | fminiw = FRAME_MINIBUF_WINDOW (XFRAME (frame1)); |
| 1561 | 1724 | ||
| 1562 | if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw)))) | 1725 | if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw)))) |
| 1563 | { | 1726 | { |
| 1564 | /* If we MUST delete this frame, delete the other first. | 1727 | /* If we MUST delete this frame, delete the other first. |
| 1565 | But do this only if FORCE equals `noelisp'. */ | 1728 | But do this only if FORCE equals `noelisp'. */ |
| 1566 | if (EQ (force, Qnoelisp)) | 1729 | if (EQ (force, Qnoelisp)) |
| 1567 | delete_frame (this, Qnoelisp); | 1730 | delete_frame (frame1, Qnoelisp); |
| 1568 | else | 1731 | else |
| 1569 | error ("Attempt to delete a surrogate minibuffer frame"); | 1732 | error ("Attempt to delete a surrogate minibuffer frame"); |
| 1570 | } | 1733 | } |
| @@ -1593,20 +1756,26 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1593 | safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame); | 1756 | safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame); |
| 1594 | } | 1757 | } |
| 1595 | 1758 | ||
| 1596 | /* The hook may sometimes (indirectly) cause the frame to be deleted. */ | 1759 | /* delete_frame_functions may have deleted any frame, including this |
| 1597 | if (! FRAME_LIVE_P (f)) | 1760 | one. */ |
| 1761 | if (!FRAME_LIVE_P (f)) | ||
| 1598 | return Qnil; | 1762 | return Qnil; |
| 1763 | else if (!EQ (force, Qnoelisp) && !other_frames (f, !NILP (force))) | ||
| 1764 | { | ||
| 1765 | if (NILP (force)) | ||
| 1766 | error ("Attempt to delete the sole visible or iconified frame"); | ||
| 1767 | else | ||
| 1768 | error ("Attempt to delete the only frame"); | ||
| 1769 | } | ||
| 1599 | 1770 | ||
| 1600 | /* At this point, we are committed to deleting the frame. | 1771 | /* At this point, we are committed to deleting the frame. |
| 1601 | There is no more chance for errors to prevent it. */ | 1772 | There is no more chance for errors to prevent it. */ |
| 1602 | |||
| 1603 | minibuffer_selected = EQ (minibuf_window, selected_window); | 1773 | minibuffer_selected = EQ (minibuf_window, selected_window); |
| 1604 | sf = SELECTED_FRAME (); | 1774 | sf = SELECTED_FRAME (); |
| 1605 | /* Don't let the frame remain selected. */ | 1775 | /* Don't let the frame remain selected. */ |
| 1606 | if (f == sf) | 1776 | if (f == sf) |
| 1607 | { | 1777 | { |
| 1608 | Lisp_Object tail; | 1778 | Lisp_Object tail; |
| 1609 | Lisp_Object frame1 = Qnil; | ||
| 1610 | 1779 | ||
| 1611 | /* Look for another visible frame on the same terminal. | 1780 | /* Look for another visible frame on the same terminal. |
| 1612 | Do not call next_frame here because it may loop forever. | 1781 | Do not call next_frame here because it may loop forever. |
| @@ -1746,16 +1915,15 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1746 | another one. */ | 1915 | another one. */ |
| 1747 | if (f == last_nonminibuf_frame) | 1916 | if (f == last_nonminibuf_frame) |
| 1748 | { | 1917 | { |
| 1749 | Lisp_Object frames, this; | ||
| 1750 | |||
| 1751 | last_nonminibuf_frame = 0; | 1918 | last_nonminibuf_frame = 0; |
| 1752 | 1919 | ||
| 1753 | FOR_EACH_FRAME (frames, this) | 1920 | FOR_EACH_FRAME (frames, frame1) |
| 1754 | { | 1921 | { |
| 1755 | f = XFRAME (this); | 1922 | struct frame *f1 = XFRAME (frame1); |
| 1756 | if (!FRAME_MINIBUF_ONLY_P (f)) | 1923 | |
| 1924 | if (!FRAME_MINIBUF_ONLY_P (f1)) | ||
| 1757 | { | 1925 | { |
| 1758 | last_nonminibuf_frame = f; | 1926 | last_nonminibuf_frame = f1; |
| 1759 | break; | 1927 | break; |
| 1760 | } | 1928 | } |
| 1761 | } | 1929 | } |
| @@ -1765,13 +1933,12 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1765 | single-kboard state if we're in it for this kboard. */ | 1933 | single-kboard state if we're in it for this kboard. */ |
| 1766 | if (kb != NULL) | 1934 | if (kb != NULL) |
| 1767 | { | 1935 | { |
| 1768 | Lisp_Object frames, this; | ||
| 1769 | /* Some frame we found on the same kboard, or nil if there are none. */ | 1936 | /* Some frame we found on the same kboard, or nil if there are none. */ |
| 1770 | Lisp_Object frame_on_same_kboard = Qnil; | 1937 | Lisp_Object frame_on_same_kboard = Qnil; |
| 1771 | 1938 | ||
| 1772 | FOR_EACH_FRAME (frames, this) | 1939 | FOR_EACH_FRAME (frames, frame1) |
| 1773 | if (kb == FRAME_KBOARD (XFRAME (this))) | 1940 | if (kb == FRAME_KBOARD (XFRAME (frame1))) |
| 1774 | frame_on_same_kboard = this; | 1941 | frame_on_same_kboard = frame1; |
| 1775 | 1942 | ||
| 1776 | if (NILP (frame_on_same_kboard)) | 1943 | if (NILP (frame_on_same_kboard)) |
| 1777 | not_single_kboard_state (kb); | 1944 | not_single_kboard_state (kb); |
| @@ -1783,29 +1950,27 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1783 | frames with other windows. */ | 1950 | frames with other windows. */ |
| 1784 | if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame))) | 1951 | if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame))) |
| 1785 | { | 1952 | { |
| 1786 | Lisp_Object frames, this; | ||
| 1787 | |||
| 1788 | /* The last frame we saw with a minibuffer, minibuffer-only or not. */ | 1953 | /* The last frame we saw with a minibuffer, minibuffer-only or not. */ |
| 1789 | Lisp_Object frame_with_minibuf = Qnil; | 1954 | Lisp_Object frame_with_minibuf = Qnil; |
| 1790 | /* Some frame we found on the same kboard, or nil if there are none. */ | 1955 | /* Some frame we found on the same kboard, or nil if there are none. */ |
| 1791 | Lisp_Object frame_on_same_kboard = Qnil; | 1956 | Lisp_Object frame_on_same_kboard = Qnil; |
| 1792 | 1957 | ||
| 1793 | FOR_EACH_FRAME (frames, this) | 1958 | FOR_EACH_FRAME (frames, frame1) |
| 1794 | { | 1959 | { |
| 1795 | struct frame *f1 = XFRAME (this); | 1960 | struct frame *f1 = XFRAME (frame1); |
| 1796 | 1961 | ||
| 1797 | /* Consider only frames on the same kboard | 1962 | /* Consider only frames on the same kboard |
| 1798 | and only those with minibuffers. */ | 1963 | and only those with minibuffers. */ |
| 1799 | if (kb == FRAME_KBOARD (f1) | 1964 | if (kb == FRAME_KBOARD (f1) |
| 1800 | && FRAME_HAS_MINIBUF_P (f1)) | 1965 | && FRAME_HAS_MINIBUF_P (f1)) |
| 1801 | { | 1966 | { |
| 1802 | frame_with_minibuf = this; | 1967 | frame_with_minibuf = frame1; |
| 1803 | if (FRAME_MINIBUF_ONLY_P (f1)) | 1968 | if (FRAME_MINIBUF_ONLY_P (f1)) |
| 1804 | break; | 1969 | break; |
| 1805 | } | 1970 | } |
| 1806 | 1971 | ||
| 1807 | if (kb == FRAME_KBOARD (f1)) | 1972 | if (kb == FRAME_KBOARD (f1)) |
| 1808 | frame_on_same_kboard = this; | 1973 | frame_on_same_kboard = frame1; |
| 1809 | } | 1974 | } |
| 1810 | 1975 | ||
| 1811 | if (!NILP (frame_on_same_kboard)) | 1976 | if (!NILP (frame_on_same_kboard)) |
| @@ -2118,7 +2283,7 @@ displayed in the terminal. */) | |||
| 2118 | { | 2283 | { |
| 2119 | struct frame *f = decode_live_frame (frame); | 2284 | struct frame *f = decode_live_frame (frame); |
| 2120 | 2285 | ||
| 2121 | if (NILP (force) && !other_visible_frames (f)) | 2286 | if (NILP (force) && !other_frames (f, true)) |
| 2122 | error ("Attempt to make invisible the sole visible or iconified frame"); | 2287 | error ("Attempt to make invisible the sole visible or iconified frame"); |
| 2123 | 2288 | ||
| 2124 | /* Don't allow minibuf_window to remain on an invisible frame. */ | 2289 | /* Don't allow minibuf_window to remain on an invisible frame. */ |
| @@ -2453,9 +2618,39 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) | |||
| 2453 | } | 2618 | } |
| 2454 | } | 2619 | } |
| 2455 | 2620 | ||
| 2621 | /* Check these parameters for circular dependeny. This does not check | ||
| 2622 | for interdependencies between these properties. Hence you can | ||
| 2623 | still create circular dependencies with different properties, for | ||
| 2624 | example a chain of frames F1->F2->...Fn such that F1 is an ancestor | ||
| 2625 | frame of Fn and thus cannot be deleted before Fn and a second chain | ||
| 2626 | Fn->Fn-1->...F1 such that Fn cannot be deleted before F1. */ | ||
| 2627 | else if (EQ (prop, Qparent_frame) || EQ (prop, Qdelete_before)) | ||
| 2628 | { | ||
| 2629 | Lisp_Object oldval = Fcdr (Fassq (prop, f->param_alist)); | ||
| 2630 | |||
| 2631 | if (!EQ (oldval, val) && !NILP (val)) | ||
| 2632 | { | ||
| 2633 | Lisp_Object frame; | ||
| 2634 | Lisp_Object frame1 = val; | ||
| 2635 | |||
| 2636 | if (!FRAMEP (frame1) || !FRAME_LIVE_P (XFRAME (frame1))) | ||
| 2637 | error ("Invalid `%s' frame parameter", | ||
| 2638 | SSDATA (SYMBOL_NAME (prop))); | ||
| 2639 | |||
| 2640 | XSETFRAME (frame, f); | ||
| 2641 | |||
| 2642 | while (FRAMEP (frame1) && FRAME_LIVE_P (XFRAME (frame1))) | ||
| 2643 | if (EQ (frame1, frame)) | ||
| 2644 | error ("Circular specification of `%s' frame parameter", | ||
| 2645 | SSDATA (SYMBOL_NAME (prop))); | ||
| 2646 | else | ||
| 2647 | frame1 = get_frame_param (XFRAME (frame1), prop); | ||
| 2648 | } | ||
| 2649 | } | ||
| 2650 | |||
| 2456 | /* The buffer-list parameters are stored in a special place and not | 2651 | /* The buffer-list parameters are stored in a special place and not |
| 2457 | in the alist. All buffers must be live. */ | 2652 | in the alist. All buffers must be live. */ |
| 2458 | if (EQ (prop, Qbuffer_list)) | 2653 | else if (EQ (prop, Qbuffer_list)) |
| 2459 | { | 2654 | { |
| 2460 | Lisp_Object list = Qnil; | 2655 | Lisp_Object list = Qnil; |
| 2461 | for (; CONSP (val); val = XCDR (val)) | 2656 | for (; CONSP (val); val = XCDR (val)) |
| @@ -2464,7 +2659,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) | |||
| 2464 | fset_buffer_list (f, Fnreverse (list)); | 2659 | fset_buffer_list (f, Fnreverse (list)); |
| 2465 | return; | 2660 | return; |
| 2466 | } | 2661 | } |
| 2467 | if (EQ (prop, Qburied_buffer_list)) | 2662 | else if (EQ (prop, Qburied_buffer_list)) |
| 2468 | { | 2663 | { |
| 2469 | Lisp_Object list = Qnil; | 2664 | Lisp_Object list = Qnil; |
| 2470 | for (; CONSP (val); val = XCDR (val)) | 2665 | for (; CONSP (val); val = XCDR (val)) |
| @@ -3095,6 +3290,13 @@ static const struct frame_parm_table frame_parms[] = | |||
| 3095 | {"sticky", SYMBOL_INDEX (Qsticky)}, | 3290 | {"sticky", SYMBOL_INDEX (Qsticky)}, |
| 3096 | {"tool-bar-position", SYMBOL_INDEX (Qtool_bar_position)}, | 3291 | {"tool-bar-position", SYMBOL_INDEX (Qtool_bar_position)}, |
| 3097 | {"inhibit-double-buffering", SYMBOL_INDEX (Qinhibit_double_buffering)}, | 3292 | {"inhibit-double-buffering", SYMBOL_INDEX (Qinhibit_double_buffering)}, |
| 3293 | {"undecorated", SYMBOL_INDEX (Qundecorated)}, | ||
| 3294 | {"parent-frame", SYMBOL_INDEX (Qparent_frame)}, | ||
| 3295 | {"skip-taskbar", SYMBOL_INDEX (Qskip_taskbar)}, | ||
| 3296 | {"no-focus-on-map", SYMBOL_INDEX (Qno_focus_on_map)}, | ||
| 3297 | {"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus)}, | ||
| 3298 | {"z-group", SYMBOL_INDEX (Qz_group)}, | ||
| 3299 | {"override-redirect", SYMBOL_INDEX (Qoverride_redirect)}, | ||
| 3098 | }; | 3300 | }; |
| 3099 | 3301 | ||
| 3100 | #ifdef HAVE_WINDOW_SYSTEM | 3302 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -4882,6 +5084,14 @@ syms_of_frame (void) | |||
| 4882 | DEFSYM (Qheight, "height"); | 5084 | DEFSYM (Qheight, "height"); |
| 4883 | DEFSYM (Qicon, "icon"); | 5085 | DEFSYM (Qicon, "icon"); |
| 4884 | DEFSYM (Qminibuffer, "minibuffer"); | 5086 | DEFSYM (Qminibuffer, "minibuffer"); |
| 5087 | DEFSYM (Qundecorated, "undecorated"); | ||
| 5088 | DEFSYM (Qparent_frame, "parent-frame"); | ||
| 5089 | DEFSYM (Qskip_taskbar, "skip-taskbar"); | ||
| 5090 | DEFSYM (Qno_focus_on_map, "no-focus-on-map"); | ||
| 5091 | DEFSYM (Qno_accept_focus, "no-accept-focus"); | ||
| 5092 | DEFSYM (Qz_group, "z-group"); | ||
| 5093 | DEFSYM (Qoverride_redirect, "override-redirect"); | ||
| 5094 | DEFSYM (Qdelete_before, "delete-before"); | ||
| 4885 | DEFSYM (Qmodeline, "modeline"); | 5095 | DEFSYM (Qmodeline, "modeline"); |
| 4886 | DEFSYM (Qonly, "only"); | 5096 | DEFSYM (Qonly, "only"); |
| 4887 | DEFSYM (Qnone, "none"); | 5097 | DEFSYM (Qnone, "none"); |
| @@ -4978,6 +5188,7 @@ syms_of_frame (void) | |||
| 4978 | DEFSYM (Qauto_raise, "auto-raise"); | 5188 | DEFSYM (Qauto_raise, "auto-raise"); |
| 4979 | DEFSYM (Qborder_color, "border-color"); | 5189 | DEFSYM (Qborder_color, "border-color"); |
| 4980 | DEFSYM (Qborder_width, "border-width"); | 5190 | DEFSYM (Qborder_width, "border-width"); |
| 5191 | DEFSYM (Qouter_border_width, "outer-border-width"); | ||
| 4981 | DEFSYM (Qbottom_divider_width, "bottom-divider-width"); | 5192 | DEFSYM (Qbottom_divider_width, "bottom-divider-width"); |
| 4982 | DEFSYM (Qcursor_color, "cursor-color"); | 5193 | DEFSYM (Qcursor_color, "cursor-color"); |
| 4983 | DEFSYM (Qcursor_type, "cursor-type"); | 5194 | DEFSYM (Qcursor_type, "cursor-type"); |
| @@ -5011,6 +5222,12 @@ syms_of_frame (void) | |||
| 5011 | DEFSYM (Qvisibility, "visibility"); | 5222 | DEFSYM (Qvisibility, "visibility"); |
| 5012 | DEFSYM (Qwait_for_wm, "wait-for-wm"); | 5223 | DEFSYM (Qwait_for_wm, "wait-for-wm"); |
| 5013 | DEFSYM (Qinhibit_double_buffering, "inhibit-double-buffering"); | 5224 | DEFSYM (Qinhibit_double_buffering, "inhibit-double-buffering"); |
| 5225 | DEFSYM (Qno_other_frame, "no-other-frame"); | ||
| 5226 | DEFSYM (Qbelow, "below"); | ||
| 5227 | DEFSYM (Qabove_suspended, "above-suspended"); | ||
| 5228 | DEFSYM (Qmin_width, "min-width"); | ||
| 5229 | DEFSYM (Qmin_height, "min-height"); | ||
| 5230 | DEFSYM (Qmouse_wheel_frame, "mouse-wheel-frame"); | ||
| 5014 | 5231 | ||
| 5015 | { | 5232 | { |
| 5016 | int i; | 5233 | int i; |
| @@ -5179,12 +5396,51 @@ displayed. | |||
| 5179 | 5396 | ||
| 5180 | This variable is local to the current terminal and cannot be buffer-local. */); | 5397 | This variable is local to the current terminal and cannot be buffer-local. */); |
| 5181 | 5398 | ||
| 5182 | DEFVAR_BOOL ("focus-follows-mouse", focus_follows_mouse, | 5399 | DEFVAR_LISP ("focus-follows-mouse", focus_follows_mouse, |
| 5183 | doc: /* Non-nil if window system changes focus when you move the mouse. | 5400 | doc: /* Non-nil if window system changes focus when you move the mouse. |
| 5184 | You should set this variable to tell Emacs how your window manager | 5401 | You should set this variable to tell Emacs how your window manager |
| 5185 | handles focus, since there is no way in general for Emacs to find out | 5402 | handles focus, since there is no way in general for Emacs to find out |
| 5186 | automatically. See also `mouse-autoselect-window'. */); | 5403 | automatically. |
| 5187 | focus_follows_mouse = 0; | 5404 | |
| 5405 | There are three meaningful values: | ||
| 5406 | |||
| 5407 | - The default nil should be used when your window manager follows a | ||
| 5408 | "click-to-focus" policy where you have to click the mouse inside of a | ||
| 5409 | frame in order for that frame to get focus. | ||
| 5410 | |||
| 5411 | - The value t should be used when your window manager has the focus | ||
| 5412 | automatically follow the position of the mouse pointer but a window | ||
| 5413 | that gains focus is not raised automatically. | ||
| 5414 | |||
| 5415 | - The value `auto-raise' should be used when your window manager has the | ||
| 5416 | focus automatically follow the position of the mouse pointer and a | ||
| 5417 | window that gains focus is raised automatically. | ||
| 5418 | |||
| 5419 | If this option is non-nil, Emacs moves the mouse pointer to the frame | ||
| 5420 | selected by `select-frame-set-input-focus'. This function is used by a | ||
| 5421 | number of commands like, for example, `other-frame' and `pop-to-buffer'. | ||
| 5422 | If this option is nil and your focus follows mouse window manager does | ||
| 5423 | not autonomously move the mouse pointer to the newly selected frame, the | ||
| 5424 | previously selected window manager window might get reselected instead | ||
| 5425 | immediately. | ||
| 5426 | |||
| 5427 | The distinction between the values t and `auto-raise' is not needed for | ||
| 5428 | "normal" frames because the window manager takes care of raising them. | ||
| 5429 | Setting this to `auto-raise' will, however, override the standard | ||
| 5430 | behavior of a window manager that does not automatically raise the frame | ||
| 5431 | that gets focus. Setting this to `auto-raise' is also necessary to | ||
| 5432 | automatically raise child frames which are usually left alone by the | ||
| 5433 | window manager. | ||
| 5434 | |||
| 5435 | Note that this option does not distinguish "sloppy" focus (where the | ||
| 5436 | frame that previously had focus retains focus as long as the mouse | ||
| 5437 | pointer does not move into another window manager window) from "strict" | ||
| 5438 | focus (where a frame immediately loses focus when it's left by the mouse | ||
| 5439 | pointer). | ||
| 5440 | |||
| 5441 | In order to extend a "focus follows mouse" policy to individual Emacs | ||
| 5442 | windows, customize the variable `mouse-autoselect-window'. */); | ||
| 5443 | focus_follows_mouse = Qnil; | ||
| 5188 | 5444 | ||
| 5189 | DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise, | 5445 | DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise, |
| 5190 | doc: /* Non-nil means resize frames pixelwise. | 5446 | doc: /* Non-nil means resize frames pixelwise. |
| @@ -5286,6 +5542,8 @@ Gtk+ tooltips are not used) and on Windows. */); | |||
| 5286 | defsubr (&Sselect_frame); | 5542 | defsubr (&Sselect_frame); |
| 5287 | defsubr (&Sselected_frame); | 5543 | defsubr (&Sselected_frame); |
| 5288 | defsubr (&Sframe_list); | 5544 | defsubr (&Sframe_list); |
| 5545 | defsubr (&Sframe_parent); | ||
| 5546 | defsubr (&Sframe_ancestor_p); | ||
| 5289 | defsubr (&Snext_frame); | 5547 | defsubr (&Snext_frame); |
| 5290 | defsubr (&Sprevious_frame); | 5548 | defsubr (&Sprevious_frame); |
| 5291 | defsubr (&Slast_nonminibuf_frame); | 5549 | defsubr (&Slast_nonminibuf_frame); |
diff --git a/src/frame.h b/src/frame.h index 5f18901a17c..376df528466 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -45,6 +45,13 @@ enum fullscreen_type | |||
| 45 | #endif | 45 | #endif |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | enum z_group | ||
| 49 | { | ||
| 50 | z_group_none, | ||
| 51 | z_group_above, | ||
| 52 | z_group_below, | ||
| 53 | z_group_above_suspended, | ||
| 54 | }; | ||
| 48 | #endif /* HAVE_WINDOW_SYSTEM */ | 55 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 49 | 56 | ||
| 50 | /* The structure representing a frame. */ | 57 | /* The structure representing a frame. */ |
| @@ -68,6 +75,11 @@ struct frame | |||
| 68 | Usually it is nil. */ | 75 | Usually it is nil. */ |
| 69 | Lisp_Object title; | 76 | Lisp_Object title; |
| 70 | 77 | ||
| 78 | #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS) | ||
| 79 | /* This frame's parent frame, if it has one. */ | ||
| 80 | Lisp_Object parent_frame; | ||
| 81 | #endif /* HAVE_WINDOW_SYSTEM and not HAVE_NS */ | ||
| 82 | |||
| 71 | /* The frame which should receive keystrokes that occur in this | 83 | /* The frame which should receive keystrokes that occur in this |
| 72 | frame, or nil if they should go to the frame itself. This is | 84 | frame, or nil if they should go to the frame itself. This is |
| 73 | usually nil, but if the frame is minibufferless, we can use this | 85 | usually nil, but if the frame is minibufferless, we can use this |
| @@ -320,6 +332,30 @@ struct frame | |||
| 320 | bool_bf horizontal_scroll_bars : 1; | 332 | bool_bf horizontal_scroll_bars : 1; |
| 321 | #endif /* HAVE_WINDOW_SYSTEM */ | 333 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 322 | 334 | ||
| 335 | #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS) | ||
| 336 | /* True if this is an undecorated frame. */ | ||
| 337 | bool_bf undecorated : 1; | ||
| 338 | |||
| 339 | #ifndef HAVE_NTGUI | ||
| 340 | /* True if this is an override_redirect frame. */ | ||
| 341 | bool_bf override_redirect : 1; | ||
| 342 | #endif | ||
| 343 | |||
| 344 | /* Nonzero if this frame's icon should not appear on its display's taskbar. */ | ||
| 345 | bool_bf skip_taskbar : 1; | ||
| 346 | |||
| 347 | /* Nonzero if this frame's window F's X window does not want to | ||
| 348 | receive input focus when it is mapped. */ | ||
| 349 | bool_bf no_focus_on_map : 1; | ||
| 350 | |||
| 351 | /* Nonzero if this frame's window does not want to receive input focus | ||
| 352 | via mouse clicks or by moving the mouse into it. */ | ||
| 353 | bool_bf no_accept_focus : 1; | ||
| 354 | |||
| 355 | /* The z-group this frame's window belongs to. */ | ||
| 356 | ENUM_BF (z_group) z_group : 2; | ||
| 357 | #endif /* HAVE_WINDOW_SYSTEM and not HAVE_NS */ | ||
| 358 | |||
| 323 | /* Whether new_height and new_width shall be interpreted | 359 | /* Whether new_height and new_width shall be interpreted |
| 324 | in pixels. */ | 360 | in pixels. */ |
| 325 | bool_bf new_pixelwise : 1; | 361 | bool_bf new_pixelwise : 1; |
| @@ -534,6 +570,13 @@ fset_face_alist (struct frame *f, Lisp_Object val) | |||
| 534 | { | 570 | { |
| 535 | f->face_alist = val; | 571 | f->face_alist = val; |
| 536 | } | 572 | } |
| 573 | #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS) | ||
| 574 | INLINE void | ||
| 575 | fset_parent_frame (struct frame *f, Lisp_Object val) | ||
| 576 | { | ||
| 577 | f->parent_frame = val; | ||
| 578 | } | ||
| 579 | #endif | ||
| 537 | INLINE void | 580 | INLINE void |
| 538 | fset_focus_frame (struct frame *f, Lisp_Object val) | 581 | fset_focus_frame (struct frame *f, Lisp_Object val) |
| 539 | { | 582 | { |
| @@ -854,7 +897,6 @@ default_pixels_per_inch_y (void) | |||
| 854 | #define FRAME_FOCUS_FRAME(f) f->focus_frame | 897 | #define FRAME_FOCUS_FRAME(f) f->focus_frame |
| 855 | 898 | ||
| 856 | #ifdef HAVE_WINDOW_SYSTEM | 899 | #ifdef HAVE_WINDOW_SYSTEM |
| 857 | |||
| 858 | /* This frame slot says whether scroll bars are currently enabled for frame F, | 900 | /* This frame slot says whether scroll bars are currently enabled for frame F, |
| 859 | and which side they are on. */ | 901 | and which side they are on. */ |
| 860 | #define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((f)->vertical_scroll_bar_type) | 902 | #define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((f)->vertical_scroll_bar_type) |
| @@ -864,17 +906,47 @@ default_pixels_per_inch_y (void) | |||
| 864 | ((f)->vertical_scroll_bar_type == vertical_scroll_bar_left) | 906 | ((f)->vertical_scroll_bar_type == vertical_scroll_bar_left) |
| 865 | #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \ | 907 | #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \ |
| 866 | ((f)->vertical_scroll_bar_type == vertical_scroll_bar_right) | 908 | ((f)->vertical_scroll_bar_type == vertical_scroll_bar_right) |
| 867 | |||
| 868 | #else /* not HAVE_WINDOW_SYSTEM */ | 909 | #else /* not HAVE_WINDOW_SYSTEM */ |
| 869 | |||
| 870 | /* If there is no window system, there are no scroll bars. */ | 910 | /* If there is no window system, there are no scroll bars. */ |
| 871 | #define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((void) f, vertical_scroll_bar_none) | 911 | #define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((void) f, vertical_scroll_bar_none) |
| 872 | #define FRAME_HAS_VERTICAL_SCROLL_BARS(f) ((void) f, 0) | 912 | #define FRAME_HAS_VERTICAL_SCROLL_BARS(f) ((void) f, 0) |
| 873 | #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) f, 0) | 913 | #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) f, 0) |
| 874 | #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) f, 0) | 914 | #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) f, 0) |
| 875 | |||
| 876 | #endif /* HAVE_WINDOW_SYSTEM */ | 915 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 877 | 916 | ||
| 917 | #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS) | ||
| 918 | #define FRAME_UNDECORATED(f) ((f)->undecorated) | ||
| 919 | #ifdef HAVE_NTGUI | ||
| 920 | #define FRAME_OVERRIDE_REDIRECT(f) ((void) f, 0) | ||
| 921 | #else | ||
| 922 | #define FRAME_OVERRIDE_REDIRECT(f) ((f)->override_redirect) | ||
| 923 | #endif | ||
| 924 | #define FRAME_PARENT_FRAME(f) \ | ||
| 925 | (NILP ((f)->parent_frame) \ | ||
| 926 | ? NULL \ | ||
| 927 | : XFRAME ((f)->parent_frame)) | ||
| 928 | #define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar) | ||
| 929 | #define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map) | ||
| 930 | #define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus) | ||
| 931 | #define FRAME_Z_GROUP(f) ((f)->z_group) | ||
| 932 | #define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none) | ||
| 933 | #define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above) | ||
| 934 | #define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \ | ||
| 935 | ((f)->z_group == z_group_above_suspended) | ||
| 936 | #define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below) | ||
| 937 | #else /* not HAVE_WINDOW_SYSTEM or HAVE_NS */ | ||
| 938 | #define FRAME_UNDECORATED(f) ((void) f, 0) | ||
| 939 | #define FRAME_OVERRIDE_REDIRECT(f) ((void) f, 0) | ||
| 940 | #define FRAME_PARENT_FRAME(f) ((void) f, NULL) | ||
| 941 | #define FRAME_SKIP_TASKBAR(f) ((void) f, 0) | ||
| 942 | #define FRAME_NO_FOCUS_ON_MAP(f) ((void) f, 0) | ||
| 943 | #define FRAME_NO_ACCEPT_FOCUS(f) ((void) f, 0) | ||
| 944 | #define FRAME_Z_GROUP(f) ((void) f, z_group_none) | ||
| 945 | #define FRAME_Z_GROUP_NONE(f) ((void) f, true) | ||
| 946 | #define FRAME_Z_GROUP_ABOVE(f) ((void) f, false) | ||
| 947 | #define FRAME_Z_GROUP_BELOW(f) ((void) f, false) | ||
| 948 | #endif /* HAVE_WINDOW_SYSTEM and not HAVE_NS */ | ||
| 949 | |||
| 878 | /* Whether horizontal scroll bars are currently enabled for frame F. */ | 950 | /* Whether horizontal scroll bars are currently enabled for frame F. */ |
| 879 | #if USE_HORIZONTAL_SCROLL_BARS | 951 | #if USE_HORIZONTAL_SCROLL_BARS |
| 880 | #define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \ | 952 | #define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \ |
| @@ -1041,7 +1113,8 @@ default_pixels_per_inch_y (void) | |||
| 1041 | loop will set FRAME_VAR, a Lisp_Object, to each frame in | 1113 | loop will set FRAME_VAR, a Lisp_Object, to each frame in |
| 1042 | Vframe_list in succession and execute the statement. LIST_VAR | 1114 | Vframe_list in succession and execute the statement. LIST_VAR |
| 1043 | should be a Lisp_Object too; it is used to iterate through the | 1115 | should be a Lisp_Object too; it is used to iterate through the |
| 1044 | Vframe_list. | 1116 | Vframe_list. Note that this macro walks over child frames and |
| 1117 | the tooltip frame as well. | ||
| 1045 | 1118 | ||
| 1046 | This macro is a holdover from a time when multiple frames weren't always | 1119 | This macro is a holdover from a time when multiple frames weren't always |
| 1047 | supported. An alternate definition of the macro would expand to | 1120 | supported. An alternate definition of the macro would expand to |
| @@ -1221,7 +1294,7 @@ FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) | |||
| 1221 | return frame_dimension (f->internal_border_width); | 1294 | return frame_dimension (f->internal_border_width); |
| 1222 | } | 1295 | } |
| 1223 | 1296 | ||
| 1224 | /* Pixel-size of window border lines */ | 1297 | /* Pixel-size of window divider lines */ |
| 1225 | INLINE int | 1298 | INLINE int |
| 1226 | FRAME_RIGHT_DIVIDER_WIDTH (struct frame *f) | 1299 | FRAME_RIGHT_DIVIDER_WIDTH (struct frame *f) |
| 1227 | { | 1300 | { |
| @@ -1446,6 +1519,7 @@ extern void x_activate_menubar (struct frame *); | |||
| 1446 | extern void x_real_positions (struct frame *, int *, int *); | 1519 | extern void x_real_positions (struct frame *, int *, int *); |
| 1447 | extern void free_frame_menubar (struct frame *); | 1520 | extern void free_frame_menubar (struct frame *); |
| 1448 | extern void x_free_frame_resources (struct frame *); | 1521 | extern void x_free_frame_resources (struct frame *); |
| 1522 | extern bool frame_ancestor_p (struct frame *af, struct frame *df); | ||
| 1449 | 1523 | ||
| 1450 | #if defined HAVE_X_WINDOWS | 1524 | #if defined HAVE_X_WINDOWS |
| 1451 | extern void x_wm_set_icon_position (struct frame *, int, int); | 1525 | extern void x_wm_set_icon_position (struct frame *, int, int); |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 63f01436413..227a062bff3 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -1200,7 +1200,14 @@ xg_create_frame_widgets (struct frame *f) | |||
| 1200 | else if (! NILP (f->name)) | 1200 | else if (! NILP (f->name)) |
| 1201 | title = SSDATA (ENCODE_UTF_8 (f->name)); | 1201 | title = SSDATA (ENCODE_UTF_8 (f->name)); |
| 1202 | 1202 | ||
| 1203 | if (title) gtk_window_set_title (GTK_WINDOW (wtop), title); | 1203 | if (title) |
| 1204 | gtk_window_set_title (GTK_WINDOW (wtop), title); | ||
| 1205 | |||
| 1206 | if (FRAME_UNDECORATED (f)) | ||
| 1207 | { | ||
| 1208 | gtk_window_set_decorated (GTK_WINDOW (wtop), FALSE); | ||
| 1209 | store_frame_param (f, Qundecorated, Qt); | ||
| 1210 | } | ||
| 1204 | 1211 | ||
| 1205 | FRAME_GTK_OUTER_WIDGET (f) = wtop; | 1212 | FRAME_GTK_OUTER_WIDGET (f) = wtop; |
| 1206 | FRAME_GTK_WIDGET (f) = wfixed; | 1213 | FRAME_GTK_WIDGET (f) = wfixed; |
| @@ -1275,6 +1282,14 @@ xg_create_frame_widgets (struct frame *f) | |||
| 1275 | gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE); | 1282 | gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE); |
| 1276 | #endif | 1283 | #endif |
| 1277 | 1284 | ||
| 1285 | if (FRAME_OVERRIDE_REDIRECT (f)) | ||
| 1286 | { | ||
| 1287 | GdkWindow *gwin = gtk_widget_get_window (wtop); | ||
| 1288 | |||
| 1289 | if (gwin) | ||
| 1290 | gdk_window_set_override_redirect (gwin, TRUE); | ||
| 1291 | } | ||
| 1292 | |||
| 1278 | #ifdef USE_GTK_TOOLTIP | 1293 | #ifdef USE_GTK_TOOLTIP |
| 1279 | /* Steal a tool tip window we can move ourselves. */ | 1294 | /* Steal a tool tip window we can move ourselves. */ |
| 1280 | f->output_data.x->ttip_widget = 0; | 1295 | f->output_data.x->ttip_widget = 0; |
| @@ -1356,7 +1371,9 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1356 | /* Don't set size hints during initialization; that apparently leads | 1371 | /* Don't set size hints during initialization; that apparently leads |
| 1357 | to a race condition. See the thread at | 1372 | to a race condition. See the thread at |
| 1358 | http://lists.gnu.org/archive/html/emacs-devel/2008-10/msg00033.html */ | 1373 | http://lists.gnu.org/archive/html/emacs-devel/2008-10/msg00033.html */ |
| 1359 | if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f)) | 1374 | if (NILP (Vafter_init_time) |
| 1375 | || !FRAME_GTK_OUTER_WIDGET (f) | ||
| 1376 | || FRAME_PARENT_FRAME (f)) | ||
| 1360 | return; | 1377 | return; |
| 1361 | 1378 | ||
| 1362 | XSETFRAME (frame, f); | 1379 | XSETFRAME (frame, f); |
| @@ -1489,6 +1506,100 @@ xg_set_background_color (struct frame *f, unsigned long bg) | |||
| 1489 | } | 1506 | } |
| 1490 | } | 1507 | } |
| 1491 | 1508 | ||
| 1509 | /* Change the frame's decoration (title bar + resize borders). This | ||
| 1510 | might not work with all window managers. */ | ||
| 1511 | void | ||
| 1512 | xg_set_undecorated (struct frame *f, Lisp_Object undecorated) | ||
| 1513 | { | ||
| 1514 | if (FRAME_GTK_WIDGET (f)) | ||
| 1515 | { | ||
| 1516 | block_input (); | ||
| 1517 | gtk_window_set_decorated (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | ||
| 1518 | NILP (undecorated) ? TRUE : FALSE); | ||
| 1519 | unblock_input (); | ||
| 1520 | } | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | |||
| 1524 | /* Restack F1 below F2, above if ABOVE_FLAG is true. This might not | ||
| 1525 | work with all window managers. */ | ||
| 1526 | void | ||
| 1527 | xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag) | ||
| 1528 | { | ||
| 1529 | block_input (); | ||
| 1530 | if (FRAME_GTK_OUTER_WIDGET (f1) && FRAME_GTK_OUTER_WIDGET (f2)) | ||
| 1531 | { | ||
| 1532 | GdkWindow *gwin1 = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f1)); | ||
| 1533 | GdkWindow *gwin2 = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f2)); | ||
| 1534 | Lisp_Object frame1, frame2; | ||
| 1535 | |||
| 1536 | XSETFRAME (frame1, f1); | ||
| 1537 | XSETFRAME (frame2, f2); | ||
| 1538 | |||
| 1539 | gdk_window_restack (gwin1, gwin2, above_flag); | ||
| 1540 | x_sync (f1); | ||
| 1541 | } | ||
| 1542 | unblock_input (); | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | |||
| 1546 | /* Don't show frame in taskbar, don't ALT-TAB to it. */ | ||
| 1547 | void | ||
| 1548 | xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar) | ||
| 1549 | { | ||
| 1550 | block_input (); | ||
| 1551 | if (FRAME_GTK_WIDGET (f)) | ||
| 1552 | gdk_window_set_skip_taskbar_hint | ||
| 1553 | (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)), | ||
| 1554 | NILP (skip_taskbar) ? FALSE : TRUE); | ||
| 1555 | unblock_input (); | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | |||
| 1559 | /* Don't give frame focus. */ | ||
| 1560 | void | ||
| 1561 | xg_set_no_focus_on_map (struct frame *f, Lisp_Object no_focus_on_map) | ||
| 1562 | { | ||
| 1563 | block_input (); | ||
| 1564 | if (FRAME_GTK_WIDGET (f)) | ||
| 1565 | { | ||
| 1566 | GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 1567 | gboolean gno_focus_on_map = NILP (no_focus_on_map) ? TRUE : FALSE; | ||
| 1568 | |||
| 1569 | gtk_window_set_focus_on_map (gwin, gno_focus_on_map); | ||
| 1570 | } | ||
| 1571 | unblock_input (); | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | |||
| 1575 | void | ||
| 1576 | xg_set_no_accept_focus (struct frame *f, Lisp_Object no_accept_focus) | ||
| 1577 | { | ||
| 1578 | block_input (); | ||
| 1579 | if (FRAME_GTK_WIDGET (f)) | ||
| 1580 | { | ||
| 1581 | GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 1582 | gboolean gno_accept_focus = NILP (no_accept_focus) ? TRUE : FALSE; | ||
| 1583 | |||
| 1584 | gtk_window_set_accept_focus (gwin, gno_accept_focus); | ||
| 1585 | } | ||
| 1586 | unblock_input (); | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | void | ||
| 1590 | xg_set_override_redirect (struct frame *f, Lisp_Object override_redirect) | ||
| 1591 | { | ||
| 1592 | block_input (); | ||
| 1593 | |||
| 1594 | if (FRAME_GTK_OUTER_WIDGET (f)) | ||
| 1595 | { | ||
| 1596 | GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 1597 | |||
| 1598 | gdk_window_set_override_redirect (gwin, NILP (override_redirect) ? FALSE : TRUE); | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | unblock_input (); | ||
| 1602 | } | ||
| 1492 | 1603 | ||
| 1493 | /* Set the frame icon to ICON_PIXMAP/MASK. This must be done with GTK | 1604 | /* Set the frame icon to ICON_PIXMAP/MASK. This must be done with GTK |
| 1494 | functions so GTK does not overwrite the icon. */ | 1605 | functions so GTK does not overwrite the icon. */ |
| @@ -3769,6 +3880,7 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3769 | GtkWidget *wparent = gtk_widget_get_parent (wscroll); | 3880 | GtkWidget *wparent = gtk_widget_get_parent (wscroll); |
| 3770 | gint msl; | 3881 | gint msl; |
| 3771 | int scale = xg_get_gdk_scale (); | 3882 | int scale = xg_get_gdk_scale (); |
| 3883 | bool hidden; | ||
| 3772 | 3884 | ||
| 3773 | top /= scale; | 3885 | top /= scale; |
| 3774 | left /= scale; | 3886 | left /= scale; |
| @@ -3793,6 +3905,7 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3793 | the height is less than the min size. */ | 3905 | the height is less than the min size. */ |
| 3794 | gtk_widget_hide (wparent); | 3906 | gtk_widget_hide (wparent); |
| 3795 | gtk_widget_hide (wscroll); | 3907 | gtk_widget_hide (wscroll); |
| 3908 | hidden = true; | ||
| 3796 | } | 3909 | } |
| 3797 | else | 3910 | else |
| 3798 | { | 3911 | { |
| @@ -3807,6 +3920,15 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3807 | x_clear_area (f, oldx, oldy, oldw, oldh); | 3920 | x_clear_area (f, oldx, oldy, oldw, oldh); |
| 3808 | } | 3921 | } |
| 3809 | 3922 | ||
| 3923 | if (!hidden) | ||
| 3924 | { | ||
| 3925 | GtkWidget *scrollbar = xg_get_widget_from_map (scrollbar_id); | ||
| 3926 | GtkWidget *webox = gtk_widget_get_parent (scrollbar); | ||
| 3927 | |||
| 3928 | /* Don't obscure any child frames. */ | ||
| 3929 | XLowerWindow (FRAME_X_DISPLAY (f), GTK_WIDGET_TO_X_WIN (webox)); | ||
| 3930 | } | ||
| 3931 | |||
| 3810 | /* GTK does not redraw until the main loop is entered again, but | 3932 | /* GTK does not redraw until the main loop is entered again, but |
| 3811 | if there are no X events pending we will not enter it. So we sync | 3933 | if there are no X events pending we will not enter it. So we sync |
| 3812 | here to get some events. */ | 3934 | here to get some events. */ |
| @@ -3872,6 +3994,15 @@ xg_update_horizontal_scrollbar_pos (struct frame *f, | |||
| 3872 | if there are no X events pending we will not enter it. So we sync | 3994 | if there are no X events pending we will not enter it. So we sync |
| 3873 | here to get some events. */ | 3995 | here to get some events. */ |
| 3874 | 3996 | ||
| 3997 | { | ||
| 3998 | GtkWidget *scrollbar = | ||
| 3999 | xg_get_widget_from_map (scrollbar_id); | ||
| 4000 | GtkWidget *webox = gtk_widget_get_parent (scrollbar); | ||
| 4001 | |||
| 4002 | /* Don't obscure any child frames. */ | ||
| 4003 | XLowerWindow (FRAME_X_DISPLAY (f), GTK_WIDGET_TO_X_WIN (webox)); | ||
| 4004 | } | ||
| 4005 | |||
| 3875 | x_sync (f); | 4006 | x_sync (f); |
| 3876 | SET_FRAME_GARBAGED (f); | 4007 | SET_FRAME_GARBAGED (f); |
| 3877 | cancel_mouse_face (f); | 4008 | cancel_mouse_face (f); |
diff --git a/src/gtkutil.h b/src/gtkutil.h index d67a7bc4328..244549fc54b 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h | |||
| @@ -172,6 +172,13 @@ extern void xg_set_frame_icon (struct frame *f, | |||
| 172 | Pixmap icon_pixmap, | 172 | Pixmap icon_pixmap, |
| 173 | Pixmap icon_mask); | 173 | Pixmap icon_mask); |
| 174 | 174 | ||
| 175 | extern void xg_set_undecorated (struct frame *f, Lisp_Object undecorated); | ||
| 176 | extern void xg_frame_restack (struct frame *f1, struct frame *f2, bool above); | ||
| 177 | extern void xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar); | ||
| 178 | extern void xg_set_no_focus_on_map (struct frame *f, Lisp_Object no_focus_on_map); | ||
| 179 | extern void xg_set_no_accept_focus (struct frame *f, Lisp_Object no_accept_focus); | ||
| 180 | extern void xg_set_override_redirect (struct frame *f, Lisp_Object override_redirect); | ||
| 181 | |||
| 175 | extern bool xg_prepare_tooltip (struct frame *f, | 182 | extern bool xg_prepare_tooltip (struct frame *f, |
| 176 | Lisp_Object string, | 183 | Lisp_Object string, |
| 177 | int *width, | 184 | int *width, |
diff --git a/src/nsfns.m b/src/nsfns.m index 9e904c68382..e8f035f0e57 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -972,6 +972,13 @@ frame_parm_handler ns_frame_parm_handlers[] = | |||
| 972 | 0, /* x_set_sticky */ | 972 | 0, /* x_set_sticky */ |
| 973 | 0, /* x_set_tool_bar_position */ | 973 | 0, /* x_set_tool_bar_position */ |
| 974 | 0, /* x_set_inhibit_double_buffering */ | 974 | 0, /* x_set_inhibit_double_buffering */ |
| 975 | 0, /* x_set_undecorated */ | ||
| 976 | 0, /* x_set_parent_frame */ | ||
| 977 | 0, /* x_set_skip_taskbar */ | ||
| 978 | 0, /* x_set_no_focus_on_map */ | ||
| 979 | 0, /* x_set_no_accept_focus */ | ||
| 980 | 0, /* x_set_z_group */ | ||
| 981 | 0, /* x_set_override_redirect */ | ||
| 975 | }; | 982 | }; |
| 976 | 983 | ||
| 977 | 984 | ||
| @@ -1248,6 +1255,12 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 1248 | init_frame_faces (f); | 1255 | init_frame_faces (f); |
| 1249 | 1256 | ||
| 1250 | /* Read comment about this code in corresponding place in xfns.c. */ | 1257 | /* Read comment about this code in corresponding place in xfns.c. */ |
| 1258 | tem = x_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL, RES_TYPE_NUMBER); | ||
| 1259 | if (NUMBERP (tem)) | ||
| 1260 | store_frame_param (f, Qmin_width, tem); | ||
| 1261 | tem = x_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL, RES_TYPE_NUMBER); | ||
| 1262 | if (NUMBERP (tem)) | ||
| 1263 | store_frame_param (f, Qmin_height, tem); | ||
| 1251 | adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), | 1264 | adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), |
| 1252 | FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, | 1265 | FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, |
| 1253 | Qx_create_frame_1); | 1266 | Qx_create_frame_1); |
diff --git a/src/nsterm.m b/src/nsterm.m index b03ad526212..162980a651b 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -6288,7 +6288,7 @@ not_in_argv (NSString *arg) | |||
| 6288 | if (WINDOWP (window) | 6288 | if (WINDOWP (window) |
| 6289 | && !EQ (window, last_mouse_window) | 6289 | && !EQ (window, last_mouse_window) |
| 6290 | && !EQ (window, selected_window) | 6290 | && !EQ (window, selected_window) |
| 6291 | && (focus_follows_mouse | 6291 | && (!NILP (focus_follows_mouse) |
| 6292 | || (EQ (XWINDOW (window)->frame, | 6292 | || (EQ (XWINDOW (window)->frame, |
| 6293 | XWINDOW (selected_window)->frame)))) | 6293 | XWINDOW (selected_window)->frame)))) |
| 6294 | { | 6294 | { |
diff --git a/src/w32fns.c b/src/w32fns.c index dd16d74439f..f7d3b722abf 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -256,6 +256,10 @@ static unsigned int sound_type = 0xFFFFFFFF; | |||
| 256 | # define WTS_SESSION_LOCK 0x7 | 256 | # define WTS_SESSION_LOCK 0x7 |
| 257 | #endif | 257 | #endif |
| 258 | 258 | ||
| 259 | #ifndef WS_EX_NOACTIVATE | ||
| 260 | #define WS_EX_NOACTIVATE 0x08000000L | ||
| 261 | #endif | ||
| 262 | |||
| 259 | /* Keyboard hook state data. */ | 263 | /* Keyboard hook state data. */ |
| 260 | static struct | 264 | static struct |
| 261 | { | 265 | { |
| @@ -367,17 +371,20 @@ void x_set_title (struct frame *, Lisp_Object, Lisp_Object); | |||
| 367 | void | 371 | void |
| 368 | x_real_positions (struct frame *f, int *xptr, int *yptr) | 372 | x_real_positions (struct frame *f, int *xptr, int *yptr) |
| 369 | { | 373 | { |
| 370 | POINT pt; | ||
| 371 | RECT rect; | 374 | RECT rect; |
| 372 | 375 | ||
| 373 | /* Get the bounds of the WM window. */ | 376 | /* Get the bounds of the WM window. */ |
| 374 | GetWindowRect (FRAME_W32_WINDOW (f), &rect); | 377 | GetWindowRect (FRAME_W32_WINDOW (f), &rect); |
| 375 | 378 | ||
| 376 | pt.x = 0; | 379 | if (FRAME_PARENT_FRAME (f)) |
| 377 | pt.y = 0; | 380 | { |
| 381 | /* For a child window we have to get its coordinates wrt its | ||
| 382 | parent. */ | ||
| 383 | HWND parent_hwnd = FRAME_W32_WINDOW (FRAME_PARENT_FRAME (f)); | ||
| 378 | 384 | ||
| 379 | /* Convert (0, 0) in the client area to screen co-ordinates. */ | 385 | if (parent_hwnd) |
| 380 | ClientToScreen (FRAME_W32_WINDOW (f), &pt); | 386 | MapWindowPoints (HWND_DESKTOP, parent_hwnd, (LPPOINT) &rect, 2); |
| 387 | } | ||
| 381 | 388 | ||
| 382 | *xptr = rect.left; | 389 | *xptr = rect.left; |
| 383 | *yptr = rect.top; | 390 | *yptr = rect.top; |
| @@ -1682,7 +1689,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | |||
| 1682 | most of the commands try to apply themselves to the minibuffer | 1689 | most of the commands try to apply themselves to the minibuffer |
| 1683 | frame itself, and get an error because you can't switch buffers | 1690 | frame itself, and get an error because you can't switch buffers |
| 1684 | in or split the minibuffer window. */ | 1691 | in or split the minibuffer window. */ |
| 1685 | if (FRAME_MINIBUF_ONLY_P (f)) | 1692 | if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f)) |
| 1686 | return; | 1693 | return; |
| 1687 | 1694 | ||
| 1688 | if (INTEGERP (value)) | 1695 | if (INTEGERP (value)) |
| @@ -1955,6 +1962,233 @@ x_set_scroll_bar_default_height (struct frame *f) | |||
| 1955 | FRAME_CONFIG_SCROLL_BAR_LINES (f) | 1962 | FRAME_CONFIG_SCROLL_BAR_LINES (f) |
| 1956 | = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + unit - 1) / unit; | 1963 | = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + unit - 1) / unit; |
| 1957 | } | 1964 | } |
| 1965 | |||
| 1966 | /** | ||
| 1967 | * x_set_undecorated: | ||
| 1968 | * | ||
| 1969 | * Set frame F's `undecorated' parameter. If non-nil, F's window-system | ||
| 1970 | * window is drawn without decorations, title, minimize/maximize boxes | ||
| 1971 | * and external borders. This usually means that the window cannot be | ||
| 1972 | * dragged, resized, iconified, maximized or deleted with the mouse. If | ||
| 1973 | * nil, draw the frame with all the elements listed above unless these | ||
| 1974 | * have been suspended via window manager settings. | ||
| 1975 | * | ||
| 1976 | * Some window managers may not honor this parameter. | ||
| 1977 | */ | ||
| 1978 | static void | ||
| 1979 | x_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 1980 | { | ||
| 1981 | HWND hwnd = FRAME_W32_WINDOW (f); | ||
| 1982 | DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE); | ||
| 1983 | Lisp_Object border_width = Fcdr (Fassq (Qborder_width, f->param_alist)); | ||
| 1984 | |||
| 1985 | block_input (); | ||
| 1986 | if (!NILP (new_value) && !FRAME_UNDECORATED (f)) | ||
| 1987 | { | ||
| 1988 | dwStyle = ((dwStyle & ~WS_THICKFRAME & ~WS_CAPTION) | ||
| 1989 | | ((NUMBERP (border_width) && (XINT (border_width) > 0)) | ||
| 1990 | ? WS_BORDER : false)); | ||
| 1991 | SetWindowLong (hwnd, GWL_STYLE, dwStyle); | ||
| 1992 | SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, | ||
| 1993 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | ||
| 1994 | | SWP_FRAMECHANGED); | ||
| 1995 | FRAME_UNDECORATED (f) = true; | ||
| 1996 | } | ||
| 1997 | else if (NILP (new_value) && FRAME_UNDECORATED (f)) | ||
| 1998 | { | ||
| 1999 | SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_THICKFRAME | WS_CAPTION | ||
| 2000 | | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU); | ||
| 2001 | SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, | ||
| 2002 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | ||
| 2003 | | SWP_FRAMECHANGED); | ||
| 2004 | FRAME_UNDECORATED (f) = false; | ||
| 2005 | } | ||
| 2006 | unblock_input (); | ||
| 2007 | } | ||
| 2008 | |||
| 2009 | /** | ||
| 2010 | * x_set_parent_frame: | ||
| 2011 | * | ||
| 2012 | * Set frame F's `parent-frame' parameter. If non-nil, make F a child | ||
| 2013 | * frame of the frame specified by that parameter. Technically, this | ||
| 2014 | * makes F's window-system window a child window of the parent frame's | ||
| 2015 | * window-system window. If nil, make F's window-system window a | ||
| 2016 | * top-level window--a child of its display's root window. | ||
| 2017 | * | ||
| 2018 | * A child frame is clipped at the native edges of its parent frame. | ||
| 2019 | * Its `left' and `top' parameters specify positions relative to the | ||
| 2020 | * top-left corner of its parent frame's native rectangle. Usually, | ||
| 2021 | * moving a parent frame moves all its child frames too, keeping their | ||
| 2022 | * position relative to the parent unaltered. When a parent frame is | ||
| 2023 | * iconified or made invisible, its child frames are made invisible. | ||
| 2024 | * When a parent frame is deleted, its child frames are deleted too. | ||
| 2025 | * | ||
| 2026 | * A visible child frame always appears on top of its parent frame thus | ||
| 2027 | * obscuring parts of it. When a frame has more than one child frame, | ||
| 2028 | * their stacking order is specified just as that of non-child frames | ||
| 2029 | * relative to their display. | ||
| 2030 | * | ||
| 2031 | * Whether a child frame has a menu or tool bar may be window-system or | ||
| 2032 | * window manager dependent. It's advisable to disable both via the | ||
| 2033 | * frame parameter settings. | ||
| 2034 | * | ||
| 2035 | * Some window managers may not honor this parameter. | ||
| 2036 | */ | ||
| 2037 | static void | ||
| 2038 | x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 2039 | { | ||
| 2040 | struct frame *p = NULL; | ||
| 2041 | |||
| 2042 | if (!NILP (new_value) | ||
| 2043 | && (!FRAMEP (new_value) | ||
| 2044 | || !FRAME_LIVE_P (p = XFRAME (new_value)) | ||
| 2045 | || !FRAME_W32_P (p))) | ||
| 2046 | { | ||
| 2047 | store_frame_param (f, Qparent_frame, old_value); | ||
| 2048 | error ("Invalid specification of `parent-frame'"); | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | if (p != FRAME_PARENT_FRAME (f)) | ||
| 2052 | { | ||
| 2053 | HWND hwnd = FRAME_W32_WINDOW (f); | ||
| 2054 | HWND hwnd_parent = p ? FRAME_W32_WINDOW (p) : NULL; | ||
| 2055 | HWND hwnd_value; | ||
| 2056 | |||
| 2057 | block_input (); | ||
| 2058 | hwnd_value = SetParent (hwnd, hwnd_parent); | ||
| 2059 | unblock_input (); | ||
| 2060 | |||
| 2061 | if (hwnd_value) | ||
| 2062 | fset_parent_frame (f, new_value); | ||
| 2063 | else | ||
| 2064 | { | ||
| 2065 | store_frame_param (f, Qparent_frame, old_value); | ||
| 2066 | error ("Reparenting frame failed"); | ||
| 2067 | } | ||
| 2068 | } | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | /** | ||
| 2072 | * x_set_skip_taskbar: | ||
| 2073 | * | ||
| 2074 | * Set frame F's `skip-taskbar' parameter. If non-nil, this should | ||
| 2075 | * remove F's icon from the taskbar associated with the display of F's | ||
| 2076 | * window-system window and inhibit switching to F's window via | ||
| 2077 | * <Alt>-<TAB>. On Windows iconifying F will "roll in" its window at | ||
| 2078 | * the bottom of the desktop. If nil, lift these restrictions. | ||
| 2079 | * | ||
| 2080 | * Some window managers may not honor this parameter. | ||
| 2081 | */ | ||
| 2082 | static void | ||
| 2083 | x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 2084 | { | ||
| 2085 | if (!EQ (new_value, old_value)) | ||
| 2086 | { | ||
| 2087 | HWND hwnd = FRAME_W32_WINDOW (f); | ||
| 2088 | DWORD exStyle = GetWindowLong (hwnd, GWL_EXSTYLE); | ||
| 2089 | |||
| 2090 | block_input (); | ||
| 2091 | /* Temporarily hide the window while changing its WS_EX_NOACTIVATE | ||
| 2092 | setting. */ | ||
| 2093 | ShowWindow (hwnd, SW_HIDE); | ||
| 2094 | if (!NILP (new_value)) | ||
| 2095 | SetWindowLong (hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE); | ||
| 2096 | else | ||
| 2097 | SetWindowLong (hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_NOACTIVATE); | ||
| 2098 | ShowWindow (hwnd, SW_SHOWNOACTIVATE); | ||
| 2099 | unblock_input (); | ||
| 2100 | |||
| 2101 | FRAME_SKIP_TASKBAR (f) = !NILP (new_value); | ||
| 2102 | } | ||
| 2103 | } | ||
| 2104 | |||
| 2105 | /** | ||
| 2106 | * x_set_no_focus_on_map: | ||
| 2107 | * | ||
| 2108 | * Set frame F's `no-focus-on-map' parameter which, if non-nil, means | ||
| 2109 | * that F's window-system window does not want to receive input focus | ||
| 2110 | * when it is mapped. (A frame's window is mapped when the frame is | ||
| 2111 | * displayed for the first time and when the frame changes its state | ||
| 2112 | * from `iconified' or `invisible' to `visible'.) | ||
| 2113 | * | ||
| 2114 | * Some window managers may not honor this parameter. | ||
| 2115 | */ | ||
| 2116 | static void | ||
| 2117 | x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 2118 | { | ||
| 2119 | if (!EQ (new_value, old_value)) | ||
| 2120 | FRAME_NO_FOCUS_ON_MAP (f) = !NILP (new_value); | ||
| 2121 | } | ||
| 2122 | |||
| 2123 | /** | ||
| 2124 | * x_set_no_accept_focus: | ||
| 2125 | * | ||
| 2126 | * Set frame F's `no-accept-focus' parameter which, if non-nil, hints | ||
| 2127 | * that F's window-system window does not want to receive input focus | ||
| 2128 | * via mouse clicks or by moving the mouse into it. | ||
| 2129 | * | ||
| 2130 | * If non-nil, this may have the unwanted side-effect that a user cannot | ||
| 2131 | * scroll a non-selected frame with the mouse. | ||
| 2132 | * | ||
| 2133 | * Some window managers may not honor this parameter. | ||
| 2134 | */ | ||
| 2135 | static void | ||
| 2136 | x_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 2137 | { | ||
| 2138 | if (!EQ (new_value, old_value)) | ||
| 2139 | FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value); | ||
| 2140 | } | ||
| 2141 | |||
| 2142 | /** | ||
| 2143 | * x_set_z_group: | ||
| 2144 | * | ||
| 2145 | * Set frame F's `z-group' parameter. If `above', F's window-system | ||
| 2146 | * window is displayed above all windows that do not have the `above' | ||
| 2147 | * property set. If nil, F's window is shown below all windows that | ||
| 2148 | * have the `above' property set and above all windows that have the | ||
| 2149 | * `below' property set. If `below', F's window is displayed below all | ||
| 2150 | * windows that do not have the `below' property set. | ||
| 2151 | * | ||
| 2152 | * Some window managers may not honor this parameter. The value `below' | ||
| 2153 | * is not supported on Windows. | ||
| 2154 | */ | ||
| 2155 | static void | ||
| 2156 | x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 2157 | { | ||
| 2158 | HWND hwnd = FRAME_W32_WINDOW (f); | ||
| 2159 | |||
| 2160 | if (NILP (new_value)) | ||
| 2161 | { | ||
| 2162 | block_input (); | ||
| 2163 | SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, | ||
| 2164 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | ||
| 2165 | | SWP_NOOWNERZORDER); | ||
| 2166 | unblock_input (); | ||
| 2167 | FRAME_Z_GROUP (f) = z_group_none; | ||
| 2168 | } | ||
| 2169 | else if (EQ (new_value, Qabove)) | ||
| 2170 | { | ||
| 2171 | block_input (); | ||
| 2172 | SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, | ||
| 2173 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | ||
| 2174 | | SWP_NOOWNERZORDER); | ||
| 2175 | unblock_input (); | ||
| 2176 | FRAME_Z_GROUP (f) = z_group_above; | ||
| 2177 | } | ||
| 2178 | else if (EQ (new_value, Qabove_suspended)) | ||
| 2179 | { | ||
| 2180 | block_input (); | ||
| 2181 | SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, | ||
| 2182 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | ||
| 2183 | | SWP_NOOWNERZORDER); | ||
| 2184 | unblock_input (); | ||
| 2185 | FRAME_Z_GROUP (f) = z_group_above_suspended; | ||
| 2186 | } | ||
| 2187 | else if (EQ (new_value, Qbelow)) | ||
| 2188 | error ("Value `below' for z-group is not supported on Windows"); | ||
| 2189 | else | ||
| 2190 | error ("Invalid z-group specification"); | ||
| 2191 | } | ||
| 1958 | 2192 | ||
| 1959 | /* Subroutines for creating a frame. */ | 2193 | /* Subroutines for creating a frame. */ |
| 1960 | 2194 | ||
| @@ -2013,7 +2247,12 @@ w32_init_class (HINSTANCE hinst) | |||
| 2013 | static HWND | 2247 | static HWND |
| 2014 | w32_createvscrollbar (struct frame *f, struct scroll_bar * bar) | 2248 | w32_createvscrollbar (struct frame *f, struct scroll_bar * bar) |
| 2015 | { | 2249 | { |
| 2016 | return CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE, | 2250 | return CreateWindow ("SCROLLBAR", "", |
| 2251 | /* Clip siblings so we don't draw over child | ||
| 2252 | frames. Apparently this is not always | ||
| 2253 | sufficient so we also try to make bar windows | ||
| 2254 | bottommost. */ | ||
| 2255 | SBS_VERT | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, | ||
| 2017 | /* Position and size of scroll bar. */ | 2256 | /* Position and size of scroll bar. */ |
| 2018 | bar->left, bar->top, bar->width, bar->height, | 2257 | bar->left, bar->top, bar->width, bar->height, |
| 2019 | FRAME_W32_WINDOW (f), NULL, hinst, NULL); | 2258 | FRAME_W32_WINDOW (f), NULL, hinst, NULL); |
| @@ -2022,7 +2261,12 @@ w32_createvscrollbar (struct frame *f, struct scroll_bar * bar) | |||
| 2022 | static HWND | 2261 | static HWND |
| 2023 | w32_createhscrollbar (struct frame *f, struct scroll_bar * bar) | 2262 | w32_createhscrollbar (struct frame *f, struct scroll_bar * bar) |
| 2024 | { | 2263 | { |
| 2025 | return CreateWindow ("SCROLLBAR", "", SBS_HORZ | WS_CHILD | WS_VISIBLE, | 2264 | return CreateWindow ("SCROLLBAR", "", |
| 2265 | /* Clip siblings so we don't draw over child | ||
| 2266 | frames. Apparently this is not always | ||
| 2267 | sufficient so we also try to make bar windows | ||
| 2268 | bottommost. */ | ||
| 2269 | SBS_HORZ | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, | ||
| 2026 | /* Position and size of scroll bar. */ | 2270 | /* Position and size of scroll bar. */ |
| 2027 | bar->left, bar->top, bar->width, bar->height, | 2271 | bar->left, bar->top, bar->width, bar->height, |
| 2028 | FRAME_W32_WINDOW (f), NULL, hinst, NULL); | 2272 | FRAME_W32_WINDOW (f), NULL, hinst, NULL); |
| @@ -2031,20 +2275,55 @@ w32_createhscrollbar (struct frame *f, struct scroll_bar * bar) | |||
| 2031 | static void | 2275 | static void |
| 2032 | w32_createwindow (struct frame *f, int *coords) | 2276 | w32_createwindow (struct frame *f, int *coords) |
| 2033 | { | 2277 | { |
| 2034 | HWND hwnd; | 2278 | HWND hwnd = NULL, parent_hwnd = NULL; |
| 2035 | RECT rect; | 2279 | RECT rect; |
| 2036 | int top; | 2280 | DWORD dwStyle; |
| 2037 | int left; | 2281 | int top, left; |
| 2282 | Lisp_Object border_width = Fcdr (Fassq (Qborder_width, f->param_alist)); | ||
| 2283 | |||
| 2284 | if (FRAME_PARENT_FRAME (f) && FRAME_W32_P (FRAME_PARENT_FRAME (f))) | ||
| 2285 | { | ||
| 2286 | parent_hwnd = FRAME_W32_WINDOW (FRAME_PARENT_FRAME (f)); | ||
| 2287 | f->output_data.w32->dwStyle = WS_CHILD | WS_CLIPSIBLINGS; | ||
| 2288 | |||
| 2289 | if (FRAME_UNDECORATED (f)) | ||
| 2290 | { | ||
| 2291 | /* If we want a thin border, specify it here. */ | ||
| 2292 | if (NUMBERP (border_width) && (XINT (border_width) > 0)) | ||
| 2293 | f->output_data.w32->dwStyle = | ||
| 2294 | f->output_data.w32->dwStyle | WS_BORDER; | ||
| 2295 | } | ||
| 2296 | else | ||
| 2297 | /* To decorate a child frame, list all needed elements. */ | ||
| 2298 | f->output_data.w32->dwStyle = | ||
| 2299 | f->output_data.w32->dwStyle | WS_THICKFRAME | WS_CAPTION | ||
| 2300 | | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU; | ||
| 2301 | } | ||
| 2302 | else if (FRAME_UNDECORATED (f)) | ||
| 2303 | { | ||
| 2304 | /* All attempts to start with ~WS_OVERLAPPEDWINDOW or overlapped | ||
| 2305 | with all other style elements negated failed here. */ | ||
| 2306 | f->output_data.w32->dwStyle = WS_POPUP; | ||
| 2307 | |||
| 2308 | /* If we want a thin border, specify it here. */ | ||
| 2309 | if (NUMBERP (border_width) && (XINT (border_width) > 0)) | ||
| 2310 | f->output_data.w32->dwStyle = | ||
| 2311 | f->output_data.w32->dwStyle | WS_BORDER; | ||
| 2312 | } | ||
| 2313 | else | ||
| 2314 | f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; | ||
| 2315 | |||
| 2316 | /* Always clip children. */ | ||
| 2317 | f->output_data.w32->dwStyle = f->output_data.w32->dwStyle | WS_CLIPCHILDREN; | ||
| 2038 | 2318 | ||
| 2039 | rect.left = rect.top = 0; | 2319 | rect.left = rect.top = 0; |
| 2040 | rect.right = FRAME_PIXEL_WIDTH (f); | 2320 | rect.right = FRAME_PIXEL_WIDTH (f); |
| 2041 | rect.bottom = FRAME_PIXEL_HEIGHT (f); | 2321 | rect.bottom = FRAME_PIXEL_HEIGHT (f); |
| 2042 | 2322 | ||
| 2043 | AdjustWindowRect (&rect, f->output_data.w32->dwStyle, | 2323 | AdjustWindowRect (&rect, f->output_data.w32->dwStyle, |
| 2044 | FRAME_EXTERNAL_MENU_BAR (f)); | 2324 | FRAME_EXTERNAL_MENU_BAR (f) && !parent_hwnd); |
| 2045 | 2325 | ||
| 2046 | /* Do first time app init */ | 2326 | /* Do first time app init */ |
| 2047 | |||
| 2048 | w32_init_class (hinst); | 2327 | w32_init_class (hinst); |
| 2049 | 2328 | ||
| 2050 | if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition) | 2329 | if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition) |
| @@ -2059,18 +2338,16 @@ w32_createwindow (struct frame *f, int *coords) | |||
| 2059 | } | 2338 | } |
| 2060 | 2339 | ||
| 2061 | FRAME_W32_WINDOW (f) = hwnd | 2340 | FRAME_W32_WINDOW (f) = hwnd |
| 2062 | = CreateWindow (EMACS_CLASS, | 2341 | = CreateWindow (EMACS_CLASS, f->namebuf, f->output_data.w32->dwStyle, |
| 2063 | f->namebuf, | 2342 | left, top, rect.right - rect.left, rect.bottom - rect.top, |
| 2064 | f->output_data.w32->dwStyle | WS_CLIPCHILDREN, | 2343 | parent_hwnd, NULL, hinst, NULL); |
| 2065 | left, top, | ||
| 2066 | rect.right - rect.left, rect.bottom - rect.top, | ||
| 2067 | NULL, | ||
| 2068 | NULL, | ||
| 2069 | hinst, | ||
| 2070 | NULL); | ||
| 2071 | 2344 | ||
| 2072 | if (hwnd) | 2345 | if (hwnd) |
| 2073 | { | 2346 | { |
| 2347 | if (FRAME_SKIP_TASKBAR (f)) | ||
| 2348 | SetWindowLong (hwnd, GWL_EXSTYLE, | ||
| 2349 | GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_NOACTIVATE); | ||
| 2350 | |||
| 2074 | SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); | 2351 | SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); |
| 2075 | SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); | 2352 | SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); |
| 2076 | SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); | 2353 | SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); |
| @@ -2086,6 +2363,12 @@ w32_createwindow (struct frame *f, int *coords) | |||
| 2086 | 2363 | ||
| 2087 | /* Update frame positions. */ | 2364 | /* Update frame positions. */ |
| 2088 | GetWindowRect (hwnd, &rect); | 2365 | GetWindowRect (hwnd, &rect); |
| 2366 | |||
| 2367 | if (parent_hwnd) | ||
| 2368 | /* For a child window we have to get its coordinates wrt its | ||
| 2369 | parent. */ | ||
| 2370 | MapWindowPoints (HWND_DESKTOP, parent_hwnd, (LPPOINT) &rect, 2); | ||
| 2371 | |||
| 2089 | f->left_pos = rect.left; | 2372 | f->left_pos = rect.left; |
| 2090 | f->top_pos = rect.top; | 2373 | f->top_pos = rect.top; |
| 2091 | } | 2374 | } |
| @@ -4381,6 +4664,22 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 4381 | } | 4664 | } |
| 4382 | } | 4665 | } |
| 4383 | 4666 | ||
| 4667 | if (f && (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN | ||
| 4668 | || msg == WM_MBUTTONDOWN ||msg == WM_XBUTTONDOWN) | ||
| 4669 | && !FRAME_NO_ACCEPT_FOCUS (f)) | ||
| 4670 | /* When clicking into a child frame or when clicking into a | ||
| 4671 | parent frame with the child frame selected and | ||
| 4672 | `no-accept-focus' is not set, select the clicked frame. */ | ||
| 4673 | { | ||
| 4674 | struct frame *p = FRAME_PARENT_FRAME (XFRAME (selected_frame)); | ||
| 4675 | |||
| 4676 | if (FRAME_PARENT_FRAME (f) || f == p) | ||
| 4677 | { | ||
| 4678 | SetFocus (hwnd); | ||
| 4679 | SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); | ||
| 4680 | } | ||
| 4681 | } | ||
| 4682 | |||
| 4384 | wmsg.dwModifiers = w32_get_modifiers (); | 4683 | wmsg.dwModifiers = w32_get_modifiers (); |
| 4385 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 4684 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
| 4386 | signal_user_input (); | 4685 | signal_user_input (); |
| @@ -4486,6 +4785,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 4486 | if (w32_pass_multimedia_buttons_to_system) | 4785 | if (w32_pass_multimedia_buttons_to_system) |
| 4487 | goto dflt; | 4786 | goto dflt; |
| 4488 | /* Otherwise, pass to lisp, the same way we do with mousehwheel. */ | 4787 | /* Otherwise, pass to lisp, the same way we do with mousehwheel. */ |
| 4788 | |||
| 4789 | /* FIXME!!! This is never reached so what's the purpose? If the | ||
| 4790 | non-zero return remark below is right we're doing it wrong all | ||
| 4791 | the time. */ | ||
| 4489 | case WM_MOUSEHWHEEL: | 4792 | case WM_MOUSEHWHEEL: |
| 4490 | wmsg.dwModifiers = w32_get_modifiers (); | 4793 | wmsg.dwModifiers = w32_get_modifiers (); |
| 4491 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 4794 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
| @@ -4712,19 +5015,34 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 4712 | } | 5015 | } |
| 4713 | return 0; | 5016 | return 0; |
| 4714 | 5017 | ||
| 4715 | #if 0 | 5018 | case WM_MOUSEACTIVATE: |
| 5019 | /* WM_MOUSEACTIVATE is the only way on Windows to implement the | ||
| 5020 | `no-accept-focus' frame parameter. This means that one can't | ||
| 5021 | use the mouse to scroll a window on a non-selected frame. */ | ||
| 5022 | |||
| 4716 | /* Still not right - can't distinguish between clicks in the | 5023 | /* Still not right - can't distinguish between clicks in the |
| 4717 | client area of the frame from clicks forwarded from the scroll | 5024 | client area of the frame from clicks forwarded from the scroll |
| 4718 | bars - may have to hook WM_NCHITTEST to remember the mouse | 5025 | bars - may have to hook WM_NCHITTEST to remember the mouse |
| 4719 | position and then check if it is in the client area ourselves. */ | 5026 | position and then check if it is in the client area |
| 4720 | case WM_MOUSEACTIVATE: | 5027 | ourselves. */ |
| 5028 | |||
| 4721 | /* Discard the mouse click that activates a frame, allowing the | 5029 | /* Discard the mouse click that activates a frame, allowing the |
| 4722 | user to click anywhere without changing point (or worse!). | 5030 | user to click anywhere without changing point (or worse!). |
| 4723 | Don't eat mouse clicks on scrollbars though!! */ | 5031 | Don't eat mouse clicks on scrollbars though!! */ |
| 4724 | if (LOWORD (lParam) == HTCLIENT ) | 5032 | |
| 4725 | return MA_ACTIVATEANDEAT; | 5033 | if ((f = x_window_to_frame (dpyinfo, hwnd)) |
| 5034 | && FRAME_NO_ACCEPT_FOCUS (f) | ||
| 5035 | /* Ignore child frames, they don't accept focus anyway. */ | ||
| 5036 | && !FRAME_PARENT_FRAME (f)) | ||
| 5037 | { | ||
| 5038 | Lisp_Object frame; | ||
| 5039 | |||
| 5040 | XSETFRAME (frame, f); | ||
| 5041 | if (!EQ (selected_frame, frame)) | ||
| 5042 | /* Don't discard the message, GTK doesn't either. */ | ||
| 5043 | return MA_NOACTIVATE; /* ANDEAT; */ | ||
| 5044 | } | ||
| 4726 | goto dflt; | 5045 | goto dflt; |
| 4727 | #endif | ||
| 4728 | 5046 | ||
| 4729 | case WM_MOUSELEAVE: | 5047 | case WM_MOUSELEAVE: |
| 4730 | /* No longer tracking mouse. */ | 5048 | /* No longer tracking mouse. */ |
| @@ -4903,6 +5221,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 4903 | AttachThreadInput (GetCurrentThreadId (), | 5221 | AttachThreadInput (GetCurrentThreadId (), |
| 4904 | foreground_thread, FALSE); | 5222 | foreground_thread, FALSE); |
| 4905 | 5223 | ||
| 5224 | /* SetFocus to give/remove focus to/from a child window. */ | ||
| 5225 | if (msg == WM_EMACS_SETFOREGROUND) | ||
| 5226 | SetFocus ((HWND) wParam); | ||
| 5227 | |||
| 4906 | return retval; | 5228 | return retval; |
| 4907 | } | 5229 | } |
| 4908 | 5230 | ||
| @@ -5134,7 +5456,8 @@ w32_window (struct frame *f, long window_prompting, bool minibuffer_only) | |||
| 5134 | 5456 | ||
| 5135 | unblock_input (); | 5457 | unblock_input (); |
| 5136 | 5458 | ||
| 5137 | if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) | 5459 | if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f) |
| 5460 | && !FRAME_PARENT_FRAME (f)) | ||
| 5138 | initialize_frame_menubar (f); | 5461 | initialize_frame_menubar (f); |
| 5139 | 5462 | ||
| 5140 | if (FRAME_W32_WINDOW (f) == 0) | 5463 | if (FRAME_W32_WINDOW (f) == 0) |
| @@ -5322,7 +5645,7 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5322 | ptrdiff_t count = SPECPDL_INDEX (); | 5645 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5323 | Lisp_Object display; | 5646 | Lisp_Object display; |
| 5324 | struct w32_display_info *dpyinfo = NULL; | 5647 | struct w32_display_info *dpyinfo = NULL; |
| 5325 | Lisp_Object parent; | 5648 | Lisp_Object parent, parent_frame; |
| 5326 | struct kboard *kb; | 5649 | struct kboard *kb; |
| 5327 | int x_width = 0, x_height = 0; | 5650 | int x_width = 0, x_height = 0; |
| 5328 | 5651 | ||
| @@ -5359,10 +5682,11 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5359 | Vx_resource_name = name; | 5682 | Vx_resource_name = name; |
| 5360 | 5683 | ||
| 5361 | /* See if parent window is specified. */ | 5684 | /* See if parent window is specified. */ |
| 5362 | parent = x_get_arg (dpyinfo, parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER); | 5685 | parent = x_get_arg (dpyinfo, parameters, Qparent_id, NULL, NULL, |
| 5686 | RES_TYPE_NUMBER); | ||
| 5363 | if (EQ (parent, Qunbound)) | 5687 | if (EQ (parent, Qunbound)) |
| 5364 | parent = Qnil; | 5688 | parent = Qnil; |
| 5365 | if (! NILP (parent)) | 5689 | else if (!NILP (parent)) |
| 5366 | CHECK_NUMBER (parent); | 5690 | CHECK_NUMBER (parent); |
| 5367 | 5691 | ||
| 5368 | /* make_frame_without_minibuffer can run Lisp code and garbage collect. */ | 5692 | /* make_frame_without_minibuffer can run Lisp code and garbage collect. */ |
| @@ -5385,6 +5709,31 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5385 | 5709 | ||
| 5386 | XSETFRAME (frame, f); | 5710 | XSETFRAME (frame, f); |
| 5387 | 5711 | ||
| 5712 | parent_frame = x_get_arg (dpyinfo, parameters, Qparent_frame, NULL, NULL, | ||
| 5713 | RES_TYPE_SYMBOL); | ||
| 5714 | /* Apply `parent-frame' parameter only when no `parent-id' was | ||
| 5715 | specified. */ | ||
| 5716 | if (!NILP (parent_frame) | ||
| 5717 | && (!NILP (parent) | ||
| 5718 | || !FRAMEP (parent_frame) | ||
| 5719 | || !FRAME_LIVE_P (XFRAME (parent_frame)) | ||
| 5720 | || !FRAME_W32_P (XFRAME (parent_frame)))) | ||
| 5721 | parent_frame = Qnil; | ||
| 5722 | |||
| 5723 | fset_parent_frame (f, parent_frame); | ||
| 5724 | store_frame_param (f, Qparent_frame, parent_frame); | ||
| 5725 | |||
| 5726 | tem = x_get_arg (dpyinfo, parameters, Qundecorated, NULL, NULL, | ||
| 5727 | RES_TYPE_BOOLEAN); | ||
| 5728 | FRAME_UNDECORATED (f) = !NILP (tem) && !EQ (tem, Qunbound); | ||
| 5729 | store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil); | ||
| 5730 | |||
| 5731 | tem = x_get_arg (dpyinfo, parameters, Qskip_taskbar, NULL, NULL, | ||
| 5732 | RES_TYPE_BOOLEAN); | ||
| 5733 | FRAME_SKIP_TASKBAR (f) = !NILP (tem) && !EQ (tem, Qunbound); | ||
| 5734 | store_frame_param (f, Qskip_taskbar, | ||
| 5735 | (NILP (tem) || EQ (tem, Qunbound)) ? Qnil : Qt); | ||
| 5736 | |||
| 5388 | /* By default, make scrollbars the system standard width and height. */ | 5737 | /* By default, make scrollbars the system standard width and height. */ |
| 5389 | FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL); | 5738 | FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL); |
| 5390 | FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL); | 5739 | FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL); |
| @@ -5412,7 +5761,9 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5412 | dpyinfo_refcount = dpyinfo->reference_count; | 5761 | dpyinfo_refcount = dpyinfo->reference_count; |
| 5413 | #endif /* GLYPH_DEBUG */ | 5762 | #endif /* GLYPH_DEBUG */ |
| 5414 | 5763 | ||
| 5415 | /* Specify the parent under which to make this window. */ | 5764 | /* Specify the parent under which to make this window - this seems to |
| 5765 | have no effect on Windows because parent_desc is explicitly reset | ||
| 5766 | below. */ | ||
| 5416 | if (!NILP (parent)) | 5767 | if (!NILP (parent)) |
| 5417 | { | 5768 | { |
| 5418 | /* Cast to UINT_PTR shuts up compiler warnings about cast to | 5769 | /* Cast to UINT_PTR shuts up compiler warnings about cast to |
| @@ -5496,23 +5847,42 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5496 | "leftFringe", "LeftFringe", RES_TYPE_NUMBER); | 5847 | "leftFringe", "LeftFringe", RES_TYPE_NUMBER); |
| 5497 | x_default_parameter (f, parameters, Qright_fringe, Qnil, | 5848 | x_default_parameter (f, parameters, Qright_fringe, Qnil, |
| 5498 | "rightFringe", "RightFringe", RES_TYPE_NUMBER); | 5849 | "rightFringe", "RightFringe", RES_TYPE_NUMBER); |
| 5499 | /* Process alpha here (Bug#16619). */ | 5850 | x_default_parameter (f, parameters, Qno_focus_on_map, Qnil, |
| 5500 | x_default_parameter (f, parameters, Qalpha, Qnil, | 5851 | NULL, NULL, RES_TYPE_BOOLEAN); |
| 5501 | "alpha", "Alpha", RES_TYPE_NUMBER); | 5852 | x_default_parameter (f, parameters, Qno_accept_focus, Qnil, |
| 5853 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 5854 | |||
| 5855 | /* Process alpha here (Bug#16619). On XP this fails with child | ||
| 5856 | frames. For `no-focus-on-map' frames delay processing of alpha | ||
| 5857 | until the frame becomes visible. */ | ||
| 5858 | if (!FRAME_NO_FOCUS_ON_MAP (f)) | ||
| 5859 | x_default_parameter (f, parameters, Qalpha, Qnil, | ||
| 5860 | "alpha", "Alpha", RES_TYPE_NUMBER); | ||
| 5502 | 5861 | ||
| 5503 | /* Init faces first since we need the frame's column width/line | 5862 | /* Init faces first since we need the frame's column width/line |
| 5504 | height in various occasions. */ | 5863 | height in various occasions. */ |
| 5505 | init_frame_faces (f); | 5864 | init_frame_faces (f); |
| 5506 | 5865 | ||
| 5507 | /* The following call of change_frame_size is needed since otherwise | 5866 | /* We have to call adjust_frame_size here since otherwise |
| 5508 | x_set_tool_bar_lines will already work with the character sizes | 5867 | x_set_tool_bar_lines will already work with the character sizes |
| 5509 | installed by init_frame_faces while the frame's pixel size is | 5868 | installed by init_frame_faces while the frame's pixel size is still |
| 5510 | still calculated from a character size of 1 and we subsequently | 5869 | calculated from a character size of 1 and we subsequently hit the |
| 5511 | hit the (height >= 0) assertion in window_box_height. | 5870 | (height >= 0) assertion in window_box_height. |
| 5512 | 5871 | ||
| 5513 | The non-pixelwise code apparently worked around this because it | 5872 | The non-pixelwise code apparently worked around this because it |
| 5514 | had one frame line vs one toolbar line which left us with a zero | 5873 | had one frame line vs one toolbar line which left us with a zero |
| 5515 | root window height which was obviously wrong as well ... */ | 5874 | root window height which was obviously wrong as well ... |
| 5875 | |||
| 5876 | Also process `min-width' and `min-height' parameters right here | ||
| 5877 | because `frame-windows-min-size' needs them. */ | ||
| 5878 | tem = x_get_arg (dpyinfo, parameters, Qmin_width, NULL, NULL, | ||
| 5879 | RES_TYPE_NUMBER); | ||
| 5880 | if (NUMBERP (tem)) | ||
| 5881 | store_frame_param (f, Qmin_width, tem); | ||
| 5882 | tem = x_get_arg (dpyinfo, parameters, Qmin_height, NULL, NULL, | ||
| 5883 | RES_TYPE_NUMBER); | ||
| 5884 | if (NUMBERP (tem)) | ||
| 5885 | store_frame_param (f, Qmin_height, tem); | ||
| 5516 | adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), | 5886 | adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), |
| 5517 | FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true, | 5887 | FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true, |
| 5518 | Qx_create_frame_1); | 5888 | Qx_create_frame_1); |
| @@ -5520,10 +5890,17 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5520 | /* The X resources controlling the menu-bar and tool-bar are | 5890 | /* The X resources controlling the menu-bar and tool-bar are |
| 5521 | processed specially at startup, and reflected in the mode | 5891 | processed specially at startup, and reflected in the mode |
| 5522 | variables; ignore them here. */ | 5892 | variables; ignore them here. */ |
| 5523 | x_default_parameter (f, parameters, Qmenu_bar_lines, | 5893 | if (NILP (parent_frame)) |
| 5524 | NILP (Vmenu_bar_mode) | 5894 | { |
| 5525 | ? make_number (0) : make_number (1), | 5895 | x_default_parameter (f, parameters, Qmenu_bar_lines, |
| 5526 | NULL, NULL, RES_TYPE_NUMBER); | 5896 | NILP (Vmenu_bar_mode) |
| 5897 | ? make_number (0) : make_number (1), | ||
| 5898 | NULL, NULL, RES_TYPE_NUMBER); | ||
| 5899 | } | ||
| 5900 | else | ||
| 5901 | /* No menu bar for child frames. */ | ||
| 5902 | store_frame_param (f, Qmenu_bar_lines, make_number (0)); | ||
| 5903 | |||
| 5527 | x_default_parameter (f, parameters, Qtool_bar_lines, | 5904 | x_default_parameter (f, parameters, Qtool_bar_lines, |
| 5528 | NILP (Vtool_bar_mode) | 5905 | NILP (Vtool_bar_mode) |
| 5529 | ? make_number (0) : make_number (1), | 5906 | ? make_number (0) : make_number (1), |
| @@ -5534,9 +5911,7 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5534 | x_default_parameter (f, parameters, Qtitle, Qnil, | 5911 | x_default_parameter (f, parameters, Qtitle, Qnil, |
| 5535 | "title", "Title", RES_TYPE_STRING); | 5912 | "title", "Title", RES_TYPE_STRING); |
| 5536 | 5913 | ||
| 5537 | f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; | ||
| 5538 | f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | 5914 | f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; |
| 5539 | |||
| 5540 | f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM); | 5915 | f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM); |
| 5541 | f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW); | 5916 | f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW); |
| 5542 | f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW); | 5917 | f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW); |
| @@ -5601,29 +5976,36 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5601 | adjust_frame_size call. */ | 5976 | adjust_frame_size call. */ |
| 5602 | x_default_parameter (f, parameters, Qfullscreen, Qnil, | 5977 | x_default_parameter (f, parameters, Qfullscreen, Qnil, |
| 5603 | "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); | 5978 | "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); |
| 5979 | x_default_parameter (f, parameters, Qz_group, Qnil, | ||
| 5980 | NULL, NULL, RES_TYPE_SYMBOL); | ||
| 5604 | 5981 | ||
| 5605 | /* Make the window appear on the frame and enable display, unless | 5982 | /* Make the window appear on the frame and enable display, unless |
| 5606 | the caller says not to. However, with explicit parent, Emacs | 5983 | the caller says not to. However, with explicit parent, Emacs |
| 5607 | cannot control visibility, so don't try. */ | 5984 | cannot control visibility, so don't try. */ |
| 5608 | if (! f->output_data.w32->explicit_parent) | 5985 | if (!f->output_data.w32->explicit_parent) |
| 5609 | { | 5986 | { |
| 5610 | Lisp_Object visibility; | 5987 | Lisp_Object visibility |
| 5611 | 5988 | = x_get_arg (dpyinfo, parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL); | |
| 5612 | visibility = x_get_arg (dpyinfo, parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL); | ||
| 5613 | if (EQ (visibility, Qunbound)) | ||
| 5614 | visibility = Qt; | ||
| 5615 | 5989 | ||
| 5616 | if (EQ (visibility, Qicon)) | 5990 | if (EQ (visibility, Qicon)) |
| 5617 | x_iconify_frame (f); | 5991 | x_iconify_frame (f); |
| 5618 | else if (! NILP (visibility)) | ||
| 5619 | x_make_frame_visible (f); | ||
| 5620 | else | 5992 | else |
| 5621 | { | 5993 | { |
| 5622 | /* Must have been Qnil. */ | 5994 | if (EQ (visibility, Qunbound)) |
| 5623 | ; | 5995 | visibility = Qt; |
| 5996 | |||
| 5997 | if (!NILP (visibility)) | ||
| 5998 | x_make_frame_visible (f); | ||
| 5624 | } | 5999 | } |
| 6000 | |||
| 6001 | store_frame_param (f, Qvisibility, visibility); | ||
| 5625 | } | 6002 | } |
| 5626 | 6003 | ||
| 6004 | /* For `no-focus-on-map' frames set alpha here. */ | ||
| 6005 | if (FRAME_NO_FOCUS_ON_MAP (f)) | ||
| 6006 | x_default_parameter (f, parameters, Qalpha, Qnil, | ||
| 6007 | "alpha", "Alpha", RES_TYPE_NUMBER); | ||
| 6008 | |||
| 5627 | /* Initialize `default-minibuffer-frame' in case this is the first | 6009 | /* Initialize `default-minibuffer-frame' in case this is the first |
| 5628 | frame on this terminal. */ | 6010 | frame on this terminal. */ |
| 5629 | if (FRAME_HAS_MINIBUF_P (f) | 6011 | if (FRAME_HAS_MINIBUF_P (f) |
| @@ -6572,8 +6954,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms) | |||
| 6572 | dpyinfo_refcount = dpyinfo->reference_count; | 6954 | dpyinfo_refcount = dpyinfo->reference_count; |
| 6573 | #endif /* GLYPH_DEBUG */ | 6955 | #endif /* GLYPH_DEBUG */ |
| 6574 | FRAME_KBOARD (f) = kb; | 6956 | FRAME_KBOARD (f) = kb; |
| 6575 | f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | ||
| 6576 | f->output_data.w32->explicit_parent = false; | ||
| 6577 | 6957 | ||
| 6578 | /* Set the name; the functions to which we pass f expect the name to | 6958 | /* Set the name; the functions to which we pass f expect the name to |
| 6579 | be set. */ | 6959 | be set. */ |
| @@ -6639,6 +7019,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms) | |||
| 6639 | 7019 | ||
| 6640 | f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; | 7020 | f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; |
| 6641 | f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | 7021 | f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; |
| 7022 | f->output_data.w32->explicit_parent = false; | ||
| 6642 | 7023 | ||
| 6643 | x_figure_window_size (f, parms, true, &x_width, &x_height); | 7024 | x_figure_window_size (f, parms, true, &x_width, &x_height); |
| 6644 | 7025 | ||
| @@ -7282,6 +7663,23 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 7282 | return 0; | 7663 | return 0; |
| 7283 | } | 7664 | } |
| 7284 | 7665 | ||
| 7666 | void | ||
| 7667 | w32_dialog_in_progress (Lisp_Object in_progress) | ||
| 7668 | { | ||
| 7669 | Lisp_Object frames, frame; | ||
| 7670 | |||
| 7671 | /* Don't let frames in `above' z-group obscure popups. */ | ||
| 7672 | FOR_EACH_FRAME (frames, frame) | ||
| 7673 | { | ||
| 7674 | struct frame *f = XFRAME (frame); | ||
| 7675 | |||
| 7676 | if (!NILP (in_progress) && FRAME_Z_GROUP_ABOVE (f)) | ||
| 7677 | x_set_z_group (f, Qabove_suspended, Qabove); | ||
| 7678 | else if (NILP (in_progress) && FRAME_Z_GROUP_ABOVE_SUSPENDED (f)) | ||
| 7679 | x_set_z_group (f, Qabove, Qabove_suspended); | ||
| 7680 | } | ||
| 7681 | } | ||
| 7682 | |||
| 7285 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, | 7683 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, |
| 7286 | doc: /* Read file name, prompting with PROMPT in directory DIR. | 7684 | doc: /* Read file name, prompting with PROMPT in directory DIR. |
| 7287 | Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file | 7685 | Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file |
| @@ -7513,8 +7911,12 @@ value of DIR as in previous invocations; this is standard Windows behavior. */) | |||
| 7513 | 7911 | ||
| 7514 | { | 7912 | { |
| 7515 | int count = SPECPDL_INDEX (); | 7913 | int count = SPECPDL_INDEX (); |
| 7914 | |||
| 7915 | w32_dialog_in_progress (Qt); | ||
| 7916 | |||
| 7516 | /* Prevent redisplay. */ | 7917 | /* Prevent redisplay. */ |
| 7517 | specbind (Qinhibit_redisplay, Qt); | 7918 | specbind (Qinhibit_redisplay, Qt); |
| 7919 | record_unwind_protect (w32_dialog_in_progress, Qnil); | ||
| 7518 | block_input (); | 7920 | block_input (); |
| 7519 | if (use_unicode) | 7921 | if (use_unicode) |
| 7520 | { | 7922 | { |
| @@ -8559,6 +8961,136 @@ menu bar or tool bar of FRAME. */) | |||
| 8559 | } | 8961 | } |
| 8560 | } | 8962 | } |
| 8561 | 8963 | ||
| 8964 | /** | ||
| 8965 | * w32_frame_list_z_order: | ||
| 8966 | * | ||
| 8967 | * Recursively add list of all frames on the display specified via | ||
| 8968 | * DPYINFO and whose window-system window's parent is specified by | ||
| 8969 | * WINDOW to FRAMES and return FRAMES. | ||
| 8970 | */ | ||
| 8971 | static Lisp_Object | ||
| 8972 | w32_frame_list_z_order (struct w32_display_info *dpyinfo, HWND window) | ||
| 8973 | { | ||
| 8974 | Lisp_Object frame, frames = Qnil; | ||
| 8975 | |||
| 8976 | while (window) | ||
| 8977 | { | ||
| 8978 | struct frame *f = x_window_to_frame (dpyinfo, window); | ||
| 8979 | |||
| 8980 | if (f) | ||
| 8981 | { | ||
| 8982 | XSETFRAME (frame, f); | ||
| 8983 | frames = Fcons (frame, frames); | ||
| 8984 | } | ||
| 8985 | |||
| 8986 | block_input (); | ||
| 8987 | window = GetNextWindow (window, GW_HWNDNEXT); | ||
| 8988 | unblock_input (); | ||
| 8989 | } | ||
| 8990 | |||
| 8991 | return Fnreverse (frames); | ||
| 8992 | } | ||
| 8993 | |||
| 8994 | DEFUN ("w32-frame-list-z-order", Fw32_frame_list_z_order, | ||
| 8995 | Sw32_frame_list_z_order, 0, 1, 0, | ||
| 8996 | doc: /* Return list of Emacs' frames, in Z (stacking) order. | ||
| 8997 | The optional argument DISPLAY specifies which display to ask about. | ||
| 8998 | DISPLAY should be either a frame or a display name (a string). If | ||
| 8999 | omitted or nil, that stands for the selected frame's display. | ||
| 9000 | |||
| 9001 | As a special case, if DISPLAY is non-nil and specifies a live frame, | ||
| 9002 | return the child frames of that frame in Z (stacking) order. | ||
| 9003 | |||
| 9004 | Frames are listed from topmost (first) to bottommost (last). */) | ||
| 9005 | (Lisp_Object display) | ||
| 9006 | { | ||
| 9007 | struct w32_display_info *dpyinfo = check_x_display_info (display); | ||
| 9008 | HWND window; | ||
| 9009 | |||
| 9010 | block_input (); | ||
| 9011 | if (FRAMEP (display) && FRAME_LIVE_P (XFRAME (display))) | ||
| 9012 | window = GetWindow (FRAME_W32_WINDOW (XFRAME (display)), GW_CHILD); | ||
| 9013 | else | ||
| 9014 | window = GetTopWindow (NULL); | ||
| 9015 | unblock_input (); | ||
| 9016 | |||
| 9017 | return w32_frame_list_z_order (dpyinfo, window); | ||
| 9018 | } | ||
| 9019 | |||
| 9020 | /** | ||
| 9021 | * w32_frame_restack: | ||
| 9022 | * | ||
| 9023 | * Restack frame F1 below frame F2, above if ABOVE_FLAG is non-nil. In | ||
| 9024 | * practice this is a two-step action: The first step removes F1's | ||
| 9025 | * window-system window from the display. The second step reinserts | ||
| 9026 | * F1's window below (above if ABOVE_FLAG is true) that of F2. | ||
| 9027 | */ | ||
| 9028 | static void | ||
| 9029 | w32_frame_restack (struct frame *f1, struct frame *f2, bool above_flag) | ||
| 9030 | { | ||
| 9031 | HWND hwnd1 = FRAME_W32_WINDOW (f1); | ||
| 9032 | HWND hwnd2 = FRAME_W32_WINDOW (f2); | ||
| 9033 | |||
| 9034 | block_input (); | ||
| 9035 | if (above_flag) | ||
| 9036 | /* Put F1 above F2 in the z-order. */ | ||
| 9037 | { | ||
| 9038 | if (GetNextWindow (hwnd1, GW_HWNDNEXT) != hwnd2) | ||
| 9039 | { | ||
| 9040 | /* Make sure F1 is below F2 first because we must not | ||
| 9041 | change the relative position of F2 wrt any other | ||
| 9042 | window but F1. */ | ||
| 9043 | if (GetNextWindow (hwnd2, GW_HWNDNEXT) != hwnd1) | ||
| 9044 | SetWindowPos (hwnd1, hwnd2, 0, 0, 0, 0, | ||
| 9045 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | ||
| 9046 | | SWP_FRAMECHANGED); | ||
| 9047 | /* Now put F1 above F2. */ | ||
| 9048 | SetWindowPos (hwnd2, hwnd1, 0, 0, 0, 0, | ||
| 9049 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | ||
| 9050 | | SWP_FRAMECHANGED); | ||
| 9051 | } | ||
| 9052 | } | ||
| 9053 | else if (GetNextWindow (hwnd2, GW_HWNDNEXT) != hwnd1) | ||
| 9054 | /* Put F1 below F2 in the z-order. */ | ||
| 9055 | SetWindowPos (hwnd1, hwnd2, 0, 0, 0, 0, | ||
| 9056 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | ||
| 9057 | | SWP_FRAMECHANGED); | ||
| 9058 | unblock_input (); | ||
| 9059 | } | ||
| 9060 | |||
| 9061 | DEFUN ("w32-frame-restack", Fw32_frame_restack, Sw32_frame_restack, 2, 3, 0, | ||
| 9062 | doc: /* Restack FRAME1 below FRAME2. | ||
| 9063 | This means that if both frames are visible and the display areas of | ||
| 9064 | these frames overlap, FRAME2 (partially) obscures FRAME1. If optional | ||
| 9065 | third argument ABOVE is non-nil, restack FRAME1 above FRAME2. This | ||
| 9066 | means that if both frames are visible and the display areas of these | ||
| 9067 | frames overlap, FRAME1 (partially) obscures FRAME2. | ||
| 9068 | |||
| 9069 | This may be thought of as an atomic action performed in two steps: The | ||
| 9070 | first step removes FRAME1's window-system window from the display. The | ||
| 9071 | second step reinserts FRAME1's window below (above if ABOVE is true) | ||
| 9072 | that of FRAME2. Hence the position of FRAME2 in its display's Z | ||
| 9073 | \(stacking) order relative to all other frames excluding FRAME1 remains | ||
| 9074 | unaltered. | ||
| 9075 | |||
| 9076 | Some window managers may refuse to restack windows. */) | ||
| 9077 | (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above) | ||
| 9078 | { | ||
| 9079 | struct frame *f1 = decode_live_frame (frame1); | ||
| 9080 | struct frame *f2 = decode_live_frame (frame2); | ||
| 9081 | |||
| 9082 | if (FRAME_W32_P (f1) && FRAME_W32_P (f2)) | ||
| 9083 | { | ||
| 9084 | w32_frame_restack (f1, f2, !NILP (above)); | ||
| 9085 | return Qt; | ||
| 9086 | } | ||
| 9087 | else | ||
| 9088 | { | ||
| 9089 | error ("Cannot restack frames"); | ||
| 9090 | return Qnil; | ||
| 9091 | } | ||
| 9092 | } | ||
| 9093 | |||
| 8562 | DEFUN ("w32-mouse-absolute-pixel-position", Fw32_mouse_absolute_pixel_position, | 9094 | DEFUN ("w32-mouse-absolute-pixel-position", Fw32_mouse_absolute_pixel_position, |
| 8563 | Sw32_mouse_absolute_pixel_position, 0, 0, 0, | 9095 | Sw32_mouse_absolute_pixel_position, 0, 0, 0, |
| 8564 | doc: /* Return absolute position of mouse cursor in pixels. | 9096 | doc: /* Return absolute position of mouse cursor in pixels. |
| @@ -9753,6 +10285,13 @@ frame_parm_handler w32_frame_parm_handlers[] = | |||
| 9753 | 0, /* x_set_sticky */ | 10285 | 0, /* x_set_sticky */ |
| 9754 | 0, /* x_set_tool_bar_position */ | 10286 | 0, /* x_set_tool_bar_position */ |
| 9755 | 0, /* x_set_inhibit_double_buffering */ | 10287 | 0, /* x_set_inhibit_double_buffering */ |
| 10288 | x_set_undecorated, | ||
| 10289 | x_set_parent_frame, | ||
| 10290 | x_set_skip_taskbar, | ||
| 10291 | x_set_no_focus_on_map, | ||
| 10292 | x_set_no_accept_focus, | ||
| 10293 | x_set_z_group, | ||
| 10294 | 0, /* x_set_override_redirect */ | ||
| 9756 | }; | 10295 | }; |
| 9757 | 10296 | ||
| 9758 | void | 10297 | void |
| @@ -10132,6 +10671,8 @@ tip frame. */); | |||
| 10132 | defsubr (&Sx_display_list); | 10671 | defsubr (&Sx_display_list); |
| 10133 | defsubr (&Sw32_frame_geometry); | 10672 | defsubr (&Sw32_frame_geometry); |
| 10134 | defsubr (&Sw32_frame_edges); | 10673 | defsubr (&Sw32_frame_edges); |
| 10674 | defsubr (&Sw32_frame_list_z_order); | ||
| 10675 | defsubr (&Sw32_frame_restack); | ||
| 10135 | defsubr (&Sw32_mouse_absolute_pixel_position); | 10676 | defsubr (&Sw32_mouse_absolute_pixel_position); |
| 10136 | defsubr (&Sw32_set_mouse_absolute_pixel_position); | 10677 | defsubr (&Sw32_set_mouse_absolute_pixel_position); |
| 10137 | defsubr (&Sx_synchronize); | 10678 | defsubr (&Sx_synchronize); |
diff --git a/src/w32font.c b/src/w32font.c index 37df1bc43c0..ef6eac44a68 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -2553,11 +2553,22 @@ in the font selection dialog. */) | |||
| 2553 | SelectObject (hdc, oldobj); | 2553 | SelectObject (hdc, oldobj); |
| 2554 | ReleaseDC (FRAME_W32_WINDOW (f), hdc); | 2554 | ReleaseDC (FRAME_W32_WINDOW (f), hdc); |
| 2555 | 2555 | ||
| 2556 | if (!ChooseFont (&cf) | 2556 | { |
| 2557 | || logfont_to_fcname (&lf, cf.iPointSize, buf, 100) < 0) | 2557 | int count = SPECPDL_INDEX (); |
| 2558 | return Qnil; | 2558 | Lisp_Object value = Qnil; |
| 2559 | |||
| 2560 | w32_dialog_in_progress (Qt); | ||
| 2561 | specbind (Qinhibit_redisplay, Qt); | ||
| 2562 | record_unwind_protect (w32_dialog_in_progress, Qnil); | ||
| 2563 | |||
| 2564 | if (ChooseFont (&cf) | ||
| 2565 | && logfont_to_fcname (&lf, cf.iPointSize, buf, 100) >= 0) | ||
| 2566 | value = DECODE_SYSTEM (build_string (buf)); | ||
| 2559 | 2567 | ||
| 2560 | return DECODE_SYSTEM (build_string (buf)); | 2568 | unbind_to (count, Qnil); |
| 2569 | |||
| 2570 | return value; | ||
| 2571 | } | ||
| 2561 | } | 2572 | } |
| 2562 | 2573 | ||
| 2563 | static const char *const w32font_booleans [] = { | 2574 | static const char *const w32font_booleans [] = { |
diff --git a/src/w32term.c b/src/w32term.c index 31f0b4a2fa0..b50f0d39a48 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -3095,7 +3095,8 @@ construct_mouse_wheel (struct input_event *result, W32Msg *msg, struct frame *f) | |||
| 3095 | coordinates, so cast to short to interpret them correctly. */ | 3095 | coordinates, so cast to short to interpret them correctly. */ |
| 3096 | p.x = (short) LOWORD (msg->msg.lParam); | 3096 | p.x = (short) LOWORD (msg->msg.lParam); |
| 3097 | p.y = (short) HIWORD (msg->msg.lParam); | 3097 | p.y = (short) HIWORD (msg->msg.lParam); |
| 3098 | ScreenToClient (msg->msg.hwnd, &p); | 3098 | /* For the case that F's w32 window is not msg->msg.hwnd. */ |
| 3099 | ScreenToClient (FRAME_W32_WINDOW (f), &p); | ||
| 3099 | XSETINT (result->x, p.x); | 3100 | XSETINT (result->x, p.x); |
| 3100 | XSETINT (result->y, p.y); | 3101 | XSETINT (result->y, p.y); |
| 3101 | XSETFRAME (result->frame_or_window, f); | 3102 | XSETFRAME (result->frame_or_window, f); |
| @@ -3446,8 +3447,22 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 3446 | /* If mouse was grabbed on a frame, give coords for that | 3447 | /* If mouse was grabbed on a frame, give coords for that |
| 3447 | frame even if the mouse is now outside it. Otherwise | 3448 | frame even if the mouse is now outside it. Otherwise |
| 3448 | check for window under mouse on one of our frames. */ | 3449 | check for window under mouse on one of our frames. */ |
| 3449 | f1 = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame | 3450 | if (x_mouse_grabbed (dpyinfo)) |
| 3450 | : x_any_window_to_frame (dpyinfo, WindowFromPoint (pt))); | 3451 | f1 = dpyinfo->last_mouse_frame; |
| 3452 | else | ||
| 3453 | { | ||
| 3454 | HWND wfp = WindowFromPoint (pt); | ||
| 3455 | |||
| 3456 | if (wfp && (f1 = x_any_window_to_frame (dpyinfo, wfp))) | ||
| 3457 | { | ||
| 3458 | HWND cwfp = ChildWindowFromPoint (wfp, pt); | ||
| 3459 | struct frame *f2; | ||
| 3460 | |||
| 3461 | /* If cwfp exists it should be one of our windows ... */ | ||
| 3462 | if (cwfp && (f2 = x_any_window_to_frame (dpyinfo, cwfp))) | ||
| 3463 | f1 = f2; | ||
| 3464 | } | ||
| 3465 | } | ||
| 3451 | 3466 | ||
| 3452 | /* If not, is it one of our scroll bars? */ | 3467 | /* If not, is it one of our scroll bars? */ |
| 3453 | if (! f1) | 3468 | if (! f1) |
| @@ -3897,7 +3912,10 @@ w32_set_vertical_scroll_bar (struct window *w, | |||
| 3897 | /* Make sure scroll bar is "visible" before moving, to ensure the | 3912 | /* Make sure scroll bar is "visible" before moving, to ensure the |
| 3898 | area of the parent window now exposed will be refreshed. */ | 3913 | area of the parent window now exposed will be refreshed. */ |
| 3899 | my_show_window (f, hwnd, SW_HIDE); | 3914 | my_show_window (f, hwnd, SW_HIDE); |
| 3900 | MoveWindow (hwnd, left, top, width, max (height, 1), TRUE); | 3915 | /** MoveWindow (hwnd, left, top, width, max (height, 1), TRUE); **/ |
| 3916 | /* Try to not draw over child frames. */ | ||
| 3917 | SetWindowPos (hwnd, HWND_BOTTOM, left, top, width, max (height, 1), | ||
| 3918 | SWP_FRAMECHANGED); | ||
| 3901 | 3919 | ||
| 3902 | si.cbSize = sizeof (si); | 3920 | si.cbSize = sizeof (si); |
| 3903 | si.fMask = SIF_RANGE; | 3921 | si.fMask = SIF_RANGE; |
| @@ -3995,7 +4013,10 @@ w32_set_horizontal_scroll_bar (struct window *w, | |||
| 3995 | /* Make sure scroll bar is "visible" before moving, to ensure the | 4013 | /* Make sure scroll bar is "visible" before moving, to ensure the |
| 3996 | area of the parent window now exposed will be refreshed. */ | 4014 | area of the parent window now exposed will be refreshed. */ |
| 3997 | my_show_window (f, hwnd, SW_HIDE); | 4015 | my_show_window (f, hwnd, SW_HIDE); |
| 3998 | MoveWindow (hwnd, left, top, width, max (height, 1), TRUE); | 4016 | /** MoveWindow (hwnd, left, top, width, max (height, 1), TRUE); **/ |
| 4017 | /* Try to not draw over child frames. */ | ||
| 4018 | SetWindowPos (hwnd, HWND_BOTTOM, left, top, max (width, 1), height, | ||
| 4019 | SWP_FRAMECHANGED); | ||
| 3999 | 4020 | ||
| 4000 | /* +++ SetScrollInfo +++ */ | 4021 | /* +++ SetScrollInfo +++ */ |
| 4001 | si.cbSize = sizeof (si); | 4022 | si.cbSize = sizeof (si); |
| @@ -4649,7 +4670,7 @@ w32_read_socket (struct terminal *terminal, | |||
| 4649 | in that case expose_frame will do nothing, and if | 4670 | in that case expose_frame will do nothing, and if |
| 4650 | the various redisplay flags happen to be unset, | 4671 | the various redisplay flags happen to be unset, |
| 4651 | we are left with a blank frame. */ | 4672 | we are left with a blank frame. */ |
| 4652 | if (!FRAME_GARBAGED_P (f)) | 4673 | if (!FRAME_GARBAGED_P (f) || FRAME_PARENT_FRAME (f)) |
| 4653 | { | 4674 | { |
| 4654 | HDC hdc = get_frame_dc (f); | 4675 | HDC hdc = get_frame_dc (f); |
| 4655 | 4676 | ||
| @@ -4835,8 +4856,15 @@ w32_read_socket (struct terminal *terminal, | |||
| 4835 | 4856 | ||
| 4836 | if (f) | 4857 | if (f) |
| 4837 | { | 4858 | { |
| 4838 | /* Generate SELECT_WINDOW_EVENTs when needed. */ | 4859 | /* Maybe generate SELECT_WINDOW_EVENTs for |
| 4839 | if (!NILP (Vmouse_autoselect_window)) | 4860 | `mouse-autoselect-window'. */ |
| 4861 | if (!NILP (Vmouse_autoselect_window) | ||
| 4862 | && (f == XFRAME (selected_frame) | ||
| 4863 | /* Switch to f from another frame iff | ||
| 4864 | focus_follows_mouse is set and f accepts | ||
| 4865 | focus. */ | ||
| 4866 | || (!NILP (focus_follows_mouse) | ||
| 4867 | && !FRAME_NO_ACCEPT_FOCUS (f)))) | ||
| 4840 | { | 4868 | { |
| 4841 | static Lisp_Object last_mouse_window; | 4869 | static Lisp_Object last_mouse_window; |
| 4842 | Lisp_Object window = window_from_coordinates | 4870 | Lisp_Object window = window_from_coordinates |
| @@ -4848,20 +4876,16 @@ w32_read_socket (struct terminal *terminal, | |||
| 4848 | only when it is active. */ | 4876 | only when it is active. */ |
| 4849 | if (WINDOWP (window) | 4877 | if (WINDOWP (window) |
| 4850 | && !EQ (window, last_mouse_window) | 4878 | && !EQ (window, last_mouse_window) |
| 4851 | && !EQ (window, selected_window) | 4879 | && !EQ (window, selected_window)) |
| 4852 | /* For click-to-focus window managers | ||
| 4853 | create event iff we don't leave the | ||
| 4854 | selected frame. */ | ||
| 4855 | && (focus_follows_mouse | ||
| 4856 | || (EQ (XWINDOW (window)->frame, | ||
| 4857 | XWINDOW (selected_window)->frame)))) | ||
| 4858 | { | 4880 | { |
| 4859 | inev.kind = SELECT_WINDOW_EVENT; | 4881 | inev.kind = SELECT_WINDOW_EVENT; |
| 4860 | inev.frame_or_window = window; | 4882 | inev.frame_or_window = window; |
| 4861 | } | 4883 | } |
| 4884 | |||
| 4862 | /* Remember the last window where we saw the mouse. */ | 4885 | /* Remember the last window where we saw the mouse. */ |
| 4863 | last_mouse_window = window; | 4886 | last_mouse_window = window; |
| 4864 | } | 4887 | } |
| 4888 | |||
| 4865 | if (!note_mouse_movement (f, &msg.msg)) | 4889 | if (!note_mouse_movement (f, &msg.msg)) |
| 4866 | help_echo_string = previous_help_echo_string; | 4890 | help_echo_string = previous_help_echo_string; |
| 4867 | } | 4891 | } |
| @@ -4927,7 +4951,10 @@ w32_read_socket (struct terminal *terminal, | |||
| 4927 | 4951 | ||
| 4928 | if (tool_bar_p | 4952 | if (tool_bar_p |
| 4929 | || (dpyinfo->w32_focus_frame | 4953 | || (dpyinfo->w32_focus_frame |
| 4930 | && f != dpyinfo->w32_focus_frame)) | 4954 | && f != dpyinfo->w32_focus_frame |
| 4955 | /* This does not help when the click happens in | ||
| 4956 | a grand-parent frame. */ | ||
| 4957 | && !frame_ancestor_p (f, dpyinfo->w32_focus_frame))) | ||
| 4931 | inev.kind = NO_EVENT; | 4958 | inev.kind = NO_EVENT; |
| 4932 | } | 4959 | } |
| 4933 | 4960 | ||
| @@ -4964,21 +4991,40 @@ w32_read_socket (struct terminal *terminal, | |||
| 4964 | 4991 | ||
| 4965 | if (f) | 4992 | if (f) |
| 4966 | { | 4993 | { |
| 4967 | |||
| 4968 | if (!dpyinfo->w32_focus_frame | 4994 | if (!dpyinfo->w32_focus_frame |
| 4969 | || f == dpyinfo->w32_focus_frame) | 4995 | || f == dpyinfo->w32_focus_frame) |
| 4996 | /* Emit an Emacs wheel-up/down event. */ | ||
| 4970 | { | 4997 | { |
| 4971 | /* Emit an Emacs wheel-up/down event. */ | ||
| 4972 | construct_mouse_wheel (&inev, &msg, f); | 4998 | construct_mouse_wheel (&inev, &msg, f); |
| 4999 | |||
| 5000 | /* Ignore any mouse motion that happened before this | ||
| 5001 | event; any subsequent mouse-movement Emacs events | ||
| 5002 | should reflect only motion after the ButtonPress. */ | ||
| 5003 | f->mouse_moved = false; | ||
| 5004 | f->last_tool_bar_item = -1; | ||
| 5005 | dpyinfo->last_mouse_frame = f; | ||
| 5006 | } | ||
| 5007 | else if (FRAME_NO_ACCEPT_FOCUS (f) | ||
| 5008 | && !x_mouse_grabbed (dpyinfo)) | ||
| 5009 | { | ||
| 5010 | Lisp_Object frame1 = get_frame_param (f, Qmouse_wheel_frame); | ||
| 5011 | struct frame *f1 = FRAMEP (frame1) ? XFRAME (frame1) : NULL; | ||
| 5012 | |||
| 5013 | if (f1 && FRAME_LIVE_P (f1) && FRAME_W32_P (f1)) | ||
| 5014 | { | ||
| 5015 | construct_mouse_wheel (&inev, &msg, f1); | ||
| 5016 | f1->mouse_moved = false; | ||
| 5017 | f1->last_tool_bar_item = -1; | ||
| 5018 | dpyinfo->last_mouse_frame = f1; | ||
| 5019 | } | ||
| 5020 | else | ||
| 5021 | dpyinfo->last_mouse_frame = f; | ||
| 4973 | } | 5022 | } |
| 4974 | /* Ignore any mouse motion that happened before this | 5023 | else |
| 4975 | event; any subsequent mouse-movement Emacs events | 5024 | dpyinfo->last_mouse_frame = f; |
| 4976 | should reflect only motion after the | ||
| 4977 | ButtonPress. */ | ||
| 4978 | f->mouse_moved = false; | ||
| 4979 | f->last_tool_bar_item = -1; | ||
| 4980 | } | 5025 | } |
| 4981 | dpyinfo->last_mouse_frame = f; | 5026 | else |
| 5027 | dpyinfo->last_mouse_frame = f; | ||
| 4982 | } | 5028 | } |
| 4983 | break; | 5029 | break; |
| 4984 | 5030 | ||
| @@ -5031,6 +5077,7 @@ w32_read_socket (struct terminal *terminal, | |||
| 5031 | w32fullscreen_hook (f); | 5077 | w32fullscreen_hook (f); |
| 5032 | } | 5078 | } |
| 5033 | } | 5079 | } |
| 5080 | |||
| 5034 | check_visibility = 1; | 5081 | check_visibility = 1; |
| 5035 | break; | 5082 | break; |
| 5036 | 5083 | ||
| @@ -5969,6 +6016,8 @@ x_calc_absolute_position (struct frame *f) | |||
| 5969 | are computed correctly (Bug#21173). */ | 6016 | are computed correctly (Bug#21173). */ |
| 5970 | int display_left = 0; | 6017 | int display_left = 0; |
| 5971 | int display_top = 0; | 6018 | int display_top = 0; |
| 6019 | struct frame *p = FRAME_PARENT_FRAME (f); | ||
| 6020 | |||
| 5972 | if (flags & (XNegative | YNegative)) | 6021 | if (flags & (XNegative | YNegative)) |
| 5973 | { | 6022 | { |
| 5974 | Lisp_Object list; | 6023 | Lisp_Object list; |
| @@ -5997,18 +6046,34 @@ x_calc_absolute_position (struct frame *f) | |||
| 5997 | /* Treat negative positions as relative to the rightmost bottommost | 6046 | /* Treat negative positions as relative to the rightmost bottommost |
| 5998 | position that fits on the screen. */ | 6047 | position that fits on the screen. */ |
| 5999 | if (flags & XNegative) | 6048 | if (flags & XNegative) |
| 6000 | f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | 6049 | { |
| 6001 | + display_left | 6050 | if (p) |
| 6002 | - FRAME_PIXEL_WIDTH (f) | 6051 | f->left_pos = (FRAME_PIXEL_WIDTH (p) |
| 6003 | + f->left_pos | 6052 | - FRAME_PIXEL_WIDTH (f) |
| 6004 | - (left_right_borders_width - 1)); | 6053 | + f->left_pos |
| 6054 | - (left_right_borders_width - 1)); | ||
| 6055 | else | ||
| 6056 | f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | ||
| 6057 | + display_left | ||
| 6058 | - FRAME_PIXEL_WIDTH (f) | ||
| 6059 | + f->left_pos | ||
| 6060 | - (left_right_borders_width - 1)); | ||
| 6061 | } | ||
| 6005 | 6062 | ||
| 6006 | if (flags & YNegative) | 6063 | if (flags & YNegative) |
| 6007 | f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | 6064 | { |
| 6008 | + display_top | 6065 | if (p) |
| 6009 | - FRAME_PIXEL_HEIGHT (f) | 6066 | f->top_pos = (FRAME_PIXEL_HEIGHT (p) |
| 6010 | + f->top_pos | 6067 | - FRAME_PIXEL_HEIGHT (f) |
| 6011 | - (top_bottom_borders_height - 1)); | 6068 | + f->top_pos |
| 6069 | - (top_bottom_borders_height - 1)); | ||
| 6070 | else | ||
| 6071 | f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | ||
| 6072 | + display_top | ||
| 6073 | - FRAME_PIXEL_HEIGHT (f) | ||
| 6074 | + f->top_pos | ||
| 6075 | - (top_bottom_borders_height - 1)); | ||
| 6076 | } | ||
| 6012 | 6077 | ||
| 6013 | /* The left_pos and top_pos are now relative to the top and left | 6078 | /* The left_pos and top_pos are now relative to the top and left |
| 6014 | screen edges, so the flags should correspond. */ | 6079 | screen edges, so the flags should correspond. */ |
| @@ -6046,11 +6111,16 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, | |||
| 6046 | modified_left = f->left_pos; | 6111 | modified_left = f->left_pos; |
| 6047 | modified_top = f->top_pos; | 6112 | modified_top = f->top_pos; |
| 6048 | 6113 | ||
| 6049 | my_set_window_pos (FRAME_W32_WINDOW (f), | 6114 | if (!FRAME_PARENT_FRAME (f)) |
| 6050 | NULL, | 6115 | my_set_window_pos (FRAME_W32_WINDOW (f), NULL, |
| 6051 | modified_left, modified_top, | 6116 | modified_left, modified_top, |
| 6052 | 0, 0, | 6117 | 0, 0, |
| 6053 | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); | 6118 | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); |
| 6119 | else | ||
| 6120 | my_set_window_pos (FRAME_W32_WINDOW (f), HWND_TOP, | ||
| 6121 | modified_left, modified_top, | ||
| 6122 | 0, 0, | ||
| 6123 | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); | ||
| 6054 | unblock_input (); | 6124 | unblock_input (); |
| 6055 | } | 6125 | } |
| 6056 | 6126 | ||
| @@ -6254,11 +6324,18 @@ x_set_window_size (struct frame *f, bool change_gravity, | |||
| 6254 | Fcons (make_number (rect.right - rect.left), | 6324 | Fcons (make_number (rect.right - rect.left), |
| 6255 | make_number (rect.bottom - rect.top)))); | 6325 | make_number (rect.bottom - rect.top)))); |
| 6256 | 6326 | ||
| 6257 | my_set_window_pos (FRAME_W32_WINDOW (f), NULL, | 6327 | if (!FRAME_PARENT_FRAME (f)) |
| 6258 | 0, 0, | 6328 | my_set_window_pos (FRAME_W32_WINDOW (f), NULL, |
| 6259 | rect.right - rect.left, | 6329 | 0, 0, |
| 6260 | rect.bottom - rect.top, | 6330 | rect.right - rect.left, |
| 6261 | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); | 6331 | rect.bottom - rect.top, |
| 6332 | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); | ||
| 6333 | else | ||
| 6334 | my_set_window_pos (FRAME_W32_WINDOW (f), HWND_TOP, | ||
| 6335 | 0, 0, | ||
| 6336 | rect.right - rect.left, | ||
| 6337 | rect.bottom - rect.top, | ||
| 6338 | SWP_NOMOVE | SWP_NOACTIVATE); | ||
| 6262 | 6339 | ||
| 6263 | change_frame_size (f, | 6340 | change_frame_size (f, |
| 6264 | ((pixelwidth == 0) | 6341 | ((pixelwidth == 0) |
| @@ -6447,18 +6524,21 @@ x_make_frame_visible (struct frame *f) | |||
| 6447 | if (! FRAME_ICONIFIED_P (f) | 6524 | if (! FRAME_ICONIFIED_P (f) |
| 6448 | && ! f->output_data.w32->asked_for_visible) | 6525 | && ! f->output_data.w32->asked_for_visible) |
| 6449 | { | 6526 | { |
| 6450 | RECT workarea_rect; | 6527 | if (!FRAME_PARENT_FRAME (f)) |
| 6451 | RECT window_rect; | 6528 | { |
| 6452 | 6529 | RECT workarea_rect; | |
| 6453 | /* Adjust vertical window position in order to avoid being | 6530 | RECT window_rect; |
| 6454 | covered by a taskbar placed at the bottom of the desktop. */ | 6531 | |
| 6455 | SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); | 6532 | /* Adjust vertical window position in order to avoid being |
| 6456 | GetWindowRect (FRAME_W32_WINDOW (f), &window_rect); | 6533 | covered by a taskbar placed at the bottom of the desktop. */ |
| 6457 | if (window_rect.bottom > workarea_rect.bottom | 6534 | SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); |
| 6458 | && window_rect.top > workarea_rect.top) | 6535 | GetWindowRect (FRAME_W32_WINDOW (f), &window_rect); |
| 6459 | f->top_pos = max (window_rect.top | 6536 | if (window_rect.bottom > workarea_rect.bottom |
| 6460 | - window_rect.bottom + workarea_rect.bottom, | 6537 | && window_rect.top > workarea_rect.top) |
| 6461 | workarea_rect.top); | 6538 | f->top_pos = max (window_rect.top |
| 6539 | - window_rect.bottom + workarea_rect.bottom, | ||
| 6540 | workarea_rect.top); | ||
| 6541 | } | ||
| 6462 | 6542 | ||
| 6463 | x_set_offset (f, f->left_pos, f->top_pos, 0); | 6543 | x_set_offset (f, f->left_pos, f->top_pos, 0); |
| 6464 | } | 6544 | } |
| @@ -6473,7 +6553,11 @@ x_make_frame_visible (struct frame *f) | |||
| 6473 | set for minimized windows that are still visible, so use that to | 6553 | set for minimized windows that are still visible, so use that to |
| 6474 | determine the appropriate flag to pass ShowWindow. */ | 6554 | determine the appropriate flag to pass ShowWindow. */ |
| 6475 | my_show_window (f, FRAME_W32_WINDOW (f), | 6555 | my_show_window (f, FRAME_W32_WINDOW (f), |
| 6476 | FRAME_ICONIFIED_P (f) ? SW_RESTORE : SW_SHOWNORMAL); | 6556 | FRAME_ICONIFIED_P (f) |
| 6557 | ? SW_RESTORE | ||
| 6558 | : FRAME_NO_FOCUS_ON_MAP (f) | ||
| 6559 | ? SW_SHOWNOACTIVATE | ||
| 6560 | : SW_SHOWNORMAL); | ||
| 6477 | } | 6561 | } |
| 6478 | 6562 | ||
| 6479 | /* Synchronize to ensure Emacs knows the frame is visible | 6563 | /* Synchronize to ensure Emacs knows the frame is visible |
diff --git a/src/w32term.h b/src/w32term.h index 990d3794b22..6896ef4f2c6 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -246,6 +246,7 @@ extern void x_set_internal_border_width (struct frame *f, | |||
| 246 | Lisp_Object value, | 246 | Lisp_Object value, |
| 247 | Lisp_Object oldval); | 247 | Lisp_Object oldval); |
| 248 | extern void initialize_frame_menubar (struct frame *); | 248 | extern void initialize_frame_menubar (struct frame *); |
| 249 | extern void w32_dialog_in_progress (Lisp_Object in_progress); | ||
| 249 | 250 | ||
| 250 | /* w32inevt.c */ | 251 | /* w32inevt.c */ |
| 251 | extern int w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId); | 252 | extern int w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId); |
diff --git a/src/xdisp.c b/src/xdisp.c index af086d17eb8..42a59d63b13 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -11767,6 +11767,7 @@ x_consider_frame_title (Lisp_Object frame) | |||
| 11767 | && FRAME_KBOARD (tf) == FRAME_KBOARD (f) | 11767 | && FRAME_KBOARD (tf) == FRAME_KBOARD (f) |
| 11768 | && !FRAME_MINIBUF_ONLY_P (tf) | 11768 | && !FRAME_MINIBUF_ONLY_P (tf) |
| 11769 | && !EQ (other_frame, tip_frame) | 11769 | && !EQ (other_frame, tip_frame) |
| 11770 | && !FRAME_PARENT_FRAME (tf) | ||
| 11770 | && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf))) | 11771 | && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf))) |
| 11771 | break; | 11772 | break; |
| 11772 | } | 11773 | } |
| @@ -11883,6 +11884,7 @@ prepare_menu_bars (void) | |||
| 11883 | continue; | 11884 | continue; |
| 11884 | 11885 | ||
| 11885 | if (!EQ (frame, tooltip_frame) | 11886 | if (!EQ (frame, tooltip_frame) |
| 11887 | && !FRAME_PARENT_FRAME (f) | ||
| 11886 | && (FRAME_ICONIFIED_P (f) | 11888 | && (FRAME_ICONIFIED_P (f) |
| 11887 | || FRAME_VISIBLE_P (f) == 1 | 11889 | || FRAME_VISIBLE_P (f) == 1 |
| 11888 | /* Exclude TTY frames that are obscured because they | 11890 | /* Exclude TTY frames that are obscured because they |
| @@ -11929,6 +11931,10 @@ prepare_menu_bars (void) | |||
| 11929 | continue; | 11931 | continue; |
| 11930 | 11932 | ||
| 11931 | run_window_size_change_functions (frame); | 11933 | run_window_size_change_functions (frame); |
| 11934 | |||
| 11935 | if (FRAME_PARENT_FRAME (f)) | ||
| 11936 | continue; | ||
| 11937 | |||
| 11932 | menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run); | 11938 | menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run); |
| 11933 | #ifdef HAVE_WINDOW_SYSTEM | 11939 | #ifdef HAVE_WINDOW_SYSTEM |
| 11934 | update_tool_bar (f, false); | 11940 | update_tool_bar (f, false); |
diff --git a/src/xfns.c b/src/xfns.c index d3e0839d8ac..3d667446e67 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -90,6 +90,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 90 | #include <Xm/FileSB.h> | 90 | #include <Xm/FileSB.h> |
| 91 | #include <Xm/List.h> | 91 | #include <Xm/List.h> |
| 92 | #include <Xm/TextF.h> | 92 | #include <Xm/TextF.h> |
| 93 | #include <Xm/MwmUtil.h> | ||
| 93 | #endif | 94 | #endif |
| 94 | 95 | ||
| 95 | #ifdef USE_LUCID | 96 | #ifdef USE_LUCID |
| @@ -117,6 +118,35 @@ static ptrdiff_t image_cache_refcount; | |||
| 117 | static int dpyinfo_refcount; | 118 | static int dpyinfo_refcount; |
| 118 | #endif | 119 | #endif |
| 119 | 120 | ||
| 121 | #ifndef USE_MOTIF | ||
| 122 | #ifndef USE_GTK | ||
| 123 | /** #define MWM_HINTS_FUNCTIONS (1L << 0) **/ | ||
| 124 | #define MWM_HINTS_DECORATIONS (1L << 1) | ||
| 125 | /** #define MWM_HINTS_INPUT_MODE (1L << 2) **/ | ||
| 126 | /** #define MWM_HINTS_STATUS (1L << 3) **/ | ||
| 127 | |||
| 128 | #define MWM_DECOR_ALL (1L << 0) | ||
| 129 | /** #define MWM_DECOR_BORDER (1L << 1) **/ | ||
| 130 | /** #define MWM_DECOR_RESIZEH (1L << 2) **/ | ||
| 131 | /** #define MWM_DECOR_TITLE (1L << 3) **/ | ||
| 132 | /** #define MWM_DECOR_MENU (1L << 4) **/ | ||
| 133 | /** #define MWM_DECOR_MINIMIZE (1L << 5) **/ | ||
| 134 | /** #define MWM_DECOR_MAXIMIZE (1L << 6) **/ | ||
| 135 | |||
| 136 | /** #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" **/ | ||
| 137 | |||
| 138 | typedef struct { | ||
| 139 | unsigned long flags; | ||
| 140 | unsigned long functions; | ||
| 141 | unsigned long decorations; | ||
| 142 | long input_mode; | ||
| 143 | unsigned long status; | ||
| 144 | } PropMotifWmHints; | ||
| 145 | |||
| 146 | #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 | ||
| 147 | #endif /* NOT USE_GTK */ | ||
| 148 | #endif /* NOT USE_MOTIF */ | ||
| 149 | |||
| 120 | static struct x_display_info *x_display_info_for_name (Lisp_Object); | 150 | static struct x_display_info *x_display_info_for_name (Lisp_Object); |
| 121 | static void set_up_x_back_buffer (struct frame *f); | 151 | static void set_up_x_back_buffer (struct frame *f); |
| 122 | 152 | ||
| @@ -185,7 +215,9 @@ x_real_pos_and_offsets (struct frame *f, | |||
| 185 | int win_x = 0, win_y = 0, outer_x = 0, outer_y = 0; | 215 | int win_x = 0, win_y = 0, outer_x = 0, outer_y = 0; |
| 186 | int real_x = 0, real_y = 0; | 216 | int real_x = 0, real_y = 0; |
| 187 | bool had_errors = false; | 217 | bool had_errors = false; |
| 188 | Window win = f->output_data.x->parent_desc; | 218 | Window win = (FRAME_PARENT_FRAME (f) |
| 219 | ? FRAME_X_WINDOW (FRAME_PARENT_FRAME (f)) | ||
| 220 | : f->output_data.x->parent_desc); | ||
| 189 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | 221 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 190 | long max_len = 400; | 222 | long max_len = 400; |
| 191 | Atom target_type = XA_CARDINAL; | 223 | Atom target_type = XA_CARDINAL; |
| @@ -323,7 +355,8 @@ x_real_pos_and_offsets (struct frame *f, | |||
| 323 | outer_geom_cookie = xcb_get_geometry (xcb_conn, | 355 | outer_geom_cookie = xcb_get_geometry (xcb_conn, |
| 324 | FRAME_OUTER_WINDOW (f)); | 356 | FRAME_OUTER_WINDOW (f)); |
| 325 | 357 | ||
| 326 | if (dpyinfo->root_window == f->output_data.x->parent_desc) | 358 | if ((dpyinfo->root_window == f->output_data.x->parent_desc) |
| 359 | && !FRAME_PARENT_FRAME (f)) | ||
| 327 | /* Try _NET_FRAME_EXTENTS if our parent is the root window. */ | 360 | /* Try _NET_FRAME_EXTENTS if our parent is the root window. */ |
| 328 | prop_cookie = xcb_get_property (xcb_conn, 0, win, | 361 | prop_cookie = xcb_get_property (xcb_conn, 0, win, |
| 329 | dpyinfo->Xatom_net_frame_extents, | 362 | dpyinfo->Xatom_net_frame_extents, |
| @@ -437,7 +470,8 @@ x_real_pos_and_offsets (struct frame *f, | |||
| 437 | #endif | 470 | #endif |
| 438 | } | 471 | } |
| 439 | 472 | ||
| 440 | if (dpyinfo->root_window == f->output_data.x->parent_desc) | 473 | if ((dpyinfo->root_window == f->output_data.x->parent_desc) |
| 474 | && !FRAME_PARENT_FRAME (f)) | ||
| 441 | { | 475 | { |
| 442 | /* Try _NET_FRAME_EXTENTS if our parent is the root window. */ | 476 | /* Try _NET_FRAME_EXTENTS if our parent is the root window. */ |
| 443 | #ifdef USE_XCB | 477 | #ifdef USE_XCB |
| @@ -735,6 +769,204 @@ x_set_inhibit_double_buffering (struct frame *f, | |||
| 735 | unblock_input (); | 769 | unblock_input (); |
| 736 | } | 770 | } |
| 737 | 771 | ||
| 772 | /** | ||
| 773 | * x_set_undecorated: | ||
| 774 | * | ||
| 775 | * Set frame F's `undecorated' parameter. If non-nil, F's window-system | ||
| 776 | * window is drawn without decorations, title, minimize/maximize boxes | ||
| 777 | * and external borders. This usually means that the window cannot be | ||
| 778 | * dragged, resized, iconified, maximized or deleted with the mouse. If | ||
| 779 | * nil, draw the frame with all the elements listed above unless these | ||
| 780 | * have been suspended via window manager settings. | ||
| 781 | * | ||
| 782 | * Some window managers may not honor this parameter. | ||
| 783 | */ | ||
| 784 | static void | ||
| 785 | x_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 786 | { | ||
| 787 | if (!EQ (new_value, old_value)) | ||
| 788 | { | ||
| 789 | FRAME_UNDECORATED (f) = NILP (new_value) ? false : true; | ||
| 790 | #ifdef USE_GTK | ||
| 791 | xg_set_undecorated (f, new_value); | ||
| 792 | #else | ||
| 793 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 794 | PropMotifWmHints hints; | ||
| 795 | Atom prop = XInternAtom (dpy, "_MOTIF_WM_HINTS", False); | ||
| 796 | |||
| 797 | memset (&hints, 0, sizeof(hints)); | ||
| 798 | hints.flags = MWM_HINTS_DECORATIONS; | ||
| 799 | hints.decorations = NILP (new_value) ? MWM_DECOR_ALL : 0; | ||
| 800 | |||
| 801 | block_input (); | ||
| 802 | /* For some reason the third and fourth argument in the following | ||
| 803 | call must be identic: In the corresponding XGetWindowProperty | ||
| 804 | call in getMotifHints, xfwm has the third and seventh arg both | ||
| 805 | display_info->atoms[MOTIF_WM_HINTS]. Obviously, YMMV. */ | ||
| 806 | XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, prop, 32, | ||
| 807 | PropModeReplace, (unsigned char *) &hints, | ||
| 808 | PROP_MOTIF_WM_HINTS_ELEMENTS); | ||
| 809 | unblock_input (); | ||
| 810 | |||
| 811 | #endif /* USE_GTK */ | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | /** | ||
| 816 | * x_set_parent_frame: | ||
| 817 | * | ||
| 818 | * Set frame F's `parent-frame' parameter. If non-nil, make F a child | ||
| 819 | * frame of the frame specified by that parameter. Technically, this | ||
| 820 | * makes F's window-system window a child window of the parent frame's | ||
| 821 | * window-system window. If nil, make F's window-system window a | ||
| 822 | * top-level window--a child of its display's root window. | ||
| 823 | * | ||
| 824 | * A child frame is clipped at the native edges of its parent frame. | ||
| 825 | * Its `left' and `top' parameters specify positions relative to the | ||
| 826 | * top-left corner of its parent frame's native rectangle. Usually, | ||
| 827 | * moving a parent frame moves all its child frames too, keeping their | ||
| 828 | * position relative to the parent unaltered. When a parent frame is | ||
| 829 | * iconified or made invisible, its child frames are made invisible. | ||
| 830 | * When a parent frame is deleted, its child frames are deleted too. | ||
| 831 | * | ||
| 832 | * A visible child frame always appears on top of its parent frame thus | ||
| 833 | * obscuring parts of it. When a frame has more than one child frame, | ||
| 834 | * their stacking order is specified just as that of non-child frames | ||
| 835 | * relative to their display. | ||
| 836 | * | ||
| 837 | * Whether a child frame has a menu or tool bar may be window-system or | ||
| 838 | * window manager dependent. It's advisable to disable both via the | ||
| 839 | * frame parameter settings. | ||
| 840 | * | ||
| 841 | * Some window managers may not honor this parameter. | ||
| 842 | */ | ||
| 843 | static void | ||
| 844 | x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 845 | { | ||
| 846 | struct frame *p = NULL; | ||
| 847 | |||
| 848 | if (!NILP (new_value) | ||
| 849 | && (!FRAMEP (new_value) | ||
| 850 | || !FRAME_LIVE_P (p = XFRAME (new_value)) | ||
| 851 | || !FRAME_X_P (p))) | ||
| 852 | { | ||
| 853 | store_frame_param (f, Qparent_frame, old_value); | ||
| 854 | error ("Invalid specification of `parent-frame'"); | ||
| 855 | } | ||
| 856 | |||
| 857 | if (p != FRAME_PARENT_FRAME (f)) | ||
| 858 | { | ||
| 859 | block_input (); | ||
| 860 | XReparentWindow | ||
| 861 | (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 862 | p ? FRAME_X_WINDOW (p) : DefaultRootWindow (FRAME_X_DISPLAY (f)), | ||
| 863 | f->left_pos, f->top_pos); | ||
| 864 | unblock_input (); | ||
| 865 | |||
| 866 | fset_parent_frame (f, new_value); | ||
| 867 | } | ||
| 868 | } | ||
| 869 | |||
| 870 | /** | ||
| 871 | * x_set_no_focus_on_map: | ||
| 872 | * | ||
| 873 | * Set frame F's `no-focus-on-map' parameter which, if non-nil, means | ||
| 874 | * that F's window-system window does not want to receive input focus | ||
| 875 | * when it is mapped. (A frame's window is mapped when the frame is | ||
| 876 | * displayed for the first time and when the frame changes its state | ||
| 877 | * from `iconified' or `invisible' to `visible'.) | ||
| 878 | * | ||
| 879 | * Some window managers may not honor this parameter. | ||
| 880 | */ | ||
| 881 | static void | ||
| 882 | x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 883 | { | ||
| 884 | if (!EQ (new_value, old_value)) | ||
| 885 | { | ||
| 886 | #ifdef USE_GTK | ||
| 887 | xg_set_no_focus_on_map (f, new_value); | ||
| 888 | #else /* not USE_GTK */ | ||
| 889 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 890 | Atom prop = XInternAtom (dpy, "_NET_WM_USER_TIME", False); | ||
| 891 | Time timestamp = NILP (new_value) ? CurrentTime : 0; | ||
| 892 | |||
| 893 | XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, | ||
| 894 | XA_CARDINAL, 32, PropModeReplace, | ||
| 895 | (unsigned char *) ×tamp, 1); | ||
| 896 | #endif /* USE_GTK */ | ||
| 897 | FRAME_NO_FOCUS_ON_MAP (f) = !NILP (new_value); | ||
| 898 | } | ||
| 899 | } | ||
| 900 | |||
| 901 | /** | ||
| 902 | * x_set_no_accept_focus: | ||
| 903 | * | ||
| 904 | * Set frame F's `no-accept-focus' parameter which, if non-nil, hints | ||
| 905 | * that F's window-system window does not want to receive input focus | ||
| 906 | * via mouse clicks or by moving the mouse into it. | ||
| 907 | * | ||
| 908 | * If non-nil, this may have the unwanted side-effect that a user cannot | ||
| 909 | * scroll a non-selected frame with the mouse. | ||
| 910 | * | ||
| 911 | * Some window managers may not honor this parameter. | ||
| 912 | */ | ||
| 913 | static void | ||
| 914 | x_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 915 | { | ||
| 916 | if (!EQ (new_value, old_value)) | ||
| 917 | { | ||
| 918 | #ifdef USE_GTK | ||
| 919 | xg_set_no_accept_focus (f, new_value); | ||
| 920 | #else /* not USE_GTK */ | ||
| 921 | #ifdef USE_X_TOOLKIT | ||
| 922 | Arg al[1]; | ||
| 923 | |||
| 924 | XtSetArg (al[0], XtNinput, NILP (new_value) ? True : False); | ||
| 925 | XtSetValues (f->output_data.x->widget, al, 1); | ||
| 926 | #else /* not USE_X_TOOLKIT */ | ||
| 927 | Window window = FRAME_X_WINDOW (f); | ||
| 928 | |||
| 929 | f->output_data.x->wm_hints.input = NILP (new_value) ? True : False; | ||
| 930 | XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints); | ||
| 931 | #endif /* USE_X_TOOLKIT */ | ||
| 932 | #endif /* USE_GTK */ | ||
| 933 | FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value); | ||
| 934 | } | ||
| 935 | } | ||
| 936 | |||
| 937 | /** | ||
| 938 | * x_set_override_redirect: | ||
| 939 | * | ||
| 940 | * Set frame F's `override_redirect' parameter which, if non-nil, hints | ||
| 941 | * that the window manager doesn't want to deal with F. Usually, such | ||
| 942 | * frames have no decorations and always appear on top of all frames. | ||
| 943 | * | ||
| 944 | * Some window managers may not honor this parameter. | ||
| 945 | */ | ||
| 946 | static void | ||
| 947 | x_set_override_redirect (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 948 | { | ||
| 949 | if (!EQ (new_value, old_value)) | ||
| 950 | { | ||
| 951 | /* Here (xfwm) override_redirect can be changed for invisible | ||
| 952 | frames only. */ | ||
| 953 | x_make_frame_invisible (f); | ||
| 954 | |||
| 955 | #ifdef USE_GTK | ||
| 956 | xg_set_override_redirect (f, new_value); | ||
| 957 | #else /* not USE_GTK */ | ||
| 958 | XSetWindowAttributes attributes; | ||
| 959 | |||
| 960 | attributes.override_redirect = NILP (new_value) ? False : True; | ||
| 961 | XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 962 | CWOverrideRedirect, &attributes); | ||
| 963 | #endif | ||
| 964 | x_make_frame_visible (f); | ||
| 965 | FRAME_OVERRIDE_REDIRECT (f) = !NILP (new_value); | ||
| 966 | } | ||
| 967 | } | ||
| 968 | |||
| 969 | |||
| 738 | #ifdef USE_GTK | 970 | #ifdef USE_GTK |
| 739 | 971 | ||
| 740 | /* Set icon from FILE for frame F. By using GTK functions the icon | 972 | /* Set icon from FILE for frame F. By using GTK functions the icon |
| @@ -1272,7 +1504,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | |||
| 1272 | most of the commands try to apply themselves to the minibuffer | 1504 | most of the commands try to apply themselves to the minibuffer |
| 1273 | frame itself, and get an error because you can't switch buffers | 1505 | frame itself, and get an error because you can't switch buffers |
| 1274 | in or split the minibuffer window. */ | 1506 | in or split the minibuffer window. */ |
| 1275 | if (FRAME_MINIBUF_ONLY_P (f)) | 1507 | if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f)) |
| 1276 | return; | 1508 | return; |
| 1277 | 1509 | ||
| 1278 | if (TYPE_RANGED_INTEGERP (int, value)) | 1510 | if (TYPE_RANGED_INTEGERP (int, value)) |
| @@ -2693,7 +2925,7 @@ x_window (struct frame *f, long window_prompting) | |||
| 2693 | and specify it. | 2925 | and specify it. |
| 2694 | Note that we do not specify here whether the position | 2926 | Note that we do not specify here whether the position |
| 2695 | is a user-specified or program-specified one. | 2927 | is a user-specified or program-specified one. |
| 2696 | We pass that information later, in x_wm_set_size_hints. */ | 2928 | We pass that information later, in x_wm_set_size_hint. */ |
| 2697 | { | 2929 | { |
| 2698 | int left = f->left_pos; | 2930 | int left = f->left_pos; |
| 2699 | bool xneg = (window_prompting & XNegative) != 0; | 2931 | bool xneg = (window_prompting & XNegative) != 0; |
| @@ -2783,7 +3015,8 @@ x_window (struct frame *f, long window_prompting) | |||
| 2783 | } | 3015 | } |
| 2784 | #endif /* HAVE_X_I18N */ | 3016 | #endif /* HAVE_X_I18N */ |
| 2785 | 3017 | ||
| 2786 | attribute_mask = CWEventMask; | 3018 | attributes.override_redirect = FRAME_OVERRIDE_REDIRECT (f); |
| 3019 | attribute_mask = CWEventMask | CWOverrideRedirect; | ||
| 2787 | XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget), | 3020 | XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget), |
| 2788 | attribute_mask, &attributes); | 3021 | attribute_mask, &attributes); |
| 2789 | 3022 | ||
| @@ -2803,6 +3036,25 @@ x_window (struct frame *f, long window_prompting) | |||
| 2803 | x_set_name (f, name, explicit); | 3036 | x_set_name (f, name, explicit); |
| 2804 | } | 3037 | } |
| 2805 | 3038 | ||
| 3039 | if (FRAME_UNDECORATED (f)) | ||
| 3040 | { | ||
| 3041 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 3042 | PropMotifWmHints hints; | ||
| 3043 | Atom prop = XInternAtom (dpy, "_MOTIF_WM_HINTS", False); | ||
| 3044 | |||
| 3045 | memset (&hints, 0, sizeof(hints)); | ||
| 3046 | hints.flags = MWM_HINTS_DECORATIONS; | ||
| 3047 | hints.decorations = 0; | ||
| 3048 | |||
| 3049 | /* For some reason the third and fourth argument in the following | ||
| 3050 | call must be identic: In the corresponding XGetWindowProperty | ||
| 3051 | call in getMotifHints, xfwm has the third and seventh arg both | ||
| 3052 | display_info->atoms[MOTIF_WM_HINTS]. Obviously, YMMV. */ | ||
| 3053 | XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, prop, 32, | ||
| 3054 | PropModeReplace, (unsigned char *) &hints, | ||
| 3055 | PROP_MOTIF_WM_HINTS_ELEMENTS); | ||
| 3056 | } | ||
| 3057 | |||
| 2806 | XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3058 | XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 2807 | f->output_data.x->current_cursor | 3059 | f->output_data.x->current_cursor |
| 2808 | = f->output_data.x->text_cursor); | 3060 | = f->output_data.x->text_cursor); |
| @@ -2870,8 +3122,9 @@ x_window (struct frame *f) | |||
| 2870 | attributes.save_under = True; | 3122 | attributes.save_under = True; |
| 2871 | attributes.event_mask = STANDARD_EVENT_SET; | 3123 | attributes.event_mask = STANDARD_EVENT_SET; |
| 2872 | attributes.colormap = FRAME_X_COLORMAP (f); | 3124 | attributes.colormap = FRAME_X_COLORMAP (f); |
| 3125 | attributes.override_redirect = FRAME_OVERRIDE_REDIRECT (f); | ||
| 2873 | attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | 3126 | attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask |
| 2874 | | CWColormap); | 3127 | | CWOverrideRedirect | CWColormap); |
| 2875 | 3128 | ||
| 2876 | block_input (); | 3129 | block_input (); |
| 2877 | FRAME_X_WINDOW (f) | 3130 | FRAME_X_WINDOW (f) |
| @@ -2943,6 +3196,26 @@ x_window (struct frame *f) | |||
| 2943 | x_set_name (f, name, explicit); | 3196 | x_set_name (f, name, explicit); |
| 2944 | } | 3197 | } |
| 2945 | 3198 | ||
| 3199 | if (FRAME_UNDECORATED (f)) | ||
| 3200 | { | ||
| 3201 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 3202 | PropMotifWmHints hints; | ||
| 3203 | Atom prop = XInternAtom (dpy, "_MOTIF_WM_HINTS", False); | ||
| 3204 | |||
| 3205 | memset (&hints, 0, sizeof(hints)); | ||
| 3206 | hints.flags = MWM_HINTS_DECORATIONS; | ||
| 3207 | hints.decorations = 0; | ||
| 3208 | |||
| 3209 | /* For some reason the third and fourth argument in the following | ||
| 3210 | call must be identic: In the corresponding XGetWindowProperty | ||
| 3211 | call in getMotifHints, xfwm has the third and seventh arg both | ||
| 3212 | display_info->atoms[MOTIF_WM_HINTS]. Obviously, YMMV. */ | ||
| 3213 | XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, prop, 32, | ||
| 3214 | PropModeReplace, (unsigned char *) &hints, | ||
| 3215 | PROP_MOTIF_WM_HINTS_ELEMENTS); | ||
| 3216 | } | ||
| 3217 | |||
| 3218 | |||
| 2946 | XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3219 | XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 2947 | f->output_data.x->current_cursor | 3220 | f->output_data.x->current_cursor |
| 2948 | = f->output_data.x->text_cursor); | 3221 | = f->output_data.x->text_cursor); |
| @@ -3285,11 +3558,12 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3285 | Lisp_Object frame, tem; | 3558 | Lisp_Object frame, tem; |
| 3286 | Lisp_Object name; | 3559 | Lisp_Object name; |
| 3287 | bool minibuffer_only = false; | 3560 | bool minibuffer_only = false; |
| 3561 | bool undecorated = false, override_redirect = false; | ||
| 3288 | long window_prompting = 0; | 3562 | long window_prompting = 0; |
| 3289 | ptrdiff_t count = SPECPDL_INDEX (); | 3563 | ptrdiff_t count = SPECPDL_INDEX (); |
| 3290 | Lisp_Object display; | 3564 | Lisp_Object display; |
| 3291 | struct x_display_info *dpyinfo = NULL; | 3565 | struct x_display_info *dpyinfo = NULL; |
| 3292 | Lisp_Object parent; | 3566 | Lisp_Object parent, parent_frame; |
| 3293 | struct kboard *kb; | 3567 | struct kboard *kb; |
| 3294 | int x_width = 0, x_height = 0; | 3568 | int x_width = 0, x_height = 0; |
| 3295 | 3569 | ||
| @@ -3341,6 +3615,36 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3341 | else | 3615 | else |
| 3342 | f = make_frame (true); | 3616 | f = make_frame (true); |
| 3343 | 3617 | ||
| 3618 | parent_frame = x_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL, | ||
| 3619 | RES_TYPE_SYMBOL); | ||
| 3620 | /* Accept parent-frame iff parent-id was not specified. */ | ||
| 3621 | if (!NILP (parent) | ||
| 3622 | || EQ (parent_frame, Qunbound) | ||
| 3623 | || NILP (parent_frame) | ||
| 3624 | || !FRAMEP (parent_frame) | ||
| 3625 | || !FRAME_LIVE_P (XFRAME (parent_frame)) | ||
| 3626 | || !FRAME_X_P (XFRAME (parent_frame))) | ||
| 3627 | parent_frame = Qnil; | ||
| 3628 | |||
| 3629 | fset_parent_frame (f, parent_frame); | ||
| 3630 | store_frame_param (f, Qparent_frame, parent_frame); | ||
| 3631 | |||
| 3632 | if (!NILP (tem = (x_get_arg (dpyinfo, parms, Qundecorated, NULL, NULL, | ||
| 3633 | RES_TYPE_BOOLEAN))) | ||
| 3634 | && !(EQ (tem, Qunbound))) | ||
| 3635 | undecorated = true; | ||
| 3636 | |||
| 3637 | FRAME_UNDECORATED (f) = undecorated; | ||
| 3638 | store_frame_param (f, Qundecorated, undecorated ? Qt : Qnil); | ||
| 3639 | |||
| 3640 | if (!NILP (tem = (x_get_arg (dpyinfo, parms, Qoverride_redirect, NULL, NULL, | ||
| 3641 | RES_TYPE_BOOLEAN))) | ||
| 3642 | && !(EQ (tem, Qunbound))) | ||
| 3643 | override_redirect = true; | ||
| 3644 | |||
| 3645 | FRAME_OVERRIDE_REDIRECT (f) = override_redirect; | ||
| 3646 | store_frame_param (f, Qoverride_redirect, override_redirect ? Qt : Qnil); | ||
| 3647 | |||
| 3344 | XSETFRAME (frame, f); | 3648 | XSETFRAME (frame, f); |
| 3345 | 3649 | ||
| 3346 | f->terminal = dpyinfo->terminal; | 3650 | f->terminal = dpyinfo->terminal; |
| @@ -3528,15 +3832,24 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3528 | init_iterator with a null face cache, which should not happen. */ | 3832 | init_iterator with a null face cache, which should not happen. */ |
| 3529 | init_frame_faces (f); | 3833 | init_frame_faces (f); |
| 3530 | 3834 | ||
| 3531 | /* The following call of change_frame_size is needed since otherwise | 3835 | /* We have to call adjust_frame_size here since otherwise |
| 3532 | x_set_tool_bar_lines will already work with the character sizes | 3836 | x_set_tool_bar_lines will already work with the character sizes |
| 3533 | installed by init_frame_faces while the frame's pixel size is | 3837 | installed by init_frame_faces while the frame's pixel size is still |
| 3534 | still calculated from a character size of 1 and we subsequently | 3838 | calculated from a character size of 1 and we subsequently hit the |
| 3535 | hit the (height >= 0) assertion in window_box_height. | 3839 | (height >= 0) assertion in window_box_height. |
| 3536 | 3840 | ||
| 3537 | The non-pixelwise code apparently worked around this because it | 3841 | The non-pixelwise code apparently worked around this because it |
| 3538 | had one frame line vs one toolbar line which left us with a zero | 3842 | had one frame line vs one toolbar line which left us with a zero |
| 3539 | root window height which was obviously wrong as well ... */ | 3843 | root window height which was obviously wrong as well ... |
| 3844 | |||
| 3845 | Also process `min-width' and `min-height' parameters right here | ||
| 3846 | because `frame-windows-min-size' needs them. */ | ||
| 3847 | tem = x_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL, RES_TYPE_NUMBER); | ||
| 3848 | if (NUMBERP (tem)) | ||
| 3849 | store_frame_param (f, Qmin_width, tem); | ||
| 3850 | tem = x_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL, RES_TYPE_NUMBER); | ||
| 3851 | if (NUMBERP (tem)) | ||
| 3852 | store_frame_param (f, Qmin_height, tem); | ||
| 3540 | adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), | 3853 | adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), |
| 3541 | FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true, | 3854 | FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true, |
| 3542 | Qx_create_frame_1); | 3855 | Qx_create_frame_1); |
| @@ -3611,6 +3924,21 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3611 | x_default_parameter (f, parms, Qalpha, Qnil, | 3924 | x_default_parameter (f, parms, Qalpha, Qnil, |
| 3612 | "alpha", "Alpha", RES_TYPE_NUMBER); | 3925 | "alpha", "Alpha", RES_TYPE_NUMBER); |
| 3613 | 3926 | ||
| 3927 | if (!NILP (parent_frame)) | ||
| 3928 | { | ||
| 3929 | struct frame *p = XFRAME (parent_frame); | ||
| 3930 | |||
| 3931 | block_input (); | ||
| 3932 | XReparentWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 3933 | FRAME_X_WINDOW (p), f->left_pos, f->top_pos); | ||
| 3934 | unblock_input (); | ||
| 3935 | } | ||
| 3936 | |||
| 3937 | x_default_parameter (f, parms, Qno_focus_on_map, Qnil, | ||
| 3938 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 3939 | x_default_parameter (f, parms, Qno_accept_focus, Qnil, | ||
| 3940 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 3941 | |||
| 3614 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | 3942 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) |
| 3615 | /* Create the menu bar. */ | 3943 | /* Create the menu bar. */ |
| 3616 | if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) | 3944 | if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) |
| @@ -3656,23 +3984,23 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3656 | /* Make the window appear on the frame and enable display, unless | 3984 | /* Make the window appear on the frame and enable display, unless |
| 3657 | the caller says not to. However, with explicit parent, Emacs | 3985 | the caller says not to. However, with explicit parent, Emacs |
| 3658 | cannot control visibility, so don't try. */ | 3986 | cannot control visibility, so don't try. */ |
| 3659 | if (! f->output_data.x->explicit_parent) | 3987 | if (!f->output_data.x->explicit_parent) |
| 3660 | { | 3988 | { |
| 3661 | Lisp_Object visibility; | 3989 | Lisp_Object visibility |
| 3662 | 3990 | = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL); | |
| 3663 | visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, | ||
| 3664 | RES_TYPE_SYMBOL); | ||
| 3665 | if (EQ (visibility, Qunbound)) | ||
| 3666 | visibility = Qt; | ||
| 3667 | 3991 | ||
| 3668 | if (EQ (visibility, Qicon)) | 3992 | if (EQ (visibility, Qicon)) |
| 3669 | x_iconify_frame (f); | 3993 | x_iconify_frame (f); |
| 3670 | else if (! NILP (visibility)) | ||
| 3671 | x_make_frame_visible (f); | ||
| 3672 | else | 3994 | else |
| 3673 | { | 3995 | { |
| 3674 | /* Must have been Qnil. */ | 3996 | if (EQ (visibility, Qunbound)) |
| 3997 | visibility = Qt; | ||
| 3998 | |||
| 3999 | if (!NILP (visibility)) | ||
| 4000 | x_make_frame_visible (f); | ||
| 3675 | } | 4001 | } |
| 4002 | |||
| 4003 | store_frame_param (f, Qvisibility, visibility); | ||
| 3676 | } | 4004 | } |
| 3677 | 4005 | ||
| 3678 | block_input (); | 4006 | block_input (); |
| @@ -3685,14 +4013,21 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3685 | if (dpyinfo->client_leader_window != 0) | 4013 | if (dpyinfo->client_leader_window != 0) |
| 3686 | { | 4014 | { |
| 3687 | XChangeProperty (FRAME_X_DISPLAY (f), | 4015 | XChangeProperty (FRAME_X_DISPLAY (f), |
| 3688 | FRAME_OUTER_WINDOW (f), | 4016 | FRAME_OUTER_WINDOW (f), |
| 3689 | dpyinfo->Xatom_wm_client_leader, | 4017 | dpyinfo->Xatom_wm_client_leader, |
| 3690 | XA_WINDOW, 32, PropModeReplace, | 4018 | XA_WINDOW, 32, PropModeReplace, |
| 3691 | (unsigned char *) &dpyinfo->client_leader_window, 1); | 4019 | (unsigned char *) &dpyinfo->client_leader_window, 1); |
| 3692 | } | 4020 | } |
| 3693 | 4021 | ||
| 3694 | unblock_input (); | 4022 | unblock_input (); |
| 3695 | 4023 | ||
| 4024 | /* Works iff frame has been already mapped. */ | ||
| 4025 | x_default_parameter (f, parms, Qskip_taskbar, Qnil, | ||
| 4026 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 4027 | /* The `z-group' parameter works only for visible frames. */ | ||
| 4028 | x_default_parameter (f, parms, Qz_group, Qnil, | ||
| 4029 | NULL, NULL, RES_TYPE_SYMBOL); | ||
| 4030 | |||
| 3696 | /* Initialize `default-minibuffer-frame' in case this is the first | 4031 | /* Initialize `default-minibuffer-frame' in case this is the first |
| 3697 | frame on this terminal. */ | 4032 | frame on this terminal. */ |
| 3698 | if (FRAME_HAS_MINIBUF_P (f) | 4033 | if (FRAME_HAS_MINIBUF_P (f) |
| @@ -3710,7 +4045,7 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3710 | and similar functions. */ | 4045 | and similar functions. */ |
| 3711 | Vwindow_list = Qnil; | 4046 | Vwindow_list = Qnil; |
| 3712 | 4047 | ||
| 3713 | return unbind_to (count, frame); | 4048 | return unbind_to (count, frame); |
| 3714 | } | 4049 | } |
| 3715 | 4050 | ||
| 3716 | 4051 | ||
| @@ -4644,9 +4979,9 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 4644 | struct frame *f = decode_live_frame (frame); | 4979 | struct frame *f = decode_live_frame (frame); |
| 4645 | /** XWindowAttributes atts; **/ | 4980 | /** XWindowAttributes atts; **/ |
| 4646 | Window rootw; | 4981 | Window rootw; |
| 4647 | unsigned int ign, native_width, native_height; | 4982 | unsigned int ign, native_width, native_height, x_border_width = 0; |
| 4648 | int xy_ign, xptr, yptr; | 4983 | int x_native = 0, y_native = 0, xptr = 0, yptr = 0; |
| 4649 | int left_off, right_off, top_off, bottom_off; | 4984 | int left_off = 0, right_off = 0, top_off = 0, bottom_off = 0; |
| 4650 | int outer_left, outer_top, outer_right, outer_bottom; | 4985 | int outer_left, outer_top, outer_right, outer_bottom; |
| 4651 | int native_left, native_top, native_right, native_bottom; | 4986 | int native_left, native_top, native_right, native_bottom; |
| 4652 | int inner_left, inner_top, inner_right, inner_bottom; | 4987 | int inner_left, inner_top, inner_right, inner_bottom; |
| @@ -4660,25 +4995,51 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 4660 | 4995 | ||
| 4661 | block_input (); | 4996 | block_input (); |
| 4662 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | 4997 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), |
| 4663 | &rootw, &xy_ign, &xy_ign, &native_width, &native_height, | 4998 | &rootw, &x_native, &y_native, &native_width, &native_height, |
| 4664 | &ign, &ign); | 4999 | &x_border_width, &ign); |
| 4665 | /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/ | 5000 | /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/ |
| 4666 | x_real_pos_and_offsets (f, &left_off, &right_off, &top_off, &bottom_off, | 5001 | if (!FRAME_PARENT_FRAME (f)) |
| 4667 | NULL, NULL, &xptr, &yptr, NULL); | 5002 | x_real_pos_and_offsets (f, &left_off, &right_off, &top_off, &bottom_off, |
| 5003 | NULL, NULL, &xptr, &yptr, NULL); | ||
| 4668 | unblock_input (); | 5004 | unblock_input (); |
| 4669 | 5005 | ||
| 4670 | /** native_width = atts.width; **/ | 5006 | /** native_width = atts.width; **/ |
| 4671 | /** native_height = atts.height; **/ | 5007 | /** native_height = atts.height; **/ |
| 4672 | 5008 | ||
| 4673 | outer_left = xptr; | 5009 | if (FRAME_PARENT_FRAME (f)) |
| 4674 | outer_top = yptr; | 5010 | { |
| 4675 | outer_right = outer_left + left_off + native_width + right_off; | 5011 | Lisp_Object parent, edges; |
| 4676 | outer_bottom = outer_top + top_off + native_height + bottom_off; | 5012 | |
| 5013 | XSETFRAME (parent, FRAME_PARENT_FRAME (f)); | ||
| 5014 | edges = Fx_frame_edges (parent, Qnative_edges); | ||
| 5015 | if (!NILP (edges)) | ||
| 5016 | { | ||
| 5017 | x_native += XINT (Fnth (make_number (0), edges)); | ||
| 5018 | y_native += XINT (Fnth (make_number (1), edges)); | ||
| 5019 | } | ||
| 5020 | |||
| 5021 | outer_left = x_native; | ||
| 5022 | outer_top = y_native; | ||
| 5023 | outer_right = outer_left + native_width + 2 * x_border_width; | ||
| 5024 | outer_bottom = outer_top + native_height + 2 * x_border_width; | ||
| 5025 | |||
| 5026 | native_left = x_native + x_border_width; | ||
| 5027 | native_top = y_native + x_border_width; | ||
| 5028 | native_right = native_left + native_width; | ||
| 5029 | native_bottom = native_top + native_height; | ||
| 5030 | } | ||
| 5031 | else | ||
| 5032 | { | ||
| 5033 | outer_left = xptr; | ||
| 5034 | outer_top = yptr; | ||
| 5035 | outer_right = outer_left + left_off + native_width + right_off; | ||
| 5036 | outer_bottom = outer_top + top_off + native_height + bottom_off; | ||
| 4677 | 5037 | ||
| 4678 | native_left = outer_left + left_off; | 5038 | native_left = outer_left + left_off; |
| 4679 | native_top = outer_top + top_off; | 5039 | native_top = outer_top + top_off; |
| 4680 | native_right = native_left + native_width; | 5040 | native_right = native_left + native_width; |
| 4681 | native_bottom = native_top + native_height; | 5041 | native_bottom = native_top + native_height; |
| 5042 | } | ||
| 4682 | 5043 | ||
| 4683 | internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f); | 5044 | internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f); |
| 4684 | inner_left = native_left + internal_border_width; | 5045 | inner_left = native_left + internal_border_width; |
| @@ -4749,7 +5110,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 4749 | make_number (inner_right), make_number (inner_bottom)); | 5110 | make_number (inner_right), make_number (inner_bottom)); |
| 4750 | else | 5111 | else |
| 4751 | return | 5112 | return |
| 4752 | listn (CONSTYPE_HEAP, 10, | 5113 | listn (CONSTYPE_HEAP, 11, |
| 4753 | Fcons (Qouter_position, | 5114 | Fcons (Qouter_position, |
| 4754 | Fcons (make_number (outer_left), | 5115 | Fcons (make_number (outer_left), |
| 4755 | make_number (outer_top))), | 5116 | make_number (outer_top))), |
| @@ -4760,6 +5121,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 4760 | Fcons (Qexternal_border_size, | 5121 | Fcons (Qexternal_border_size, |
| 4761 | Fcons (make_number (right_off), | 5122 | Fcons (make_number (right_off), |
| 4762 | make_number (bottom_off))), | 5123 | make_number (bottom_off))), |
| 5124 | Fcons (Qouter_border_width, make_number (x_border_width)), | ||
| 4763 | /* Approximate. */ | 5125 | /* Approximate. */ |
| 4764 | Fcons (Qtitle_bar_size, | 5126 | Fcons (Qtitle_bar_size, |
| 4765 | Fcons (make_number (0), | 5127 | Fcons (make_number (0), |
| @@ -4788,7 +5150,8 @@ and width values are in pixels. | |||
| 4788 | 5150 | ||
| 4789 | `outer-size' is a cons of the outer width and height of FRAME. The | 5151 | `outer-size' is a cons of the outer width and height of FRAME. The |
| 4790 | outer size includes the title bar and the external borders as well as | 5152 | outer size includes the title bar and the external borders as well as |
| 4791 | any menu and/or tool bar of frame. | 5153 | any menu and/or tool bar of frame. For a child frame the value |
| 5154 | includes FRAME's X borders, if any. | ||
| 4792 | 5155 | ||
| 4793 | `external-border-size' is a cons of the horizontal and vertical width of | 5156 | `external-border-size' is a cons of the horizontal and vertical width of |
| 4794 | FRAME's external borders as supplied by the window manager. | 5157 | FRAME's external borders as supplied by the window manager. |
| @@ -4815,7 +5178,11 @@ and width values are in pixels. | |||
| 4815 | FRAME. | 5178 | FRAME. |
| 4816 | 5179 | ||
| 4817 | `internal-border-width' is the width of the internal border of | 5180 | `internal-border-width' is the width of the internal border of |
| 4818 | FRAME. */) | 5181 | FRAME. |
| 5182 | |||
| 5183 | `outer-border-width' is the width of the X border of FRAME. The X | ||
| 5184 | border is usually only shown for frames without window manager | ||
| 5185 | decorations like child and tooltip frames. */) | ||
| 4819 | (Lisp_Object frame) | 5186 | (Lisp_Object frame) |
| 4820 | { | 5187 | { |
| 4821 | return frame_geometry (frame, Qnil); | 5188 | return frame_geometry (frame, Qnil); |
| @@ -4845,6 +5212,139 @@ menu bar or tool bar of FRAME. */) | |||
| 4845 | : Qnative_edges)); | 5212 | : Qnative_edges)); |
| 4846 | } | 5213 | } |
| 4847 | 5214 | ||
| 5215 | /** | ||
| 5216 | * x_frame_list_z_order: | ||
| 5217 | * | ||
| 5218 | * Recursively add list of all frames on the display specified via | ||
| 5219 | * DPYINFO and whose window-system window's parent is specified by | ||
| 5220 | * WINDOW to FRAMES and return FRAMES. | ||
| 5221 | */ | ||
| 5222 | static Lisp_Object | ||
| 5223 | x_frame_list_z_order (Display* dpy, Window window) | ||
| 5224 | { | ||
| 5225 | Window root, parent, *children; | ||
| 5226 | unsigned int nchildren; | ||
| 5227 | int i; | ||
| 5228 | Lisp_Object frames = Qnil; | ||
| 5229 | |||
| 5230 | block_input (); | ||
| 5231 | if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren)) | ||
| 5232 | { | ||
| 5233 | unblock_input (); | ||
| 5234 | for (i = 0; i < nchildren; i++) | ||
| 5235 | { | ||
| 5236 | Lisp_Object frame, tail; | ||
| 5237 | |||
| 5238 | FOR_EACH_FRAME (tail, frame) | ||
| 5239 | /* With a reparenting window manager the parent_desc field | ||
| 5240 | usually specifies the topmost windows of our frames. | ||
| 5241 | Otherwise FRAME_OUTER_WINDOW should do. */ | ||
| 5242 | if (XFRAME (frame)->output_data.x->parent_desc == children[i] | ||
| 5243 | || FRAME_OUTER_WINDOW (XFRAME (frame)) == children[i]) | ||
| 5244 | frames = Fcons (frame, frames); | ||
| 5245 | } | ||
| 5246 | |||
| 5247 | if (children) XFree ((char *)children); | ||
| 5248 | } | ||
| 5249 | else | ||
| 5250 | unblock_input (); | ||
| 5251 | |||
| 5252 | return frames; | ||
| 5253 | } | ||
| 5254 | |||
| 5255 | |||
| 5256 | DEFUN ("x-frame-list-z-order", Fx_frame_list_z_order, | ||
| 5257 | Sx_frame_list_z_order, 0, 1, 0, | ||
| 5258 | doc: /* Return list of Emacs' frames, in Z (stacking) order. | ||
| 5259 | The optional argument TERMINAL specifies which display to ask about. | ||
| 5260 | TERMINAL should be either a frame or a display name (a string). If | ||
| 5261 | omitted or nil, that stands for the selected frame's display. Return | ||
| 5262 | nil if TERMINAL contains no Emacs frame. | ||
| 5263 | |||
| 5264 | As a special case, if TERMINAL is non-nil and specifies a live frame, | ||
| 5265 | return the child frames of that frame in Z (stacking) order. | ||
| 5266 | |||
| 5267 | Frames are listed from topmost (first) to bottommost (last). */) | ||
| 5268 | (Lisp_Object terminal) | ||
| 5269 | { | ||
| 5270 | struct x_display_info *dpyinfo = check_x_display_info (terminal); | ||
| 5271 | Display *dpy = dpyinfo->display; | ||
| 5272 | Window window; | ||
| 5273 | |||
| 5274 | if (FRAMEP (terminal) && FRAME_LIVE_P (XFRAME (terminal))) | ||
| 5275 | window = FRAME_X_WINDOW (XFRAME (terminal)); | ||
| 5276 | else | ||
| 5277 | window = dpyinfo->root_window; | ||
| 5278 | |||
| 5279 | return x_frame_list_z_order (dpy, window); | ||
| 5280 | } | ||
| 5281 | |||
| 5282 | /** | ||
| 5283 | * x_frame_restack: | ||
| 5284 | * | ||
| 5285 | * Restack frame F1 below frame F2, above if ABOVE_FLAG is non-nil. In | ||
| 5286 | * practice this is a two-step action: The first step removes F1's | ||
| 5287 | * window-system window from the display. The second step reinserts | ||
| 5288 | * F1's window below (above if ABOVE_FLAG is true) that of F2. | ||
| 5289 | */ | ||
| 5290 | static void | ||
| 5291 | x_frame_restack (struct frame *f1, struct frame *f2, bool above_flag) | ||
| 5292 | { | ||
| 5293 | #ifdef USE_GTK | ||
| 5294 | block_input (); | ||
| 5295 | xg_frame_restack (f1, f2, above_flag); | ||
| 5296 | unblock_input (); | ||
| 5297 | #else | ||
| 5298 | Display *dpy = FRAME_X_DISPLAY (f1); | ||
| 5299 | Window window1 = FRAME_OUTER_WINDOW (f1); | ||
| 5300 | XWindowChanges wc; | ||
| 5301 | unsigned long mask = (CWSibling | CWStackMode); | ||
| 5302 | |||
| 5303 | wc.sibling = FRAME_OUTER_WINDOW (f2); | ||
| 5304 | wc.stack_mode = above_flag ? Above : Below; | ||
| 5305 | block_input (); | ||
| 5306 | /* Configure the window manager window (a normal XConfigureWindow | ||
| 5307 | won't cut it). This should also work for child frames. */ | ||
| 5308 | XReconfigureWMWindow (dpy, window1, FRAME_X_SCREEN_NUMBER (f1), mask, &wc); | ||
| 5309 | unblock_input (); | ||
| 5310 | #endif /* USE_GTK */ | ||
| 5311 | } | ||
| 5312 | |||
| 5313 | |||
| 5314 | DEFUN ("x-frame-restack", Fx_frame_restack, Sx_frame_restack, 2, 3, 0, | ||
| 5315 | doc: /* Restack FRAME1 below FRAME2. | ||
| 5316 | This means that if both frames are visible and the display areas of | ||
| 5317 | these frames overlap, FRAME2 (partially) obscures FRAME1. If optional | ||
| 5318 | third argument ABOVE is non-nil, restack FRAME1 above FRAME2. This | ||
| 5319 | means that if both frames are visible and the display areas of these | ||
| 5320 | frames overlap, FRAME1 (partially) obscures FRAME2. | ||
| 5321 | |||
| 5322 | This may be thought of as an atomic action performed in two steps: The | ||
| 5323 | first step removes FRAME1's window-step window from the display. The | ||
| 5324 | second step reinserts FRAME1's window below (above if ABOVE is true) | ||
| 5325 | that of FRAME2. Hence the position of FRAME2 in its display's Z | ||
| 5326 | \(stacking) order relative to all other frames excluding FRAME1 remains | ||
| 5327 | unaltered. | ||
| 5328 | |||
| 5329 | Some window managers may refuse to restack windows. */) | ||
| 5330 | (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above) | ||
| 5331 | { | ||
| 5332 | struct frame *f1 = decode_live_frame (frame1); | ||
| 5333 | struct frame *f2 = decode_live_frame (frame2); | ||
| 5334 | |||
| 5335 | if (FRAME_OUTER_WINDOW (f1) && FRAME_OUTER_WINDOW (f2)) | ||
| 5336 | { | ||
| 5337 | x_frame_restack (f1, f2, !NILP (above)); | ||
| 5338 | return Qt; | ||
| 5339 | } | ||
| 5340 | else | ||
| 5341 | { | ||
| 5342 | error ("Cannot restack frames"); | ||
| 5343 | return Qnil; | ||
| 5344 | } | ||
| 5345 | } | ||
| 5346 | |||
| 5347 | |||
| 4848 | DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position, | 5348 | DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position, |
| 4849 | Sx_mouse_absolute_pixel_position, 0, 0, 0, | 5349 | Sx_mouse_absolute_pixel_position, 0, 0, 0, |
| 4850 | doc: /* Return absolute position of mouse cursor in pixels. | 5350 | doc: /* Return absolute position of mouse cursor in pixels. |
| @@ -6585,6 +7085,8 @@ value of DIR as in previous invocations; this is standard Windows behavior. */) | |||
| 6585 | 7085 | ||
| 6586 | if (popup_activated ()) | 7086 | if (popup_activated ()) |
| 6587 | error ("Trying to use a menu from within a menu-entry"); | 7087 | error ("Trying to use a menu from within a menu-entry"); |
| 7088 | else | ||
| 7089 | x_menu_set_in_use (true); | ||
| 6588 | 7090 | ||
| 6589 | CHECK_STRING (prompt); | 7091 | CHECK_STRING (prompt); |
| 6590 | CHECK_STRING (dir); | 7092 | CHECK_STRING (dir); |
| @@ -6641,6 +7143,8 @@ nil, it defaults to the selected frame. */) | |||
| 6641 | 7143 | ||
| 6642 | if (popup_activated ()) | 7144 | if (popup_activated ()) |
| 6643 | error ("Trying to use a menu from within a menu-entry"); | 7145 | error ("Trying to use a menu from within a menu-entry"); |
| 7146 | else | ||
| 7147 | x_menu_set_in_use (true); | ||
| 6644 | 7148 | ||
| 6645 | /* Prevent redisplay. */ | 7149 | /* Prevent redisplay. */ |
| 6646 | specbind (Qinhibit_redisplay, Qt); | 7150 | specbind (Qinhibit_redisplay, Qt); |
| @@ -6979,6 +7483,13 @@ frame_parm_handler x_frame_parm_handlers[] = | |||
| 6979 | x_set_sticky, | 7483 | x_set_sticky, |
| 6980 | x_set_tool_bar_position, | 7484 | x_set_tool_bar_position, |
| 6981 | x_set_inhibit_double_buffering, | 7485 | x_set_inhibit_double_buffering, |
| 7486 | x_set_undecorated, | ||
| 7487 | x_set_parent_frame, | ||
| 7488 | x_set_skip_taskbar, | ||
| 7489 | x_set_no_focus_on_map, | ||
| 7490 | x_set_no_accept_focus, | ||
| 7491 | x_set_z_group, | ||
| 7492 | x_set_override_redirect, | ||
| 6982 | }; | 7493 | }; |
| 6983 | 7494 | ||
| 6984 | void | 7495 | void |
| @@ -7183,6 +7694,8 @@ When using Gtk+ tooltips, the tooltip face is not used. */); | |||
| 7183 | defsubr (&Sx_display_monitor_attributes_list); | 7694 | defsubr (&Sx_display_monitor_attributes_list); |
| 7184 | defsubr (&Sx_frame_geometry); | 7695 | defsubr (&Sx_frame_geometry); |
| 7185 | defsubr (&Sx_frame_edges); | 7696 | defsubr (&Sx_frame_edges); |
| 7697 | defsubr (&Sx_frame_list_z_order); | ||
| 7698 | defsubr (&Sx_frame_restack); | ||
| 7186 | defsubr (&Sx_mouse_absolute_pixel_position); | 7699 | defsubr (&Sx_mouse_absolute_pixel_position); |
| 7187 | defsubr (&Sx_set_mouse_absolute_pixel_position); | 7700 | defsubr (&Sx_set_mouse_absolute_pixel_position); |
| 7188 | defsubr (&Sx_wm_set_size_hint); | 7701 | defsubr (&Sx_wm_set_size_hint); |
diff --git a/src/xmenu.c b/src/xmenu.c index 249cd6903fa..28052491646 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -140,14 +140,26 @@ menubar_id_to_frame (LWLIB_ID id) | |||
| 140 | void | 140 | void |
| 141 | x_menu_set_in_use (bool in_use) | 141 | x_menu_set_in_use (bool in_use) |
| 142 | { | 142 | { |
| 143 | Lisp_Object frames, frame; | ||
| 144 | |||
| 143 | menu_items_inuse = in_use ? Qt : Qnil; | 145 | menu_items_inuse = in_use ? Qt : Qnil; |
| 144 | popup_activated_flag = in_use; | 146 | popup_activated_flag = in_use; |
| 145 | #ifdef USE_X_TOOLKIT | 147 | #ifdef USE_X_TOOLKIT |
| 146 | if (popup_activated_flag) | 148 | if (popup_activated_flag) |
| 147 | x_activate_timeout_atimer (); | 149 | x_activate_timeout_atimer (); |
| 148 | #endif | 150 | #endif |
| 149 | } | ||
| 150 | 151 | ||
| 152 | /* Don't let frames in `above' z-group obscure popups. */ | ||
| 153 | FOR_EACH_FRAME (frames, frame) | ||
| 154 | { | ||
| 155 | struct frame *f = XFRAME (frame); | ||
| 156 | |||
| 157 | if (in_use && FRAME_Z_GROUP_ABOVE (f)) | ||
| 158 | x_set_z_group (f, Qabove_suspended, Qabove); | ||
| 159 | else if (!in_use && FRAME_Z_GROUP_ABOVE_SUSPENDED (f)) | ||
| 160 | x_set_z_group (f, Qabove, Qabove_suspended); | ||
| 161 | } | ||
| 162 | } | ||
| 151 | #endif | 163 | #endif |
| 152 | 164 | ||
| 153 | /* Wait for an X event to arrive or for a timer to expire. */ | 165 | /* Wait for an X event to arrive or for a timer to expire. */ |
diff --git a/src/xterm.c b/src/xterm.c index 1d14407aa43..4444a5c187a 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -945,11 +945,14 @@ x_set_frame_alpha (struct frame *f) | |||
| 945 | Do this unconditionally as this function is called on reparent when | 945 | Do this unconditionally as this function is called on reparent when |
| 946 | alpha has not changed on the frame. */ | 946 | alpha has not changed on the frame. */ |
| 947 | 947 | ||
| 948 | parent = x_find_topmost_parent (f); | 948 | if (!FRAME_PARENT_FRAME (f)) |
| 949 | if (parent != None) | 949 | { |
| 950 | XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, | 950 | parent = x_find_topmost_parent (f); |
| 951 | XA_CARDINAL, 32, PropModeReplace, | 951 | if (parent != None) |
| 952 | (unsigned char *) &opac, 1); | 952 | XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, |
| 953 | XA_CARDINAL, 32, PropModeReplace, | ||
| 954 | (unsigned char *) &opac, 1); | ||
| 955 | } | ||
| 953 | 956 | ||
| 954 | /* return unless necessary */ | 957 | /* return unless necessary */ |
| 955 | { | 958 | { |
| @@ -4964,6 +4967,9 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 4964 | containing the pointer. */ | 4967 | containing the pointer. */ |
| 4965 | { | 4968 | { |
| 4966 | Window win, child; | 4969 | Window win, child; |
| 4970 | #ifdef USE_GTK | ||
| 4971 | Window first_win = 0; | ||
| 4972 | #endif | ||
| 4967 | int win_x, win_y; | 4973 | int win_x, win_y; |
| 4968 | int parent_x = 0, parent_y = 0; | 4974 | int parent_x = 0, parent_y = 0; |
| 4969 | 4975 | ||
| @@ -5010,20 +5016,37 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 5010 | &child); | 5016 | &child); |
| 5011 | 5017 | ||
| 5012 | if (child == None || child == win) | 5018 | if (child == None || child == win) |
| 5013 | break; | 5019 | { |
| 5020 | #ifdef USE_GTK | ||
| 5021 | /* On GTK we have not inspected WIN yet. If it has | ||
| 5022 | a frame and that frame has a parent, use it. */ | ||
| 5023 | struct frame *f = x_window_to_frame (dpyinfo, win); | ||
| 5024 | |||
| 5025 | if (f && FRAME_PARENT_FRAME (f)) | ||
| 5026 | first_win = win; | ||
| 5027 | #endif | ||
| 5028 | break; | ||
| 5029 | } | ||
| 5014 | #ifdef USE_GTK | 5030 | #ifdef USE_GTK |
| 5015 | /* We don't wan't to know the innermost window. We | 5031 | /* We don't wan't to know the innermost window. We |
| 5016 | want the edit window. For non-Gtk+ the innermost | 5032 | want the edit window. For non-Gtk+ the innermost |
| 5017 | window is the edit window. For Gtk+ it might not | 5033 | window is the edit window. For Gtk+ it might not |
| 5018 | be. It might be the tool bar for example. */ | 5034 | be. It might be the tool bar for example. */ |
| 5019 | if (x_window_to_frame (dpyinfo, win)) | 5035 | if (x_window_to_frame (dpyinfo, win)) |
| 5020 | break; | 5036 | /* But don't hurry. We might find a child frame |
| 5037 | beneath. */ | ||
| 5038 | first_win = win; | ||
| 5021 | #endif | 5039 | #endif |
| 5022 | win = child; | 5040 | win = child; |
| 5023 | parent_x = win_x; | 5041 | parent_x = win_x; |
| 5024 | parent_y = win_y; | 5042 | parent_y = win_y; |
| 5025 | } | 5043 | } |
| 5026 | 5044 | ||
| 5045 | #ifdef USE_GTK | ||
| 5046 | if (first_win) | ||
| 5047 | win = first_win; | ||
| 5048 | #endif | ||
| 5049 | |||
| 5027 | /* Now we know that: | 5050 | /* Now we know that: |
| 5028 | win is the innermost window containing the pointer | 5051 | win is the innermost window containing the pointer |
| 5029 | (XTC says it has no child containing the pointer), | 5052 | (XTC says it has no child containing the pointer), |
| @@ -6496,10 +6519,14 @@ x_scroll_bar_create (struct window *w, int top, int left, | |||
| 6496 | Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); | 6519 | Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); |
| 6497 | XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); | 6520 | XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); |
| 6498 | XtMapWidget (scroll_bar); | 6521 | XtMapWidget (scroll_bar); |
| 6522 | /* Don't obscure any child frames. */ | ||
| 6523 | XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window); | ||
| 6499 | #endif /* not USE_GTK */ | 6524 | #endif /* not USE_GTK */ |
| 6500 | } | 6525 | } |
| 6501 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | 6526 | #else /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6502 | XMapRaised (FRAME_X_DISPLAY (f), bar->x_window); | 6527 | XMapWindow (FRAME_X_DISPLAY (f), bar->x_window); |
| 6528 | /* Don't obscure any child frames. */ | ||
| 6529 | XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window); | ||
| 6503 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 6530 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6504 | 6531 | ||
| 6505 | unblock_input (); | 6532 | unblock_input (); |
| @@ -7067,10 +7094,10 @@ x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event) | |||
| 7067 | /* x, y, width, height */ | 7094 | /* x, y, width, height */ |
| 7068 | 0, 0, bar->width - 1, bar->height - 1); | 7095 | 0, 0, bar->width - 1, bar->height - 1); |
| 7069 | 7096 | ||
| 7070 | /* Restore the foreground color of the GC if we changed it above. */ | 7097 | /* Restore the foreground color of the GC if we changed it above. */ |
| 7071 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 7098 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| 7072 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 7099 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 7073 | FRAME_FOREGROUND_PIXEL (f)); | 7100 | FRAME_FOREGROUND_PIXEL (f)); |
| 7074 | 7101 | ||
| 7075 | unblock_input (); | 7102 | unblock_input (); |
| 7076 | 7103 | ||
| @@ -7839,8 +7866,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7839 | f = x_top_window_to_frame (dpyinfo, event->xreparent.window); | 7866 | f = x_top_window_to_frame (dpyinfo, event->xreparent.window); |
| 7840 | if (f) | 7867 | if (f) |
| 7841 | { | 7868 | { |
| 7842 | f->output_data.x->parent_desc = event->xreparent.parent; | 7869 | /* Maybe we shouldn't set this for child frames ?? */ |
| 7843 | x_real_positions (f, &f->left_pos, &f->top_pos); | 7870 | f->output_data.x->parent_desc = event->xreparent.parent; |
| 7871 | if (!FRAME_PARENT_FRAME (f)) | ||
| 7872 | x_real_positions (f, &f->left_pos, &f->top_pos); | ||
| 7873 | else | ||
| 7874 | { | ||
| 7875 | Window root; | ||
| 7876 | unsigned int dummy_uint; | ||
| 7877 | |||
| 7878 | block_input (); | ||
| 7879 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 7880 | &root, &f->left_pos, &f->top_pos, | ||
| 7881 | &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint); | ||
| 7882 | unblock_input (); | ||
| 7883 | } | ||
| 7844 | 7884 | ||
| 7845 | /* Perhaps reparented due to a WM restart. Reset this. */ | 7885 | /* Perhaps reparented due to a WM restart. Reset this. */ |
| 7846 | FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; | 7886 | FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; |
| @@ -8000,7 +8040,26 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8000 | /* Check if fullscreen was specified before we where mapped the | 8040 | /* Check if fullscreen was specified before we where mapped the |
| 8001 | first time, i.e. from the command line. */ | 8041 | first time, i.e. from the command line. */ |
| 8002 | if (!f->output_data.x->has_been_visible) | 8042 | if (!f->output_data.x->has_been_visible) |
| 8003 | x_check_fullscreen (f); | 8043 | { |
| 8044 | |||
| 8045 | x_check_fullscreen (f); | ||
| 8046 | #ifndef USE_GTK | ||
| 8047 | /* For systems that cannot synthesize `skip_taskbar' for | ||
| 8048 | unmapped windows do the following. */ | ||
| 8049 | if (FRAME_SKIP_TASKBAR (f)) | ||
| 8050 | x_set_skip_taskbar (f, Qt, Qnil); | ||
| 8051 | #endif /* Not USE_GTK */ | ||
| 8052 | } | ||
| 8053 | |||
| 8054 | if (!iconified) | ||
| 8055 | { | ||
| 8056 | /* The `z-group' is reset every time a frame becomes | ||
| 8057 | invisible. Handle this here. */ | ||
| 8058 | if (FRAME_Z_GROUP (f) == z_group_above) | ||
| 8059 | x_set_z_group (f, Qabove, Qnil); | ||
| 8060 | else if (FRAME_Z_GROUP (f) == z_group_below) | ||
| 8061 | x_set_z_group (f, Qbelow, Qnil); | ||
| 8062 | } | ||
| 8004 | 8063 | ||
| 8005 | SET_FRAME_VISIBLE (f, 1); | 8064 | SET_FRAME_VISIBLE (f, 1); |
| 8006 | SET_FRAME_ICONIFIED (f, false); | 8065 | SET_FRAME_ICONIFIED (f, false); |
| @@ -8444,34 +8503,46 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8444 | #endif | 8503 | #endif |
| 8445 | if (f) | 8504 | if (f) |
| 8446 | { | 8505 | { |
| 8447 | 8506 | /* Maybe generate a SELECT_WINDOW_EVENT for | |
| 8448 | /* Generate SELECT_WINDOW_EVENTs when needed. | 8507 | `mouse-autoselect-window' but don't let popup menus |
| 8449 | Don't let popup menus influence things (bug#1261). */ | 8508 | interfere with this (Bug#1261). */ |
| 8450 | if (!NILP (Vmouse_autoselect_window) && !popup_activated ()) | 8509 | if (!NILP (Vmouse_autoselect_window) |
| 8510 | && !popup_activated () | ||
| 8511 | /* Don't switch if we're currently in the minibuffer. | ||
| 8512 | This tries to work around problems where the | ||
| 8513 | minibuffer gets unselected unexpectedly, and where | ||
| 8514 | you then have to move your mouse all the way down to | ||
| 8515 | the minibuffer to select it. */ | ||
| 8516 | && !MINI_WINDOW_P (XWINDOW (selected_window)) | ||
| 8517 | /* With `focus-follows-mouse' non-nil create an event | ||
| 8518 | also when the target window is on another frame. */ | ||
| 8519 | && (f == XFRAME (selected_frame) | ||
| 8520 | || !NILP (focus_follows_mouse))) | ||
| 8451 | { | 8521 | { |
| 8452 | static Lisp_Object last_mouse_window; | 8522 | static Lisp_Object last_mouse_window; |
| 8453 | Lisp_Object window = window_from_coordinates | 8523 | Lisp_Object window = window_from_coordinates |
| 8454 | (f, event->xmotion.x, event->xmotion.y, 0, false); | 8524 | (f, event->xmotion.x, event->xmotion.y, 0, false); |
| 8455 | 8525 | ||
| 8456 | /* Window will be selected only when it is not selected now and | 8526 | /* A window will be autoselected only when it is not |
| 8457 | last mouse movement event was not in it. Minibuffer window | 8527 | selected now and the last mouse movement event was |
| 8458 | will be selected only when it is active. */ | 8528 | not in it. The remainder of the code is a bit vague |
| 8529 | wrt what a "window" is. For immediate autoselection, | ||
| 8530 | the window is usually the entire window but for GTK | ||
| 8531 | where the scroll bars don't count. For delayed | ||
| 8532 | autoselection the window is usually the window's text | ||
| 8533 | area including the margins. */ | ||
| 8459 | if (WINDOWP (window) | 8534 | if (WINDOWP (window) |
| 8460 | && !EQ (window, last_mouse_window) | 8535 | && !EQ (window, last_mouse_window) |
| 8461 | && !EQ (window, selected_window) | 8536 | && !EQ (window, selected_window)) |
| 8462 | /* For click-to-focus window managers | ||
| 8463 | create event iff we don't leave the | ||
| 8464 | selected frame. */ | ||
| 8465 | && (focus_follows_mouse | ||
| 8466 | || (EQ (XWINDOW (window)->frame, | ||
| 8467 | XWINDOW (selected_window)->frame)))) | ||
| 8468 | { | 8537 | { |
| 8469 | inev.ie.kind = SELECT_WINDOW_EVENT; | 8538 | inev.ie.kind = SELECT_WINDOW_EVENT; |
| 8470 | inev.ie.frame_or_window = window; | 8539 | inev.ie.frame_or_window = window; |
| 8471 | } | 8540 | } |
| 8541 | |||
| 8472 | /* Remember the last window where we saw the mouse. */ | 8542 | /* Remember the last window where we saw the mouse. */ |
| 8473 | last_mouse_window = window; | 8543 | last_mouse_window = window; |
| 8474 | } | 8544 | } |
| 8545 | |||
| 8475 | if (!note_mouse_movement (f, &event->xmotion)) | 8546 | if (!note_mouse_movement (f, &event->xmotion)) |
| 8476 | help_echo_string = previous_help_echo_string; | 8547 | help_echo_string = previous_help_echo_string; |
| 8477 | } | 8548 | } |
| @@ -8621,7 +8692,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8621 | 8692 | ||
| 8622 | XSETFRAME (frame, f); | 8693 | XSETFRAME (frame, f); |
| 8623 | 8694 | ||
| 8624 | x_real_positions (f, &f->left_pos, &f->top_pos); | 8695 | if (!FRAME_PARENT_FRAME (f)) |
| 8696 | x_real_positions (f, &f->left_pos, &f->top_pos); | ||
| 8697 | else | ||
| 8698 | { | ||
| 8699 | Window root; | ||
| 8700 | unsigned int dummy_uint; | ||
| 8701 | |||
| 8702 | block_input (); | ||
| 8703 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 8704 | &root, &f->left_pos, &f->top_pos, | ||
| 8705 | &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint); | ||
| 8706 | unblock_input (); | ||
| 8707 | } | ||
| 8625 | 8708 | ||
| 8626 | if (old_left != f->left_pos || old_top != f->top_pos) | 8709 | if (old_left != f->left_pos || old_top != f->top_pos) |
| 8627 | { | 8710 | { |
| @@ -8650,8 +8733,35 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8650 | dpyinfo->last_mouse_glyph_frame = NULL; | 8733 | dpyinfo->last_mouse_glyph_frame = NULL; |
| 8651 | x_display_set_last_user_time (dpyinfo, event->xbutton.time); | 8734 | x_display_set_last_user_time (dpyinfo, event->xbutton.time); |
| 8652 | 8735 | ||
| 8653 | f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame | 8736 | if (x_mouse_grabbed (dpyinfo)) |
| 8654 | : x_window_to_frame (dpyinfo, event->xbutton.window)); | 8737 | f = dpyinfo->last_mouse_frame; |
| 8738 | else | ||
| 8739 | { | ||
| 8740 | f = x_window_to_frame (dpyinfo, event->xbutton.window); | ||
| 8741 | |||
| 8742 | if (f && event->xbutton.type == ButtonPress | ||
| 8743 | && !popup_activated () | ||
| 8744 | && !x_window_to_scroll_bar (event->xbutton.display, | ||
| 8745 | event->xbutton.window, 2) | ||
| 8746 | && !FRAME_NO_ACCEPT_FOCUS (f)) | ||
| 8747 | { | ||
| 8748 | /* When clicking into a child frame or when clicking | ||
| 8749 | into a parent frame with the child frame selected and | ||
| 8750 | `no-accept-focus' is not set, select the clicked | ||
| 8751 | frame. */ | ||
| 8752 | struct frame *hf = dpyinfo->x_highlight_frame; | ||
| 8753 | |||
| 8754 | if (FRAME_PARENT_FRAME (f) || frame_ancestor_p (f, hf)) | ||
| 8755 | { | ||
| 8756 | block_input (); | ||
| 8757 | XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 8758 | RevertToParent, CurrentTime); | ||
| 8759 | if (FRAME_PARENT_FRAME (f)) | ||
| 8760 | XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | ||
| 8761 | unblock_input (); | ||
| 8762 | } | ||
| 8763 | } | ||
| 8764 | } | ||
| 8655 | 8765 | ||
| 8656 | #ifdef USE_GTK | 8766 | #ifdef USE_GTK |
| 8657 | if (f && xg_event_is_for_scrollbar (f, event)) | 8767 | if (f && xg_event_is_for_scrollbar (f, event)) |
| @@ -10007,6 +10117,7 @@ static void | |||
| 10007 | x_calc_absolute_position (struct frame *f) | 10117 | x_calc_absolute_position (struct frame *f) |
| 10008 | { | 10118 | { |
| 10009 | int flags = f->size_hint_flags; | 10119 | int flags = f->size_hint_flags; |
| 10120 | struct frame *p = FRAME_PARENT_FRAME (f); | ||
| 10010 | 10121 | ||
| 10011 | /* We have nothing to do if the current position | 10122 | /* We have nothing to do if the current position |
| 10012 | is already for the top-left corner. */ | 10123 | is already for the top-left corner. */ |
| @@ -10015,32 +10126,72 @@ x_calc_absolute_position (struct frame *f) | |||
| 10015 | 10126 | ||
| 10016 | /* Treat negative positions as relative to the leftmost bottommost | 10127 | /* Treat negative positions as relative to the leftmost bottommost |
| 10017 | position that fits on the screen. */ | 10128 | position that fits on the screen. */ |
| 10018 | if (flags & XNegative) | 10129 | if ((flags & XNegative) && (f->left_pos <= 0)) |
| 10019 | f->left_pos = x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | 10130 | { |
| 10020 | - FRAME_PIXEL_WIDTH (f) + f->left_pos; | 10131 | int width = FRAME_PIXEL_WIDTH (f); |
| 10021 | 10132 | ||
| 10022 | { | 10133 | /* A frame that has been visible at least once should have outer |
| 10023 | int height = FRAME_PIXEL_HEIGHT (f); | 10134 | edges. */ |
| 10135 | if (f->output_data.x->has_been_visible && !p) | ||
| 10136 | { | ||
| 10137 | Lisp_Object frame; | ||
| 10138 | Lisp_Object edges = Qnil; | ||
| 10139 | |||
| 10140 | XSETFRAME (frame, f); | ||
| 10141 | edges = Fx_frame_edges (frame, Qouter_edges); | ||
| 10142 | if (!NILP (edges)) | ||
| 10143 | width = (XINT (Fnth (make_number (2), edges)) | ||
| 10144 | - XINT (Fnth (make_number (0), edges))); | ||
| 10145 | } | ||
| 10146 | |||
| 10147 | if (p) | ||
| 10148 | f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width | ||
| 10149 | + f->left_pos); | ||
| 10150 | else | ||
| 10151 | f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | ||
| 10152 | - width + f->left_pos); | ||
| 10153 | |||
| 10154 | } | ||
| 10155 | |||
| 10156 | if ((flags & YNegative) && (f->top_pos <= 0)) | ||
| 10157 | { | ||
| 10158 | int height = FRAME_PIXEL_HEIGHT (f); | ||
| 10024 | 10159 | ||
| 10025 | #if defined USE_X_TOOLKIT && defined USE_MOTIF | 10160 | #if defined USE_X_TOOLKIT && defined USE_MOTIF |
| 10026 | /* Something is fishy here. When using Motif, starting Emacs with | 10161 | /* Something is fishy here. When using Motif, starting Emacs with |
| 10027 | `-g -0-0', the frame appears too low by a few pixels. | 10162 | `-g -0-0', the frame appears too low by a few pixels. |
| 10028 | 10163 | ||
| 10029 | This seems to be so because initially, while Emacs is starting, | 10164 | This seems to be so because initially, while Emacs is starting, |
| 10030 | the column widget's height and the frame's pixel height are | 10165 | the column widget's height and the frame's pixel height are |
| 10031 | different. The column widget's height is the right one. In | 10166 | different. The column widget's height is the right one. In |
| 10032 | later invocations, when Emacs is up, the frame's pixel height | 10167 | later invocations, when Emacs is up, the frame's pixel height |
| 10033 | is right, though. | 10168 | is right, though. |
| 10034 | 10169 | ||
| 10035 | It's not obvious where the initial small difference comes from. | 10170 | It's not obvious where the initial small difference comes from. |
| 10036 | 2000-12-01, gerd. */ | 10171 | 2000-12-01, gerd. */ |
| 10037 | 10172 | ||
| 10038 | XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL); | 10173 | XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL); |
| 10039 | #endif | 10174 | #endif |
| 10040 | 10175 | ||
| 10041 | if (flags & YNegative) | 10176 | if (f->output_data.x->has_been_visible && !p) |
| 10042 | f->top_pos = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | 10177 | { |
| 10043 | - height + f->top_pos; | 10178 | Lisp_Object frame; |
| 10179 | Lisp_Object edges = Qnil; | ||
| 10180 | |||
| 10181 | XSETFRAME (frame, f); | ||
| 10182 | if (NILP (edges)) | ||
| 10183 | edges = Fx_frame_edges (frame, Qouter_edges); | ||
| 10184 | if (!NILP (edges)) | ||
| 10185 | height = (XINT (Fnth (make_number (3), edges)) | ||
| 10186 | - XINT (Fnth (make_number (1), edges))); | ||
| 10187 | } | ||
| 10188 | |||
| 10189 | if (p) | ||
| 10190 | f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width | ||
| 10191 | + f->top_pos); | ||
| 10192 | else | ||
| 10193 | f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | ||
| 10194 | - height + f->top_pos); | ||
| 10044 | } | 10195 | } |
| 10045 | 10196 | ||
| 10046 | /* The left_pos and top_pos | 10197 | /* The left_pos and top_pos |
| @@ -10125,6 +10276,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_ | |||
| 10125 | need to compute the top/left offset adjustment for this frame. */ | 10276 | need to compute the top/left offset adjustment for this frame. */ |
| 10126 | 10277 | ||
| 10127 | if (change_gravity != 0 | 10278 | if (change_gravity != 0 |
| 10279 | && !FRAME_PARENT_FRAME (f) | ||
| 10128 | && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN | 10280 | && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN |
| 10129 | || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A | 10281 | || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A |
| 10130 | && (FRAME_X_OUTPUT (f)->move_offset_left == 0 | 10282 | && (FRAME_X_OUTPUT (f)->move_offset_left == 0 |
| @@ -10255,6 +10407,92 @@ x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | |||
| 10255 | dpyinfo->Xatom_net_wm_state_sticky, None); | 10407 | dpyinfo->Xatom_net_wm_state_sticky, None); |
| 10256 | } | 10408 | } |
| 10257 | 10409 | ||
| 10410 | /** | ||
| 10411 | * x_set_skip_taskbar: | ||
| 10412 | * | ||
| 10413 | * Set frame F's `skip-taskbar' parameter. If non-nil, this should | ||
| 10414 | * remove F's icon from the taskbar associated with the display of F's | ||
| 10415 | * window-system window and inhibit switching to F's window via | ||
| 10416 | * <Alt>-<TAB>. If nil, lift these restrictions. | ||
| 10417 | * | ||
| 10418 | * Some window managers may not honor this parameter. | ||
| 10419 | */ | ||
| 10420 | void | ||
| 10421 | x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 10422 | { | ||
| 10423 | if (!EQ (new_value, old_value)) | ||
| 10424 | { | ||
| 10425 | #ifdef USE_GTK | ||
| 10426 | xg_set_skip_taskbar (f, new_value); | ||
| 10427 | #else | ||
| 10428 | Lisp_Object frame; | ||
| 10429 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 10430 | |||
| 10431 | XSETFRAME (frame, f); | ||
| 10432 | set_wm_state (frame, !NILP (new_value), | ||
| 10433 | dpyinfo->Xatom_net_wm_state_skip_taskbar, None); | ||
| 10434 | #endif /* USE_GTK */ | ||
| 10435 | FRAME_SKIP_TASKBAR (f) = !NILP (new_value); | ||
| 10436 | } | ||
| 10437 | } | ||
| 10438 | |||
| 10439 | /** | ||
| 10440 | * x_set_z_group: | ||
| 10441 | * | ||
| 10442 | * Set frame F's `z-group' parameter. If `above', F's window-system | ||
| 10443 | * window is displayed above all windows that do not have the `above' | ||
| 10444 | * property set. If nil, F's window is shown below all windows that | ||
| 10445 | * have the `above' property set and above all windows that have the | ||
| 10446 | * `below' property set. If `below', F's window is displayed below all | ||
| 10447 | * windows that do not have the `below' property set. | ||
| 10448 | * | ||
| 10449 | * Some window managers may not honor this parameter. | ||
| 10450 | */ | ||
| 10451 | void | ||
| 10452 | x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 10453 | { | ||
| 10454 | /* We don't care about old_value. The window manager might have | ||
| 10455 | reset the value without telling us. */ | ||
| 10456 | Lisp_Object frame; | ||
| 10457 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 10458 | |||
| 10459 | XSETFRAME (frame, f); | ||
| 10460 | |||
| 10461 | if (NILP (new_value)) | ||
| 10462 | { | ||
| 10463 | set_wm_state (frame, false, | ||
| 10464 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10465 | set_wm_state (frame, false, | ||
| 10466 | dpyinfo->Xatom_net_wm_state_below, None); | ||
| 10467 | FRAME_Z_GROUP (f) = z_group_none; | ||
| 10468 | } | ||
| 10469 | else if (EQ (new_value, Qabove)) | ||
| 10470 | { | ||
| 10471 | set_wm_state (frame, true, | ||
| 10472 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10473 | set_wm_state (frame, false, | ||
| 10474 | dpyinfo->Xatom_net_wm_state_below, None); | ||
| 10475 | FRAME_Z_GROUP (f) = z_group_above; | ||
| 10476 | } | ||
| 10477 | else if (EQ (new_value, Qbelow)) | ||
| 10478 | { | ||
| 10479 | set_wm_state (frame, false, | ||
| 10480 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10481 | set_wm_state (frame, true, | ||
| 10482 | dpyinfo->Xatom_net_wm_state_below, None); | ||
| 10483 | FRAME_Z_GROUP (f) = z_group_below; | ||
| 10484 | } | ||
| 10485 | else if (EQ (new_value, Qabove_suspended)) | ||
| 10486 | { | ||
| 10487 | set_wm_state (frame, false, | ||
| 10488 | dpyinfo->Xatom_net_wm_state_above, None); | ||
| 10489 | FRAME_Z_GROUP (f) = z_group_above_suspended; | ||
| 10490 | } | ||
| 10491 | else | ||
| 10492 | error ("Invalid z-group specification"); | ||
| 10493 | } | ||
| 10494 | |||
| 10495 | |||
| 10258 | /* Return the current _NET_WM_STATE. | 10496 | /* Return the current _NET_WM_STATE. |
| 10259 | SIZE_STATE is set to one of the FULLSCREEN_* values. | 10497 | SIZE_STATE is set to one of the FULLSCREEN_* values. |
| 10260 | Set *STICKY to the sticky state. | 10498 | Set *STICKY to the sticky state. |
| @@ -10758,7 +10996,8 @@ x_set_window_size_1 (struct frame *f, bool change_gravity, | |||
| 10758 | int old_height = FRAME_PIXEL_HEIGHT (f); | 10996 | int old_height = FRAME_PIXEL_HEIGHT (f); |
| 10759 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); | 10997 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); |
| 10760 | 10998 | ||
| 10761 | if (change_gravity) f->win_gravity = NorthWestGravity; | 10999 | if (change_gravity) |
| 11000 | f->win_gravity = NorthWestGravity; | ||
| 10762 | x_wm_set_size_hint (f, 0, false); | 11001 | x_wm_set_size_hint (f, 0, false); |
| 10763 | 11002 | ||
| 10764 | /* When the frame is fullheight and we only want to change the width | 11003 | /* When the frame is fullheight and we only want to change the width |
| @@ -11047,6 +11286,26 @@ xembed_send_message (struct frame *f, Time t, enum xembed_message msg, | |||
| 11047 | void | 11286 | void |
| 11048 | x_make_frame_visible (struct frame *f) | 11287 | x_make_frame_visible (struct frame *f) |
| 11049 | { | 11288 | { |
| 11289 | if (FRAME_PARENT_FRAME (f)) | ||
| 11290 | { | ||
| 11291 | if (!FRAME_VISIBLE_P (f)) | ||
| 11292 | { | ||
| 11293 | block_input (); | ||
| 11294 | #ifdef USE_GTK | ||
| 11295 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 11296 | XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 11297 | f->left_pos, f->top_pos); | ||
| 11298 | #else | ||
| 11299 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | ||
| 11300 | #endif | ||
| 11301 | unblock_input (); | ||
| 11302 | |||
| 11303 | SET_FRAME_VISIBLE (f, true); | ||
| 11304 | SET_FRAME_ICONIFIED (f, false); | ||
| 11305 | } | ||
| 11306 | return; | ||
| 11307 | } | ||
| 11308 | |||
| 11050 | block_input (); | 11309 | block_input (); |
| 11051 | 11310 | ||
| 11052 | x_set_bitmap_icon (f); | 11311 | x_set_bitmap_icon (f); |
| @@ -11115,9 +11374,10 @@ x_make_frame_visible (struct frame *f) | |||
| 11115 | because the window manager may choose the position | 11374 | because the window manager may choose the position |
| 11116 | and we don't want to override it. */ | 11375 | and we don't want to override it. */ |
| 11117 | 11376 | ||
| 11118 | if (! FRAME_VISIBLE_P (f) | 11377 | if (!FRAME_VISIBLE_P (f) |
| 11119 | && ! FRAME_ICONIFIED_P (f) | 11378 | && !FRAME_ICONIFIED_P (f) |
| 11120 | && ! FRAME_X_EMBEDDED_P (f) | 11379 | && !FRAME_X_EMBEDDED_P (f) |
| 11380 | && !FRAME_PARENT_FRAME (f) | ||
| 11121 | && f->win_gravity == NorthWestGravity | 11381 | && f->win_gravity == NorthWestGravity |
| 11122 | && previously_visible) | 11382 | && previously_visible) |
| 11123 | { | 11383 | { |
| @@ -11180,15 +11440,15 @@ x_make_frame_invisible (struct frame *f) | |||
| 11180 | xembed_set_info (f, 0); | 11440 | xembed_set_info (f, 0); |
| 11181 | else | 11441 | else |
| 11182 | #endif | 11442 | #endif |
| 11183 | { | ||
| 11184 | 11443 | ||
| 11185 | if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window, | 11444 | if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window, |
| 11186 | DefaultScreen (FRAME_X_DISPLAY (f)))) | 11445 | DefaultScreen (FRAME_X_DISPLAY (f)))) |
| 11187 | { | 11446 | { |
| 11188 | unblock_input (); | 11447 | unblock_input (); |
| 11189 | error ("Can't notify window manager of window withdrawal"); | 11448 | error ("Can't notify window manager of window withdrawal"); |
| 11190 | } | 11449 | } |
| 11191 | } | 11450 | |
| 11451 | x_sync (f); | ||
| 11192 | 11452 | ||
| 11193 | /* We can't distinguish this from iconification | 11453 | /* We can't distinguish this from iconification |
| 11194 | just by the event that we get from the server. | 11454 | just by the event that we get from the server. |
| @@ -11198,8 +11458,6 @@ x_make_frame_invisible (struct frame *f) | |||
| 11198 | SET_FRAME_VISIBLE (f, 0); | 11458 | SET_FRAME_VISIBLE (f, 0); |
| 11199 | SET_FRAME_ICONIFIED (f, false); | 11459 | SET_FRAME_ICONIFIED (f, false); |
| 11200 | 11460 | ||
| 11201 | x_sync (f); | ||
| 11202 | |||
| 11203 | unblock_input (); | 11461 | unblock_input (); |
| 11204 | } | 11462 | } |
| 11205 | 11463 | ||
| @@ -12355,6 +12613,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 12355 | ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) | 12613 | ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) |
| 12356 | ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) | 12614 | ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) |
| 12357 | ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr) | 12615 | ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr) |
| 12616 | ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar) | ||
| 12617 | ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above) | ||
| 12618 | ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below) | ||
| 12358 | }; | 12619 | }; |
| 12359 | 12620 | ||
| 12360 | int i; | 12621 | int i; |
diff --git a/src/xterm.h b/src/xterm.h index 32c879bcdca..a75257006fd 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -447,9 +447,9 @@ struct x_display_info | |||
| 447 | /* Atoms dealing with EWMH (i.e. _NET_...) */ | 447 | /* Atoms dealing with EWMH (i.e. _NET_...) */ |
| 448 | Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen, | 448 | Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen, |
| 449 | Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert, | 449 | Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert, |
| 450 | Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden, | 450 | Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, Xatom_net_wm_state_below, |
| 451 | Xatom_net_frame_extents, | 451 | Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar, |
| 452 | Xatom_net_current_desktop, Xatom_net_workarea; | 452 | Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea; |
| 453 | 453 | ||
| 454 | /* XSettings atoms and windows. */ | 454 | /* XSettings atoms and windows. */ |
| 455 | Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; | 455 | Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; |
| @@ -1168,6 +1168,8 @@ x_mutable_colormap (Visual *visual) | |||
| 1168 | } | 1168 | } |
| 1169 | 1169 | ||
| 1170 | extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); | 1170 | extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); |
| 1171 | extern void x_set_skip_taskbar (struct frame *, Lisp_Object, Lisp_Object); | ||
| 1172 | extern void x_set_z_group (struct frame *, Lisp_Object, Lisp_Object); | ||
| 1171 | extern bool x_wm_supports (struct frame *, Atom); | 1173 | extern bool x_wm_supports (struct frame *, Atom); |
| 1172 | extern void x_wait_for_event (struct frame *, int); | 1174 | extern void x_wait_for_event (struct frame *, int); |
| 1173 | extern void x_clear_under_internal_border (struct frame *f); | 1175 | extern void x_clear_under_internal_border (struct frame *f); |