diff options
| author | Martin Rudalics | 2011-10-21 11:15:32 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2011-10-21 11:15:32 +0200 |
| commit | e07b9a6d33fedd63f424c0e7627cbf680cbf3b6f (patch) | |
| tree | 307557ece9c75b55af524cdf42d9f92bcba8dfcc | |
| parent | 7e1361d995cba156dd4b14ac4ba236bf90908d46 (diff) | |
| download | emacs-e07b9a6d33fedd63f424c0e7627cbf680cbf3b6f.tar.gz emacs-e07b9a6d33fedd63f424c0e7627cbf680cbf3b6f.zip | |
Fix and improve mouse-dragging of horizontal/vertical lines.
* mouse.el (mouse-drag-window-above)
(mouse-drag-move-window-bottom, mouse-drag-move-window-top)
(mouse-drag-mode-line-1, mouse-drag-header-line)
(mouse-drag-vertical-line-rightward-window): Remove.
(mouse-drag-line): New function.
(mouse-drag-mode-line, mouse-drag-header-line)
(mouse-drag-vertical-line): Call mouse-drag-line.
* window.el (window-at-side-p, windows-at-side): New functions.
| -rw-r--r-- | lisp/ChangeLog | 11 | ||||
| -rw-r--r-- | lisp/mouse.el | 418 | ||||
| -rw-r--r-- | lisp/window.el | 29 |
3 files changed, 181 insertions, 277 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7f3e324a6e8..150ffd629e5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2011-10-21 Martin Rudalics <rudalics@gmx.at> | ||
| 2 | |||
| 3 | * mouse.el (mouse-drag-window-above) | ||
| 4 | (mouse-drag-move-window-bottom, mouse-drag-move-window-top) | ||
| 5 | (mouse-drag-mode-line-1, mouse-drag-header-line) | ||
| 6 | (mouse-drag-vertical-line-rightward-window): Remove. | ||
| 7 | (mouse-drag-line): New function. | ||
| 8 | (mouse-drag-mode-line, mouse-drag-header-line) | ||
| 9 | (mouse-drag-vertical-line): Call mouse-drag-line. | ||
| 10 | * window.el (window-at-side-p, windows-at-side): New functions. | ||
| 11 | |||
| 1 | 2011-10-21 Ulrich Mueller <ulm@gentoo.org> | 12 | 2011-10-21 Ulrich Mueller <ulm@gentoo.org> |
| 2 | 13 | ||
| 3 | * tar-mode.el (tar-grind-file-mode): | 14 | * tar-mode.el (tar-grind-file-mode): |
diff --git a/lisp/mouse.el b/lisp/mouse.el index ff175288445..ffa3db738ac 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el | |||
| @@ -372,300 +372,164 @@ This command must be bound to a mouse click." | |||
| 372 | (split-window-horizontally | 372 | (split-window-horizontally |
| 373 | (min (max new-width first-col) last-col)))))) | 373 | (min (max new-width first-col) last-col)))))) |
| 374 | 374 | ||
| 375 | (defun mouse-drag-window-above (window) | 375 | ;; `mouse-drag-line' is now the common routine for handling all line |
| 376 | "Return the (or a) window directly above WINDOW. | 376 | ;; dragging events combining the earlier `mouse-drag-mode-line-1' and |
| 377 | That means one whose bottom edge is at the same height as WINDOW's top edge." | 377 | ;; `mouse-drag-vertical-line'. It should improve the behavior of line |
| 378 | (let ((start-top (nth 1 (window-edges window))) | 378 | ;; dragging wrt Emacs 23 as follows: |
| 379 | (start-left (nth 0 (window-edges window))) | 379 | |
| 380 | (start-right (nth 2 (window-edges window))) | 380 | ;; (1) Gratuitous error messages and restrictions have been (hopefully) |
| 381 | (start-window window) | 381 | ;; removed. (The help-echo that dragging the mode-line can resize a |
| 382 | above-window) | 382 | ;; one-window-frame's window will still show through via bindings.el.) |
| 383 | (setq window (previous-window window 0)) | 383 | |
| 384 | (while (and (not above-window) (not (eq window start-window))) | 384 | ;; (2) No gratuitous selection of other windows should happen. (This |
| 385 | (let ((left (nth 0 (window-edges window))) | 385 | ;; has not been completely fixed for mouse-autoselected windows yet.) |
| 386 | (right (nth 2 (window-edges window)))) | 386 | |
| 387 | (when (and (= (+ (window-height window) (nth 1 (window-edges window))) | 387 | ;; (3) Mouse clicks below a scroll-bar should pass through via unread |
| 388 | start-top) | 388 | ;; command events. |
| 389 | (or (and (<= left start-left) (<= start-right right)) | 389 | |
| 390 | (and (<= start-left left) (<= left start-right)) | 390 | ;; Note that `window-in-direction' replaces `mouse-drag-window-above' |
| 391 | (and (<= start-left right) (<= right start-right)))) | 391 | ;; and `mouse-drag-vertical-line-rightward-window' with Emacs 24.1. |
| 392 | (setq above-window window))) | 392 | (defun mouse-drag-line (start-event line) |
| 393 | (setq window (previous-window window))) | 393 | "Drag some line with the mouse. |
| 394 | above-window)) | 394 | START-EVENT is the starting mouse-event of the drag action. LINE |
| 395 | 395 | must be one of the symbols header, mode, or vertical." | |
| 396 | (defun mouse-drag-move-window-bottom (window growth) | ||
| 397 | "Move the bottom of WINDOW up or down by GROWTH lines. | ||
| 398 | Move it down if GROWTH is positive, or up if GROWTH is negative. | ||
| 399 | If this would make WINDOW too short, | ||
| 400 | shrink the window or windows above it to make room." | ||
| 401 | (condition-case nil | ||
| 402 | (adjust-window-trailing-edge window growth nil) | ||
| 403 | (error nil))) | ||
| 404 | |||
| 405 | (defsubst mouse-drag-move-window-top (window growth) | ||
| 406 | "Move the top of WINDOW up or down by GROWTH lines. | ||
| 407 | Move it down if GROWTH is positive, or up if GROWTH is negative. | ||
| 408 | If this would make WINDOW too short, shrink the window or windows | ||
| 409 | above it to make room." | ||
| 410 | ;; Moving the top of WINDOW is actually moving the bottom of the | ||
| 411 | ;; window above. | ||
| 412 | (let ((window-above (mouse-drag-window-above window))) | ||
| 413 | (and window-above | ||
| 414 | (mouse-drag-move-window-bottom window-above (- growth))))) | ||
| 415 | |||
| 416 | (defun mouse-drag-mode-line-1 (start-event mode-line-p) | ||
| 417 | "Change the height of a window by dragging on the mode or header line. | ||
| 418 | START-EVENT is the starting mouse-event of the drag action. | ||
| 419 | MODE-LINE-P non-nil means dragging a mode line; nil means a header line." | ||
| 420 | ;; Give temporary modes such as isearch a chance to turn off. | 396 | ;; Give temporary modes such as isearch a chance to turn off. |
| 421 | (run-hooks 'mouse-leave-buffer-hook) | 397 | (run-hooks 'mouse-leave-buffer-hook) |
| 422 | (let* ((done nil) | 398 | (let* ((echo-keystrokes 0) |
| 423 | (echo-keystrokes 0) | ||
| 424 | (start (event-start start-event)) | 399 | (start (event-start start-event)) |
| 425 | (start-event-window (posn-window start)) | 400 | (window (posn-window start)) |
| 426 | (start-event-frame (window-frame start-event-window)) | 401 | (frame (window-frame window)) |
| 427 | (start-nwindows (count-windows t)) | 402 | (minibuffer-window (minibuffer-window frame)) |
| 428 | (on-link (and mouse-1-click-follows-link | 403 | (on-link (and mouse-1-click-follows-link |
| 429 | (or mouse-1-click-in-non-selected-windows | 404 | (or mouse-1-click-in-non-selected-windows |
| 430 | (eq (posn-window start) (selected-window))) | 405 | (eq window (selected-window))) |
| 431 | (mouse-on-link-p start))) | 406 | (mouse-on-link-p start))) |
| 432 | (minibuffer (frame-parameter nil 'minibuffer)) | 407 | (enlarge-minibuffer |
| 433 | should-enlarge-minibuffer event mouse y top bot edges wconfig growth) | 408 | (and (eq line 'mode) |
| 409 | (eq (window-frame minibuffer-window) frame) | ||
| 410 | (not (one-window-p t frame)) | ||
| 411 | (= (nth 1 (window-edges minibuffer-window)) | ||
| 412 | (nth 3 (window-edges window))))) | ||
| 413 | (which-side | ||
| 414 | (and (eq line 'vertical) | ||
| 415 | (or (cdr (assq 'vertical-scroll-bars (frame-parameters frame))) | ||
| 416 | 'right))) | ||
| 417 | done event mouse growth dragged) | ||
| 418 | (cond | ||
| 419 | ((eq line 'header) | ||
| 420 | ;; Check whether header-line can be dragged at all. | ||
| 421 | (when (window-at-side-p window 'top) | ||
| 422 | (setq done t))) | ||
| 423 | ((eq line 'mode) | ||
| 424 | ;; Check whether mode-line can be dragged at all. | ||
| 425 | (when (window-at-side-p window 'bottom) | ||
| 426 | (setq done t))) | ||
| 427 | ((eq line 'vertical) | ||
| 428 | ;; Get the window to adjust for the vertical case. | ||
| 429 | (setq window | ||
| 430 | (if (eq which-side 'right) | ||
| 431 | ;; If the scroll bar is on the window's right or there's | ||
| 432 | ;; no scroll bar at all, adjust the window where the | ||
| 433 | ;; start-event occurred. | ||
| 434 | window | ||
| 435 | ;; If the scroll bar is on the start-event window's left, | ||
| 436 | ;; adjust the window on the left of it. | ||
| 437 | (window-in-direction 'left window))))) | ||
| 438 | |||
| 439 | ;; Start tracking. | ||
| 434 | (track-mouse | 440 | (track-mouse |
| 435 | (progn | 441 | ;; Loop reading events and sampling the position of the mouse. |
| 436 | ;; if this is the bottommost ordinary window, then to | 442 | (while (not done) |
| 437 | ;; move its modeline the minibuffer must be enlarged. | 443 | (setq event (read-event)) |
| 438 | (setq should-enlarge-minibuffer | 444 | (setq mouse (mouse-position)) |
| 439 | (and minibuffer | 445 | ;; Do nothing if |
| 440 | mode-line-p | 446 | ;; - there is a switch-frame event. |
| 441 | (not (one-window-p t)) | 447 | ;; - the mouse isn't in the frame that we started in |
| 442 | (= (nth 1 (window-edges minibuffer)) | 448 | ;; - the mouse isn't in any Emacs frame |
| 443 | (nth 3 (window-edges start-event-window))))) | 449 | ;; Drag if |
| 444 | 450 | ;; - there is a mouse-movement event | |
| 445 | ;; loop reading events and sampling the position of | 451 | ;; - there is a scroll-bar-movement event (??) |
| 446 | ;; the mouse. | 452 | ;; (same as mouse movement for our purposes) |
| 447 | (while (not done) | 453 | ;; Quit if |
| 448 | (setq event (read-event) | 454 | ;; - there is a keyboard event or some other unknown event. |
| 449 | mouse (mouse-position)) | 455 | (cond |
| 450 | 456 | ((not (consp event)) | |
| 451 | ;; do nothing if | 457 | (setq done t)) |
| 452 | ;; - there is a switch-frame event. | 458 | ((memq (car event) '(switch-frame select-window)) |
| 453 | ;; - the mouse isn't in the frame that we started in | 459 | nil) |
| 454 | ;; - the mouse isn't in any Emacs frame | 460 | ((not (memq (car event) '(mouse-movement scroll-bar-movement))) |
| 455 | ;; drag if | 461 | (when (consp event) |
| 456 | ;; - there is a mouse-movement event | 462 | ;; Do not unread a drag-mouse-1 event to avoid selecting |
| 457 | ;; - there is a scroll-bar-movement event | 463 | ;; some other window. For vertical line dragging do not |
| 458 | ;; (same as mouse movement for our purposes) | 464 | ;; unread mouse-1 events either (but only if we dragged at |
| 459 | ;; quit if | 465 | ;; least once to allow mouse-1 clicks get through. |
| 460 | ;; - there is a keyboard event or some other unknown event. | 466 | (unless (and dragged |
| 461 | (cond ((not (consp event)) | 467 | (if (eq line 'vertical) |
| 462 | (setq done t)) | 468 | (memq (car event) '(drag-mouse-1 mouse-1)) |
| 463 | 469 | (eq (car event) 'drag-mouse-1))) | |
| 464 | ((memq (car event) '(switch-frame select-window)) | 470 | (push event unread-command-events))) |
| 465 | nil) | 471 | (setq done t)) |
| 466 | 472 | ((or (not (eq (car mouse) frame)) (null (car (cdr mouse)))) | |
| 467 | ((not (memq (car event) '(mouse-movement scroll-bar-movement))) | 473 | nil) |
| 468 | (when (consp event) | 474 | ((eq line 'vertical) |
| 469 | ;; Do not unread a drag-mouse-1 event since it will cause the | 475 | ;; Drag vertical divider (the calculations below are those |
| 470 | ;; selection of the window above when dragging the modeline | 476 | ;; from Emacs 23). |
| 471 | ;; above the selected window. | 477 | (setq growth |
| 472 | (unless (eq (car event) 'drag-mouse-1) | 478 | (- (- (cadr mouse) |
| 473 | (push event unread-command-events))) | 479 | (if (eq which-side 'right) 0 2)) |
| 474 | (setq done t)) | 480 | (nth 2 (window-edges window)) |
| 475 | 481 | -1)) | |
| 476 | ((not (eq (car mouse) start-event-frame)) | 482 | (unless (zerop growth) |
| 477 | nil) | 483 | ;; Remember that we dragged. |
| 478 | 484 | (setq dragged t)) | |
| 479 | ((null (car (cdr mouse))) | 485 | (adjust-window-trailing-edge window growth t)) |
| 480 | nil) | 486 | (t |
| 481 | 487 | ;; Drag horizontal divider (the calculations below are those | |
| 482 | (t | 488 | ;; from Emacs 23). |
| 483 | (setq y (cdr (cdr mouse)) | 489 | (setq growth |
| 484 | edges (window-edges start-event-window) | 490 | (if (eq line 'mode) |
| 485 | top (nth 1 edges) | 491 | (- (cddr mouse) (nth 3 (window-edges window)) -1) |
| 486 | bot (nth 3 edges)) | 492 | ;; The window's top includes the header line! |
| 487 | 493 | (- (nth 3 (window-edges window)) (cddr mouse)))) | |
| 488 | ;; compute size change needed | 494 | |
| 489 | (cond (mode-line-p | 495 | (unless (zerop growth) |
| 490 | (setq growth (- y bot -1))) | 496 | ;; Remember that we dragged. |
| 491 | (t ; header line | 497 | (setq dragged t)) |
| 492 | (when (< (- bot y) window-min-height) | 498 | |
| 493 | (setq y (- bot window-min-height))) | 499 | (cond |
| 494 | ;; The window's top includes the header line! | 500 | (enlarge-minibuffer |
| 495 | (setq growth (- top y)))) | 501 | (adjust-window-trailing-edge window growth)) |
| 496 | (setq wconfig (current-window-configuration)) | 502 | ((eq line 'mode) |
| 497 | 503 | (adjust-window-trailing-edge window growth)) | |
| 498 | ;; Check for an error case. | 504 | (t |
| 499 | (when (and (/= growth 0) | 505 | (adjust-window-trailing-edge window (- growth))))))) |
| 500 | (not minibuffer) | 506 | |
| 501 | (one-window-p t)) | 507 | ;; Presumably, if this was just a click, the last event should be |
| 502 | (error "Attempt to resize sole window")) | 508 | ;; `mouse-1', whereas if this did move the mouse, it should be a |
| 503 | 509 | ;; `drag-mouse-1'. `dragged' nil tells us that we never dragged | |
| 504 | ;; If we ever move, make sure we don't mistakenly treat | 510 | ;; and `on-link' tells us that there is a link to follow. |
| 505 | ;; some unexpected `mouse-1' final event as a sign that | 511 | (when (and on-link (not dragged) |
| 506 | ;; this whole drag was nothing more than a click. | 512 | (eq 'mouse-1 (car-safe (car unread-command-events)))) |
| 507 | (if (/= growth 0) (setq on-link nil)) | 513 | ;; If mouse-2 has never been done by the user, it doesn't |
| 508 | 514 | ;; have the necessary property to be interpreted correctly. | |
| 509 | ;; grow/shrink minibuffer? | 515 | (put 'mouse-2 'event-kind 'mouse-click) |
| 510 | (if should-enlarge-minibuffer | 516 | (setcar unread-command-events |
| 511 | (unless resize-mini-windows | 517 | (cons 'mouse-2 (cdar unread-command-events))))))) |
| 512 | (mouse-drag-move-window-bottom start-event-window growth)) | ||
| 513 | ;; no. grow/shrink the selected window | ||
| 514 | ;(message "growth = %d" growth) | ||
| 515 | (if mode-line-p | ||
| 516 | (mouse-drag-move-window-bottom start-event-window growth) | ||
| 517 | (mouse-drag-move-window-top start-event-window growth))) | ||
| 518 | |||
| 519 | ;; if this window's growth caused another | ||
| 520 | ;; window to be deleted because it was too | ||
| 521 | ;; short, rescind the change. | ||
| 522 | ;; | ||
| 523 | ;; if size change caused space to be stolen | ||
| 524 | ;; from a window above this one, rescind the | ||
| 525 | ;; change, but only if we didn't grow/shrink | ||
| 526 | ;; the minibuffer. minibuffer size changes | ||
| 527 | ;; can cause all windows to shrink... no way | ||
| 528 | ;; around it. | ||
| 529 | (when (or (/= start-nwindows (count-windows t)) | ||
| 530 | (and (not should-enlarge-minibuffer) | ||
| 531 | (> growth 0) | ||
| 532 | mode-line-p | ||
| 533 | (/= top | ||
| 534 | (nth 1 (window-edges | ||
| 535 | ;; Choose right window. | ||
| 536 | start-event-window))))) | ||
| 537 | (set-window-configuration wconfig))))) | ||
| 538 | |||
| 539 | ;; Presumably if this was just a click, the last event should | ||
| 540 | ;; be `mouse-1', whereas if this did move the mouse, it should be | ||
| 541 | ;; a `drag-mouse-1'. In any case `on-link' would have been nulled | ||
| 542 | ;; above if there had been any significant mouse movement. | ||
| 543 | (when (and on-link | ||
| 544 | (eq 'mouse-1 (car-safe (car unread-command-events)))) | ||
| 545 | ;; If mouse-2 has never been done by the user, it doesn't | ||
| 546 | ;; have the necessary property to be interpreted correctly. | ||
| 547 | (put 'mouse-2 'event-kind 'mouse-click) | ||
| 548 | (setcar unread-command-events | ||
| 549 | (cons 'mouse-2 (cdar unread-command-events)))))))) | ||
| 550 | 518 | ||
| 551 | (defun mouse-drag-mode-line (start-event) | 519 | (defun mouse-drag-mode-line (start-event) |
| 552 | "Change the height of a window by dragging on the mode line." | 520 | "Change the height of a window by dragging on the mode line." |
| 553 | (interactive "e") | 521 | (interactive "e") |
| 554 | (mouse-drag-mode-line-1 start-event t)) | 522 | (mouse-drag-line start-event 'mode)) |
| 555 | 523 | ||
| 556 | (defun mouse-drag-header-line (start-event) | 524 | (defun mouse-drag-header-line (start-event) |
| 557 | "Change the height of a window by dragging on the header line. | 525 | "Change the height of a window by dragging on the header line." |
| 558 | Windows whose header-lines are at the top of the frame cannot be | ||
| 559 | resized by dragging their header-line." | ||
| 560 | (interactive "e") | 526 | (interactive "e") |
| 561 | ;; Changing the window's size by dragging its header-line when the | 527 | (mouse-drag-line start-event 'header)) |
| 562 | ;; header-line is at the top of the frame is somewhat strange, | ||
| 563 | ;; because the header-line doesn't move, so don't do it. | ||
| 564 | (let* ((start (event-start start-event)) | ||
| 565 | (window (posn-window start)) | ||
| 566 | (frame (window-frame window)) | ||
| 567 | (first-window (frame-first-window frame))) | ||
| 568 | (unless (or (eq window first-window) | ||
| 569 | (= (nth 1 (window-edges window)) | ||
| 570 | (nth 1 (window-edges first-window)))) | ||
| 571 | (mouse-drag-mode-line-1 start-event nil)))) | ||
| 572 | |||
| 573 | |||
| 574 | (defun mouse-drag-vertical-line-rightward-window (window) | ||
| 575 | "Return a window that is immediately to the right of WINDOW, or nil." | ||
| 576 | (let ((bottom (nth 3 (window-inside-edges window))) | ||
| 577 | (left (nth 0 (window-inside-edges window))) | ||
| 578 | best best-right | ||
| 579 | (try (previous-window window))) | ||
| 580 | (while (not (eq try window)) | ||
| 581 | (let ((try-top (nth 1 (window-inside-edges try))) | ||
| 582 | (try-bottom (nth 3 (window-inside-edges try))) | ||
| 583 | (try-right (nth 2 (window-inside-edges try)))) | ||
| 584 | (if (and (< try-top bottom) | ||
| 585 | (>= try-bottom bottom) | ||
| 586 | (< try-right left) | ||
| 587 | (or (null best-right) (> try-right best-right))) | ||
| 588 | (setq best-right try-right best try))) | ||
| 589 | (setq try (previous-window try))) | ||
| 590 | best)) | ||
| 591 | 528 | ||
| 592 | (defun mouse-drag-vertical-line (start-event) | 529 | (defun mouse-drag-vertical-line (start-event) |
| 593 | "Change the width of a window by dragging on the vertical line." | 530 | "Change the width of a window by dragging on the vertical line." |
| 594 | (interactive "e") | 531 | (interactive "e") |
| 595 | ;; Give temporary modes such as isearch a chance to turn off. | 532 | (mouse-drag-line start-event 'vertical)) |
| 596 | (run-hooks 'mouse-leave-buffer-hook) | ||
| 597 | (let* ((done nil) | ||
| 598 | (echo-keystrokes 0) | ||
| 599 | (start-event-frame (window-frame (car (car (cdr start-event))))) | ||
| 600 | (start-event-window (car (car (cdr start-event)))) | ||
| 601 | event mouse x left right edges growth | ||
| 602 | (which-side | ||
| 603 | (or (cdr (assq 'vertical-scroll-bars (frame-parameters start-event-frame))) | ||
| 604 | 'right))) | ||
| 605 | (cond | ||
| 606 | ((one-window-p t) | ||
| 607 | (error "Attempt to resize sole ordinary window")) | ||
| 608 | ((and (eq which-side 'right) | ||
| 609 | (>= (nth 2 (window-inside-edges start-event-window)) | ||
| 610 | (frame-width start-event-frame))) | ||
| 611 | (error "Attempt to drag rightmost scrollbar")) | ||
| 612 | ((and (eq which-side 'left) | ||
| 613 | (= (nth 0 (window-inside-edges start-event-window)) 0)) | ||
| 614 | (error "Attempt to drag leftmost scrollbar"))) | ||
| 615 | (track-mouse | ||
| 616 | (progn | ||
| 617 | ;; loop reading events and sampling the position of | ||
| 618 | ;; the mouse. | ||
| 619 | (while (not done) | ||
| 620 | (setq event (read-event) | ||
| 621 | mouse (mouse-position)) | ||
| 622 | ;; do nothing if | ||
| 623 | ;; - there is a switch-frame event. | ||
| 624 | ;; - the mouse isn't in the frame that we started in | ||
| 625 | ;; - the mouse isn't in any Emacs frame | ||
| 626 | ;; drag if | ||
| 627 | ;; - there is a mouse-movement event | ||
| 628 | ;; - there is a scroll-bar-movement event | ||
| 629 | ;; (same as mouse movement for our purposes) | ||
| 630 | ;; quit if | ||
| 631 | ;; - there is a keyboard event or some other unknown event | ||
| 632 | ;; unknown event. | ||
| 633 | (cond ((integerp event) | ||
| 634 | (setq done t)) | ||
| 635 | ((memq (car event) '(switch-frame select-window)) | ||
| 636 | nil) | ||
| 637 | ((not (memq (car event) | ||
| 638 | '(mouse-movement scroll-bar-movement))) | ||
| 639 | (if (consp event) | ||
| 640 | (setq unread-command-events | ||
| 641 | (cons event unread-command-events))) | ||
| 642 | (setq done t)) | ||
| 643 | ((not (eq (car mouse) start-event-frame)) | ||
| 644 | nil) | ||
| 645 | ((null (car (cdr mouse))) | ||
| 646 | nil) | ||
| 647 | (t | ||
| 648 | (let ((window | ||
| 649 | ;; If the scroll bar is on the window's left, | ||
| 650 | ;; adjust the window on the left. | ||
| 651 | (if (eq which-side 'right) | ||
| 652 | start-event-window | ||
| 653 | (mouse-drag-vertical-line-rightward-window | ||
| 654 | start-event-window)))) | ||
| 655 | (setq x (- (car (cdr mouse)) | ||
| 656 | (if (eq which-side 'right) 0 2)) | ||
| 657 | edges (window-edges window) | ||
| 658 | left (nth 0 edges) | ||
| 659 | right (nth 2 edges)) | ||
| 660 | ;; scale back a move that would make the | ||
| 661 | ;; window too thin. | ||
| 662 | (if (< (- x left -1) window-min-width) | ||
| 663 | (setq x (+ left window-min-width -1))) | ||
| 664 | ;; compute size change needed | ||
| 665 | (setq growth (- x right -1)) | ||
| 666 | (condition-case nil | ||
| 667 | (adjust-window-trailing-edge window growth t) | ||
| 668 | (error nil)))))))))) | ||
| 669 | 533 | ||
| 670 | (defun mouse-set-point (event) | 534 | (defun mouse-set-point (event) |
| 671 | "Move point to the position clicked on with the mouse. | 535 | "Move point to the position clicked on with the mouse. |
diff --git a/lisp/window.el b/lisp/window.el index 4d8b3c92b95..968f47f4f31 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -1084,6 +1084,35 @@ regardless of whether that buffer is current or not." | |||
| 1084 | (goto-char pos)) | 1084 | (goto-char pos)) |
| 1085 | (set-window-point window pos))) | 1085 | (set-window-point window pos))) |
| 1086 | 1086 | ||
| 1087 | (defun window-at-side-p (&optional window side) | ||
| 1088 | "Return t if WINDOW is at SIDE of its containing frame. | ||
| 1089 | WINDOW can be any window and defaults to the selected one. SIDE | ||
| 1090 | can be any of the symbols `left', `top', `right' or `bottom'. | ||
| 1091 | The default value nil is handled like `bottom'." | ||
| 1092 | (setq window (window-normalize-any-window window)) | ||
| 1093 | (let ((edge | ||
| 1094 | (cond | ||
| 1095 | ((eq side 'left) 0) | ||
| 1096 | ((eq side 'top) 1) | ||
| 1097 | ((eq side 'right) 2) | ||
| 1098 | ((memq side '(bottom nil)) 3)))) | ||
| 1099 | (= (nth edge (window-edges window)) | ||
| 1100 | (nth edge (window-edges (frame-root-window window)))))) | ||
| 1101 | |||
| 1102 | (defun windows-at-side (&optional frame side) | ||
| 1103 | "Return list of all windows on SIDE of FRAME. | ||
| 1104 | FRAME must be a live frame and defaults to the selected frame. | ||
| 1105 | SIDE can be any of the symbols `left', `top', `right' or | ||
| 1106 | `bottom'. The default value nil is handled like `bottom'." | ||
| 1107 | (setq frame (window-normalize-frame frame)) | ||
| 1108 | (let (windows) | ||
| 1109 | (walk-window-tree | ||
| 1110 | (lambda (window) | ||
| 1111 | (when (window-at-side-p window side) | ||
| 1112 | (setq windows (cons window windows)))) | ||
| 1113 | frame) | ||
| 1114 | (nreverse windows))) | ||
| 1115 | |||
| 1087 | (defun window-in-direction-2 (window posn &optional horizontal) | 1116 | (defun window-in-direction-2 (window posn &optional horizontal) |
| 1088 | "Support function for `window-in-direction'." | 1117 | "Support function for `window-in-direction'." |
| 1089 | (if horizontal | 1118 | (if horizontal |