all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Re: Side windows
  2010-04-13 23:31 ` Side windows (was: Gtk tabs in emacs, new branch.) Juri Linkov
  2010-04-14  3:18   ` Eli Zaretskii
@ 2010-04-14  5:15   ` Jan Djärv
  2010-04-16 14:03   ` grischka
  2 siblings, 0 replies; 27+ messages in thread
From: Jan Djärv @ 2010-04-14  5:15 UTC (permalink / raw)
  To: Juri Linkov; +Cc: grischka, drew.adams, emacs-devel



Juri Linkov skrev 2010-04-14 01.31:
>> To give another example:  A scrollbar is defined mostly by its action
>> to "scroll content in the associated window".  Of course you could use
>> the scrollbar widget just as well to adjust your speaker volume, but
>> then it wouldn't be a scrollbar, even if it looked like one.
>
> There is a task in etc/TODO:
>
>    ** Compilation error navigation bar, parallel to the scroll bar,
>    indicating where in the buffer there are compilation errors.
>    Perhaps we could arrange to display these error indications on top
>    of the scroll bar itself.  That depends on to what extent toolkit
>    scroll bars are extensible.
>
> If it's possible to display such tab-like indications
> on the scroll bar, is it still called a scroll bar?
>
> If it's not possible, then what is an alternative?
> Maybe, 1-column side bar windows?
>

As Eli already said, the fringe.  Scrollbars aren't the place for this.
How do you know when to remove these indications?

	Jan D.




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-14  3:18   ` Eli Zaretskii
@ 2010-04-14 15:24     ` Jason Rumney
  2010-04-14 16:52       ` Juri Linkov
  0 siblings, 1 reply; 27+ messages in thread
From: Jason Rumney @ 2010-04-14 15:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Juri Linkov, grishka, drew.adams, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>>   ** Compilation error navigation bar, parallel to the scroll bar,
>>   indicating where in the buffer there are compilation errors.
>>   Perhaps we could arrange to display these error indications on top
>>   of the scroll bar itself.  That depends on to what extent toolkit
>>   scroll bars are extensible.
>> 
>> If it's possible to display such tab-like indications
>> on the scroll bar, is it still called a scroll bar?
>> 
>> If it's not possible, then what is an alternative?
>> Maybe, 1-column side bar windows?
>
> The fringe, I think.

The fringe nearest the scroll-bar is the right place to display the
indicators I think, but we need a new mechanism to display them, as they
should not scroll with the buffer text.




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-14 15:24     ` Side windows Jason Rumney
@ 2010-04-14 16:52       ` Juri Linkov
  2010-04-14 18:19         ` Eli Zaretskii
  0 siblings, 1 reply; 27+ messages in thread
From: Juri Linkov @ 2010-04-14 16:52 UTC (permalink / raw)
  To: Jason Rumney; +Cc: Eli Zaretskii, grishka, drew.adams, emacs-devel

>>>   ** Compilation error navigation bar, parallel to the scroll bar,
>>>   indicating where in the buffer there are compilation errors.
>>>   Perhaps we could arrange to display these error indications on top
>>>   of the scroll bar itself.  That depends on to what extent toolkit
>>>   scroll bars are extensible.
>>>
>>> If it's possible to display such tab-like indications
>>> on the scroll bar, is it still called a scroll bar?
>>>
>>> If it's not possible, then what is an alternative?
>>> Maybe, 1-column side bar windows?
>>
>> The fringe, I think.
>
> The fringe nearest the scroll-bar is the right place to display the
> indicators I think, but we need a new mechanism to display them, as they
> should not scroll with the buffer text.

Does this mean an additional fringe is necessary that doesn't scroll?

Then we have the same question as with multiple header lines:
whether to allow multiple fringes and header lines or implement them
as true windows placed on the left or on the top of the base window.

Using windows will allow implementing emulations of the scroll bar
like minimap.el, etc.  I'm not sure whether this is possible to do
with additional fringes?

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-14 16:52       ` Juri Linkov
@ 2010-04-14 18:19         ` Eli Zaretskii
  2010-04-14 23:54           ` Juri Linkov
  0 siblings, 1 reply; 27+ messages in thread
From: Eli Zaretskii @ 2010-04-14 18:19 UTC (permalink / raw)
  To: Juri Linkov; +Cc: grishka, emacs-devel, drew.adams, jasonr

> From: Juri Linkov <juri@jurta.org>
> Cc: Eli Zaretskii <eliz@gnu.org>,  grishka@gmx.de,  drew.adams@oracle.com,  emacs-devel@gnu.org
> Date: Wed, 14 Apr 2010 19:52:01 +0300
> 
> >>>   ** Compilation error navigation bar, parallel to the scroll bar,
> >>>   indicating where in the buffer there are compilation errors.
> >>>   Perhaps we could arrange to display these error indications on top
> >>>   of the scroll bar itself.  That depends on to what extent toolkit
> >>>   scroll bars are extensible.
> >>>
> >>> If it's possible to display such tab-like indications
> >>> on the scroll bar, is it still called a scroll bar?
> >>>
> >>> If it's not possible, then what is an alternative?
> >>> Maybe, 1-column side bar windows?
> >>
> >> The fringe, I think.
> >
> > The fringe nearest the scroll-bar is the right place to display the
> > indicators I think, but we need a new mechanism to display them, as they
> > should not scroll with the buffer text.
> 
> Does this mean an additional fringe is necessary that doesn't scroll?

Not necessarily.  We could provide a feature whereby bitmaps displayed
in the fringe would be moved by redisplay so that their position
relative to the window top does not change as the window is scrolled.




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-14 18:19         ` Eli Zaretskii
@ 2010-04-14 23:54           ` Juri Linkov
  2010-04-15  3:18             ` Eli Zaretskii
  0 siblings, 1 reply; 27+ messages in thread
From: Juri Linkov @ 2010-04-14 23:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: grishka, emacs-devel, drew.adams, jasonr

>> >>> Maybe, 1-column side bar windows?
>> >>
>> >> The fringe, I think.
>> >
>> > The fringe nearest the scroll-bar is the right place to display the
>> > indicators I think, but we need a new mechanism to display them, as
>> > they should not scroll with the buffer text.
>>
>> Does this mean an additional fringe is necessary that doesn't scroll?
>
> Not necessarily.  We could provide a feature whereby bitmaps displayed
> in the fringe would be moved by redisplay so that their position
> relative to the window top does not change as the window is scrolled.

Currently fringe positions are relative to lines (to indicate truncated
lines, continued lines, overlay arrows, etc.)

Using it to indicate window relative positions like scroll bars do
will make a mess in the same fringe.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-14 23:54           ` Juri Linkov
@ 2010-04-15  3:18             ` Eli Zaretskii
  2010-04-15 23:46               ` Juri Linkov
  0 siblings, 1 reply; 27+ messages in thread
From: Eli Zaretskii @ 2010-04-15  3:18 UTC (permalink / raw)
  To: Juri Linkov; +Cc: grishka, emacs-devel, drew.adams, jasonr

> From: Juri Linkov <juri@jurta.org>
> Cc: jasonr@gnu.org,  grishka@gmx.de,  drew.adams@oracle.com,  emacs-devel@gnu.org
> Date: Thu, 15 Apr 2010 02:54:21 +0300
> 
> Currently fringe positions are relative to lines (to indicate truncated
> lines, continued lines, overlay arrows, etc.)
> 
> Using it to indicate window relative positions like scroll bars do
> will make a mess in the same fringe.

The proposed bitmap is very small (thin), AFAIU, so I'm not sure the
mess would be quite as big as you seem to fear.  Overlay arrows are on
the left fringe, so they do not contribute to the mess at all.  We
could enlarge the right fringe (in compilation-mode) to make the mess
even smaller.

An alternative could be to use the margin for this.  Its advantage is
that it will also work on a TTY.  But I think this would be a larger
job because currently margins are not clickable, while the fringe is.




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-15  3:18             ` Eli Zaretskii
@ 2010-04-15 23:46               ` Juri Linkov
  2010-04-16  6:33                 ` Eli Zaretskii
  0 siblings, 1 reply; 27+ messages in thread
From: Juri Linkov @ 2010-04-15 23:46 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: grishka, emacs-devel, drew.adams, jasonr

> The proposed bitmap is very small (thin), AFAIU, so I'm not sure the
> mess would be quite as big as you seem to fear.  Overlay arrows are on
> the left fringe, so they do not contribute to the mess at all.  We
> could enlarge the right fringe (in compilation-mode) to make the mess
> even smaller.

This practically means multi-column fringes.  Maybe the same suggests
implementing the multi-line header line instead of multiple header lines
or multiple header windows.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-15 23:46               ` Juri Linkov
@ 2010-04-16  6:33                 ` Eli Zaretskii
  0 siblings, 0 replies; 27+ messages in thread
From: Eli Zaretskii @ 2010-04-16  6:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: grishka, emacs-devel, drew.adams, jasonr

> From: Juri Linkov <juri@jurta.org>
> Cc: jasonr@gnu.org,  grishka@gmx.de,  drew.adams@oracle.com,  emacs-devel@gnu.org
> Date: Fri, 16 Apr 2010 02:46:17 +0300
> 
> > The proposed bitmap is very small (thin), AFAIU, so I'm not sure the
> > mess would be quite as big as you seem to fear.  Overlay arrows are on
> > the left fringe, so they do not contribute to the mess at all.  We
> > could enlarge the right fringe (in compilation-mode) to make the mess
> > even smaller.
> 
> This practically means multi-column fringes.

No, it doesn't.  I wasn't suggesting to have more than one bitmap on
the fringe at the same place (I think this is impossible with today's
code).  I was just saying that the visual appearance would not be as
bad as it may sound.

> Maybe the same suggests implementing the multi-line header line
> instead of multiple header lines or multiple header windows.

I don't think so.  The current display engine does not support a
notion of glyph rows that are more than one glyph tall.  And since
each glyph comes from some font, you cannot have two of them together,
unless you either (a) craft a font with combination of 2 characters in
it, or (b) make some composition rules to compose them into a single
glyph.




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-13 23:31 ` Side windows (was: Gtk tabs in emacs, new branch.) Juri Linkov
  2010-04-14  3:18   ` Eli Zaretskii
  2010-04-14  5:15   ` Jan Djärv
@ 2010-04-16 14:03   ` grischka
  2010-04-16 20:48     ` Juri Linkov
  2 siblings, 1 reply; 27+ messages in thread
From: grischka @ 2010-04-16 14:03 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 711 bytes --]

Juri Linkov wrote:
> There is a task in etc/TODO:
> 
>   ** Compilation error navigation bar, parallel to the scroll bar,
>   indicating where in the buffer there are compilation errors.
>   Perhaps we could arrange to display these error indications on top
>   of the scroll bar itself.  That depends on to what extent toolkit
>   scroll bars are extensible.
> 
> If it's possible to display such tab-like indications
> on the scroll bar, is it still called a scroll bar?
> 
> If it's not possible, then what is an alternative?
> Maybe, 1-column side bar windows?

WinMerge and KDiff3 have a "sort of" scrollbar with transparent thumb
used to indicate (and jump to) the regions with differences.

See picture.

[-- Attachment #2: wmind.png --]
[-- Type: image/png, Size: 4270 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side windows
  2010-04-16 14:03   ` grischka
@ 2010-04-16 20:48     ` Juri Linkov
  0 siblings, 0 replies; 27+ messages in thread
From: Juri Linkov @ 2010-04-16 20:48 UTC (permalink / raw)
  To: grischka; +Cc: emacs-devel

>>   ** Compilation error navigation bar, parallel to the scroll bar,
>>   indicating where in the buffer there are compilation errors.
>>   Perhaps we could arrange to display these error indications on top
>>   of the scroll bar itself.  That depends on to what extent toolkit
>>   scroll bars are extensible.
>>
>> If it's possible to display such tab-like indications
>> on the scroll bar, is it still called a scroll bar?
>>
>> If it's not possible, then what is an alternative?
>> Maybe, 1-column side bar windows?
>
> WinMerge and KDiff3 have a "sort of" scrollbar with transparent thumb
> used to indicate (and jump to) the regions with differences.
>
> See picture.

This is definitely impossible to do in fringes with today's code.
But using the same technique as is used by palette.el
http://www.emacswiki.org/emacs/ColorPalette to create pseudo-graphics
in a side window it should be doable.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Side Windows
@ 2016-09-22  9:07 martin rudalics
  2016-09-22 20:54 ` Juri Linkov
  2016-09-23  8:38 ` Eli Zaretskii
  0 siblings, 2 replies; 27+ messages in thread
From: martin rudalics @ 2016-09-22  9:07 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 148 bytes --]

The attached patch fixes some longstanding bugs/issues with side windows
and provides the lacking documentation.  Comments welcome.

Thanks, martin

[-- Attachment #2: side-windows.diff --]
[-- Type: text/plain, Size: 55668 bytes --]

--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1038,6 +1038,7 @@ Top
                               a specific window.
 * Quitting Windows::        How to restore the state prior to displaying a
                               buffer.
+* Side Windows::            Special windows on a frame's sides.
 * Window Point::            Each window has its own location of point.
 * Window Start and End::    Buffer positions indicating which text is
                               on-screen in a window.
@@ -1051,6 +1052,14 @@ Top
                               redisplay going past a certain point,
                               or window configuration changes.

+Side Windows
+
+* Displaying Buffers in Side Windows:: An action function for displaying
+                              buffers in side windows.
+* Side Window Options and Functions:: Further tuning of side windows.
+* Frame Layouts with Side Windows:: Setting up frame layouts with side
+                              windows.
+
 Frames

 * Creating Frames::         Creating additional frames.
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 3c9df0b..c326b7c 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -33,6 +33,7 @@ Windows
                               a specific window.
 * Quitting Windows::        How to restore the state prior to displaying a
                               buffer.
+* Side Windows::            Special windows on a frame's sides.
 * Window Point::            Each window has its own location of point.
 * Window Start and End::    Buffer positions indicating which text is
                               on-screen in a window.
@@ -1275,9 +1276,12 @@ Deleting Windows
 @deffn Command delete-window &optional window
 This function removes @var{window} from display and returns
 @code{nil}.  If @var{window} is omitted or @code{nil}, it defaults to
-the selected window.  If deleting the window would leave no more
-windows in the window tree (e.g., if it is the only live window in the
-frame), an error is signaled.
+the selected window.
+
+If deleting the window would leave no more windows in the window tree
+(e.g., if it is the only live window in the frame) or all remaining
+windows on @var{window}'s frame are side windows (@pxref{Side Windows}),
+an error is signaled.

 By default, the space taken up by @var{window} is given to one of its
 adjacent sibling windows, if any.  However, if the variable
@@ -1285,33 +1289,34 @@ Deleting Windows
 proportionally distributed among any remaining windows in the same
 window combination.  @xref{Recombining Windows}.

-The behavior of this function may be altered by the window parameters
-of @var{window}, so long as the variable
-@code{ignore-window-parameters} is @code{nil}.  If the value of
-the @code{delete-window} window parameter is @code{t}, this function
-ignores all other window parameters.  Otherwise, if the value of the
-@code{delete-window} window parameter is a function, that function is
-called with the argument @var{window}, in lieu of the usual action of
-@code{delete-window}.  Otherwise, this function obeys the
-@code{window-atom} or @code{window-side} window parameter, if any.
-@xref{Window Parameters}.
+The behavior of this function may be altered by the window parameters of
+@var{window}, so long as the variable @code{ignore-window-parameters} is
+@code{nil}.  If the value of the @code{delete-window} window parameter
+is @code{t}, this function ignores all other window parameters.
+Otherwise, if the value of the @code{delete-window} window parameter is
+a function, that function is called with the argument @var{window}, in
+lieu of the usual action of @code{delete-window}.  @xref{Window
+Parameters}.
 @end deffn

 @deffn Command delete-other-windows &optional window
-This function makes @var{window} fill its frame, by deleting other
-windows as necessary.  If @var{window} is omitted or @code{nil}, it
-defaults to the selected window.  The return value is @code{nil}.
-
-The behavior of this function may be altered by the window parameters
-of @var{window}, so long as the variable
-@code{ignore-window-parameters} is @code{nil}.  If the value of
-the @code{delete-other-windows} window parameter is @code{t}, this
-function ignores all other window parameters.  Otherwise, if the value
-of the @code{delete-other-windows} window parameter is a function,
-that function is called with the argument @var{window}, in lieu of the
-usual action of @code{delete-other-windows}.  Otherwise, this function
-obeys the @code{window-atom} or @code{window-side} window parameter,
-if any.  @xref{Window Parameters}.
+This function makes @var{window} fill its frame, deleting other windows
+as necessary.  If @var{window} is omitted or @code{nil}, it defaults to
+the selected window.  An error is signaled if @var{window} is a side
+window (@pxref{Side Windows}).  The return value is @code{nil}.
+
+The behavior of this function may be altered by the window parameters of
+@var{window}, so long as the variable @code{ignore-window-parameters} is
+@code{nil}.  If the value of the @code{delete-other-windows} window
+parameter is @code{t}, this function ignores all other window
+parameters.  Otherwise, if the value of the @code{delete-other-windows}
+window parameter is a function, that function is called with the
+argument @var{window}, in lieu of the usual action of
+@code{delete-other-windows}.  @xref{Window Parameters}.
+
+Also, if @code{ignore-window-parameters} is @code{nil}, this function
+does not delete any window whose @code{no-delete-other-window} parameter
+is non-@code{nil}.
 @end deffn

 @deffn Command delete-windows-on &optional buffer-or-name frame
@@ -2574,7 +2579,12 @@ Display Action Functions
 from @code{display-buffer} in this case.
 @end defun

-To illustrate the use of action functions, consider the following
+If the @var{alist} argument of any of these functions contains a
+@code{window-parameters} entry, @code{display-buffer} assigns the
+elements of the associated value as window parameters of the chosen
+window.
+
+   To illustrate the use of action functions, consider the following
 example.

 @example
@@ -3068,6 +3078,278 @@ Quitting Windows
 @end defopt


+@node Side Windows
+@section Side Windows
+@cindex side windows
+@cindex main window
+@cindex main window of a frame
+
+Side windows are special windows positioned at any of the four sides of
+a frame's root window (@pxref{Windows and Frames}).  In practice, this
+means that the area of the frame's root window is subdivided into a main
+window and a number of side windows surrounding that main window.  The
+main window is either a ``normal'' live window or specifies the area
+containing all the normal windows.
+
+   In their most simple form of use, side windows allow to display
+specific buffers always in the same area of a frame.  Hence they can be
+regarded as a generalization of the concept provided by
+@code{display-buffer-at-bottom} (@pxref{Display Action Functions}) to
+the remaining sides of a frame.  With suitable customizations, however,
+side windows can be also used to provide frame layouts similar to those
+found in so-called integrated development environments (IDEs).
+
+@menu
+* Displaying Buffers in Side Windows:: An action function for displaying
+                              buffers in side windows.
+* Side Window Options and Functions:: Further tuning of side windows.
+* Frame Layouts with Side Windows:: Setting up frame layouts with side
+                              windows.
+@end menu
+
+
+@node Displaying Buffers in Side Windows
+@subsection Displaying Buffers in Side Windows
+
+The following action function for @code{display-buffer} (@pxref{Display
+Action Functions}) creates or reuses a side window for displaying the
+specified buffer.
+
+@defun display-buffer-in-side-window buffer alist
+This function displays @var{buffer} in a side window of the selected
+frame.  @var{alist} is an association list of symbols and values as for
+@code{display-buffer}.  The following symbols in @var{alist} are special
+for this function:
+
+@table @code
+@item side
+Denotes the side of the frame where the window shall be located.  Valid
+values are @code{left}, @code{top}, @code{right} and @code{bottom}.  If
+unspecified, the window is located at the bottom of the frame.
+
+@item slot
+Denotes a slot at the specified side where to locate the window.  A
+value of zero means to preferably position the window in the middle of
+the specified side.  A negative value means to use a slot preceding
+(that is, above or on the left of) the middle slot.  A positive value
+means to use a slot following (that is, below or on the right of) the
+middle slot.  Hence, all windows on a specific side are ordered by their
+@code{slot} value.  If unspecified, the window is located in the middle
+of the specified side.
+@end table
+
+If you specify the same slot on the same side for two or more different
+buffers, the buffer displayed last is shown in the corresponding window.
+Hence, slots can be used for sharing the same side window between
+buffers.
+
+This function installs the @code{window-side} and @code{window-slot}
+parameters (@pxref{Window Parameters}) and makes them persistent.  It
+does not install any other window parameters unless they have been
+explicitly provided via a @code{window-parameters} entry in @var{alist}.
+@end defun
+
+By default, side windows cannot be split via @code{split-window}
+(@pxref{Splitting Windows}).  Also, a side window is not reused or split
+by any buffer display action (@pxref{Display Action Functions}) unless
+it is explicitly specified as target of that action.  Note also that
+@code{delete-other-windows} cannot make a side window the only window on
+its frame (@pxref{Deleting Windows}).
+
+   Once set up, side windows also change the behavior of the commands
+@code{switch-to-prev-buffer} and @code{switch-to-next-buffer}
+(@pxref{Window History}).  In particular, these commands will refrain
+from showing, in a side window, buffers that have not been displayed in
+that window before.  And, they will refrain from having a normal,
+non-side window show a buffer that has been already displayed in a side
+window.  A notable exception to the latter rule occurs when an
+application, after displaying a buffer, resets that buffer's local
+variables.
+
+
+@node Side Window Options and Functions
+@subsection Side Window Options and Functions
+
+The following two options provide additional control over the
+placement of side windows.
+
+@defopt window-sides-vertical
+If non-@code{nil}, this means that the side windows on the left and
+right of a frame occupy the frame's full height.  Otherwise, the side
+windows on the top and bottom of the frame occupy the frame's full
+width.  Note that changing the value of this variable does not affect
+the layout of frames already displaying side windows on at least two
+orthogonal sides.
+@end defopt
+
+@defopt window-sides-slots
+This option specifies the maximum number of side windows on each side of
+a frame.  The value is a list of four elements specifying the number of
+side window slots on (in this order) the left, top, right and bottom of
+each frame.  If an element is a number, this means to display at most
+that many windows on the corresponding side.  If an element is
+@code{nil}, this means there's no bound on the number of slots on that
+side.
+
+If any of the specified values is zero, no window can be created on the
+corresponding side.  @code{display-buffer-in-side-window} will not
+signal an error in that case but return @code{nil}.  If a specified
+value just forbids the creation of an additional side window, the most
+suitable window on that side is reused and may have its
+@code{window-slot} parameter changed accordingly.
+@end defopt
+
+When a frame has side windows, the following function returns the main
+window of that frame.
+
+@defun window-main-window &optional frame
+This function returns the main window of the specified @var{frame}.  The
+optional argument @var{frame} must be a live frame and defaults to the
+selected one.
+
+If @var{frame} has no side windows, it returns @var{frame}'s root
+window.  Otherwise, it returns either an internal non-side window such
+that all other non-side windows on @var{frame} descend from it, or the
+single live non-side window of @var{frame}.  Note that the main window
+of a frame cannot be deleted via @code{delete-window}.
+@end defun
+
+The following command is handy to toggle the appearance of all side
+windows on a specified frame.
+
+@deffn Command window-toggle-side-windows &optional frame
+This command toggles side windows on the specified @var{frame}.  The
+optional argument @var{frame} must be a live frame and defaults to the
+selected one.
+
+If @var{frame} has at least one side window, this command saves the
+state of @var{frame}'s root window in the @var{frame}'s
+@code{window-state} frame parameter and deletes all side windows on
+@var{frame} afterwards.
+
+If @var{frame} has no side window but a @code{window-state} parameter,
+it uses that parameter's value to restore the side windows on
+@var{frame} leaving @var{frame}'s main window alone.
+
+An error is signaled if @var{frame} has no side window and no saved
+state is found.
+@end deffn
+
+
+@node Frame Layouts with Side Windows
+@subsection Frame Layouts with Side Windows
+
+Side windows can be used to create more complex frame layouts like those
+provided by integrated development environments (IDEs).  In such
+layouts, the area of the main window is where the normal editing
+activities take place.  Side windows are not conceived for editing in
+the usual sense.  Rather, they are supposed to display information
+complementary to the current editing activity, like lists of files, tags
+or buffers, help information, search or grep results or shell output.
+
+   The layout of such a frame might appear as follows:
+
+@smallexample
+@group
+     ___________________________________
+    |          *Buffer List*            | 
+    |___________________________________|
+    |     |                       |     |
+    |  *  |                       |  *  |
+    |  d  |                       |  T  |
+    |  i  |                       |  a  |
+    |  r  |   Main Window Area    |  g  |
+    |  e  |                       |  s  |
+    |  d  |                       |  *  |
+    |  *  |                       |     |
+    |_____|_______________________|_____|
+    | *help*/*grep*/  |  *shell*/       |
+    | *Completions*   |  *compilation*  |
+    |_________________|_________________|
+    |             Echo Area             |
+    |___________________________________|
+
+
+@end group
+@end smallexample
+
+The following example illustrates how window parameters (@pxref{Window
+Parameters}) can be used with @code{display-buffer-in-side-window}
+(@pxref{Displaying Buffers in Side Windows}) to set up code for
+producing the frame sketched above.
+
+@example
+@group
+(defvar parameters
+  '(window-parameters . ((no-other-window . t) (no-delete-other-window . t))))
+
+(setq fit-window-to-buffer-horizontally t)
+(setq window-resize-pixelwise t)
+
+(setq
+ display-buffer-alist
+ `(("\\*Buffer List\\*" display-buffer-in-side-window
+    (side . top) (slot . 0) (window-height . fit-window-to-buffer)
+    (preserve-size . (nil . t)) ,parameters)
+   ("\\*Tags List\\*" display-buffer-in-side-window
+    (side . right) (slot . 0) (window-width . fit-window-to-buffer)
+    (preserve-size . (t . nil)) ,parameters)
+   ("\\*\\(?:help\\|grep\\|Completions\\)\\*" display-buffer-in-side-window
+    (side . bottom) (slot . -1) (preserve-size . (nil . t)) ,parameters)
+   ("\\*\\(?:shell\\|compilation\\)\\*" display-buffer-in-side-window
+    (side . bottom) (slot . 1) (preserve-size . (nil . t)) ,parameters)))
+@end group
+@end example
+
+This specifies @code{display-buffer-alist} entries (@pxref{Choosing
+Window}) for buffers with fixed names.  In particular, it asks for
+showing @file{*Buffer List*} with adjustable height at the top of the
+frame and @file{*Tags List*} with adjustable width on the frame's right.
+It also asks for having the @file{*help*}, @file{*grep*} and
+@file{*Completions*} buffers share a window on the bottom left side of
+the frame and the @file{*shell*} and @file{*compilation*} buffers appear
+in a window on the bottom right side of the frame.
+
+   Note that the option @code{fit-window-to-buffer-horizontally} must
+have a non-@code{nil} value in order to allow horizontal adjustment of
+windows.  We also added entries that ask for preserving the height of
+side windows at the top and bottom of the frame and the width of side
+windows at the left or right of the frame.  To assure that side windows
+retain their respective sizes when maximizing the associated frame, we
+have also set the variable @code{window-resize-pixelwise}.
+@xref{Resizing Windows}.
+
+   The last form also makes sure that none of the side windows it
+creates are accessible via @kbd{C-x o} by installing a
+@code{no-other-window} parameter for each of these windows.  In addition
+it also makes sure that side windows are not deleted via @kbd{C-x 1} by
+installing a @code{no-delete-other-window} parameter on each of these
+windows.
+
+   Since @code{dired} buffers have no fixed names, we use a special
+function @code{dired-default-directory-on-left} in order to display a
+lean directory buffer on the left side of the frame.
+
+@example
+@group
+(defun dired-default-directory-on-left ()
+  "Display `default-directory' in side window on left, hiding details."
+  (interactive)
+  (let ((buffer (dired-noselect default-directory)))
+    (with-current-buffer buffer (dired-hide-details-mode t))
+    (display-buffer-in-side-window
+     buffer `((side . left) (slot . 0)
+              (window-width . fit-window-to-buffer)
+              (preserve-size . (t . nil)) ,parameters))))
+@end group
+@end example
+
+Evaluating the preceding forms and typing, in any order, @kbd{M-x
+list-buffers}, @kbd{C-h f}, @kbd{M-x shell}, @kbd{M-x list-tags} and
+@kbd{M-x dired-default-directory-on-left} should now reproduce the frame
+layout sketched above.
+
+
 @node Window Point
 @section Windows and Point
 @cindex window position
@@ -4279,6 +4561,7 @@ Window Parameters
 parameters reset to @code{nil}.  The following variable allows you to
 override the standard behavior:

+@cindex persistent window parameters
 @defvar window-persistent-parameters
 This variable is an alist specifying which parameters get saved by
 @code{current-window-configuration} and @code{window-state-get}, and
@@ -4308,10 +4591,10 @@ Window Parameters
 @end defvar

 Some functions (notably @code{delete-window},
-@code{delete-other-windows} and @code{split-window}), may behave specially
-when their @var{window} argument has a parameter set.  You can override
-such special behavior by binding the following variable to a
-non-@code{nil} value:
+@code{delete-other-windows} and @code{split-window}), may behave
+specially when the window specified by their @var{window} argument has
+the homonymous parameter set.  You can override such special behavior by
+binding the following variable to a non-@code{nil} value:

 @defvar ignore-window-parameters
 If this variable is non-@code{nil}, some standard functions do not
@@ -4337,6 +4620,10 @@ Window Parameters
 This parameter affects the execution of @code{delete-other-windows}
 (@pxref{Deleting Windows}).

+@item @code{no-delete-other-window}
+This parameter marks the window as not deletable by
+@code{delete-other-windows} (@pxref{Deleting Windows}).
+
 @item @code{split-window}
 This parameter affects the execution of @code{split-window}
 (@pxref{Splitting Windows}).
@@ -4387,6 +4674,10 @@ Window Parameters
 this parameter.  @code{quit-restore-window} deletes the specified window
 only if it still shows that buffer.

+@item @code{window-side} @code{window-slot}
+These parameters are used for implementing side windows (@pxref{Side
+Windows}).
+
 @item @code{min-margins}
 The value of this parameter is a cons cell whose @sc{car} and @sc{cdr},
 if non-@code{nil}, specify the minimum values (in columns) for the left
@@ -4409,8 +4700,7 @@ Window Parameters
 versions of Emacs.
 @end table

-There are additional parameters @code{window-atom} and @code{window-side};
-these are reserved and should not be used by applications.
+The @code{window-atom} parameter is used for implemeting atomic windows.


 @node Window Hooks
diff --git a/lisp/window.el b/lisp/window.el
index 6728ea3..73c48be 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -714,19 +714,23 @@ window-sides

 (defcustom window-sides-vertical nil
   "If non-nil, left and right side windows are full height.
-Otherwise, top and bottom side windows are full width."
+Otherwise, top and bottom side windows are full width.  
+
+Setting this variable does not affect the layout of frames
+already displaying side windows on at least two orthogonal
+sides."
   :type 'boolean
   :group 'windows
   :version "24.1")

 (defcustom window-sides-slots '(nil nil nil nil)
   "Maximum number of side window slots.
-The value is a list of four elements specifying the number of
-side window slots on (in this order) the left, top, right and
-bottom side of each frame.  If an element is a number, this means
-to display at most that many side windows on the corresponding
-side.  If an element is nil, this means there's no bound on the
-number of slots on that side."
+The value is a list of four elements specifying the maximum
+number of side windows on the left, top, right and bottom side of
+any frame.  If an element is a number, this means to display at
+most that many side windows on the corresponding side.  If an
+element is nil, this means there's no bound on the number of
+slots on that side."
   :version "24.1"
   :risky t
   :type
@@ -734,34 +738,44 @@ window-sides-slots
     :value (nil nil nil nil)
     (choice
      :tag "Left"
-     :help-echo "Maximum slots of left side window."
+     :help-echo "Maximum number of left side windows."
      :value nil
      :format "%[Left%] %v\n"
      (const :tag "Unlimited" :format "%t" nil)
      (integer :tag "Number" :value 2 :size 5))
     (choice
      :tag "Top"
-     :help-echo "Maximum slots of top side window."
+     :help-echo "Maximum number of top side windows."
      :value nil
      :format "%[Top%] %v\n"
      (const :tag "Unlimited" :format "%t" nil)
      (integer :tag "Number" :value 3 :size 5))
     (choice
      :tag "Right"
-     :help-echo "Maximum slots of right side window."
+     :help-echo "Maximum number of right side windows."
      :value nil
      :format "%[Right%] %v\n"
      (const :tag "Unlimited" :format "%t" nil)
      (integer :tag "Number" :value 2 :size 5))
     (choice
      :tag "Bottom"
-     :help-echo "Maximum slots of bottom side window."
+     :help-echo "Maximum number of bottom side windows."
      :value nil
      :format "%[Bottom%] %v\n"
      (const :tag "Unlimited" :format "%t" nil)
      (integer :tag "Number" :value 3 :size 5)))
   :group 'windows)

+(defvar-local window-sides-shown nil
+  "Non-nil if this buffer was shown in a side window once.
+If this variable is non-nil in a buffer, the
+`switch-to-prev-buffer' and `switch-to-next-buffer' functions
+will refrain to show this buffer within the main window area.
+`display-buffer-in-side-window' sets this variable automatically.
+
+Killing buffer local variables after showing the buffer in a side
+window annihilates the effect provided by setting this.")
+
 (defun window--side-window-p (window)
   "Return non-nil if WINDOW is a side window or the parent of one."
   (or (window-parameter window 'window-side)
@@ -771,19 +785,18 @@ window--side-window-p
 	       (window-parameter
 		(window-last-child window) 'window-side)))))

-(defun window--major-non-side-window (&optional frame)
-  "Return the major non-side window of frame FRAME.
+(defun window-main-window (&optional frame)
+  "Return the main window of specified FRAME.
 The optional argument FRAME must be a live frame and defaults to
 the selected one.

-If FRAME has at least one side window, the major non-side window
-is either an internal non-side window such that all other
-non-side windows on FRAME descend from it, or the single live
-non-side window of FRAME.  If FRAME has no side windows, return
-its root window."
+If FRAME has no side windows, return FRAME's root window.
+Otherwise, return either an internal non-side window such that
+all other non-side windows on FRAME descend from it, or the
+single live non-side window of FRAME."
   (let ((frame (window-normalize-frame frame))
-	major sibling)
-    ;; Set major to the _last_ window found by `walk-window-tree' that
+	main sibling)
+    ;; Set main to the _last_ window found by `walk-window-tree' that
     ;; is not a side window but has a side window as its sibling.
     (walk-window-tree
      (lambda (window)
@@ -792,14 +805,17 @@ window--major-non-side-window
 		     (window-parameter sibling 'window-side))
 		(and (setq sibling (window-next-sibling window))
 		     (window-parameter sibling 'window-side)))
-	    (setq major window)))
+	    (setq main window)))
      frame t 'nomini)
-    (or major (frame-root-window frame))))
+    (or main (frame-root-window frame))))

-(defun window--major-side-window (side)
-  "Return major side window on SIDE.
+(defun window--make-major-side-window-next-to (side)
+  "Return window to split for making a major side window.
 SIDE must be one of the symbols `left', `top', `right' or
-`bottom'.  Return nil if no such window exists."
+`bottom'.
+
+This is an auxiliary function of `window--make-major-side-window'
+and must not be called when a window on SIDE exists already."
   (let ((root (frame-root-window))
 	window)
     ;; (1) If a window on the opposite side exists, return that window's
@@ -839,35 +855,36 @@ window--major-side-window
 	(window-prev-sibling window))
        (t root))))))

-(defun display-buffer-in-major-side-window (buffer side slot &optional alist)
-  "Display BUFFER in a new window on SIDE of the selected frame.
+(defun window--make-major-side-window (buffer side slot &optional alist)
+  "Display BUFFER in a new major side window on the selected frame.
 SIDE must be one of `left', `top', `right' or `bottom'.  SLOT
 specifies the slot to use.  ALIST is an association list of
 symbols and values as passed to `display-buffer-in-side-window'.
-This function may be called only if no window on SIDE exists yet.
-The new window automatically becomes the \"major\" side window on
-SIDE.  Return the new window, nil if its creation window failed."
+Return the new window, nil if its creation failed.
+
+This is an auxiliary function of `display-buffer-in-side-window'
+and may be called only if no window on SIDE exists yet."
   (let* ((left-or-right (memq side '(left right)))
-	 (major (window--major-side-window side))
+	 (next-to (window--make-major-side-window-next-to side))
 	 (on-side (cond
 		   ((eq side 'top) 'above)
 		   ((eq side 'bottom) 'below)
 		   (t side)))
 	 ;; The following two bindings will tell `split-window' to take
-	 ;; the space for the new window from `major' and not make a new
-	 ;; parent window unless needed.
+	 ;; the space for the new window from the selected frame's main
+	 ;; window and not make a new parent window unless needed.
 	 (window-combination-resize 'side)
 	 (window-combination-limit nil)
-	 (new (split-window major nil on-side)))
-    (when new
-      ;; Initialize `window-side' parameter of new window to SIDE.
-      (set-window-parameter new 'window-side side)
-      ;; Install `window-slot' parameter of new window.
-      (set-window-parameter new 'window-slot slot)
-      ;; Install `delete-window' parameter thus making sure that when
-      ;; the new window is deleted, a side window on the opposite side
-      ;; does not get resized.
-      (set-window-parameter new 'delete-window 'delete-side-window)
+	 (window (split-window next-to nil on-side)))
+    (when window
+      ;; Initialize `window-side' parameter of new window to SIDE and
+      ;; make that parameter persistent.
+      (set-window-parameter window 'window-side side)
+      (add-to-list 'window-persistent-parameters '(window-side . writable))
+      ;; Install `window-slot' parameter of new window and make that
+      ;; parameter persistent.
+      (set-window-parameter window 'window-slot slot)
+      (add-to-list 'window-persistent-parameters '(window-slot . writable))
       ;; Auto-adjust height/width of new window unless a size has been
       ;; explicitly requested.
       (unless (if left-or-right
@@ -882,15 +899,10 @@ display-buffer-in-major-side-window
 		   ;; root window.
 		   4))
 	       alist)))
-      ;; Install BUFFER in new window and return NEW.
-      (window--display-buffer buffer new 'window alist 'side))))
-
-(defun delete-side-window (window)
-  "Delete side window WINDOW."
-  (let ((window-combination-resize
-	 (window-parameter (window-parent window) 'window-side))
-	(ignore-window-parameters t))
-    (delete-window window)))
+      (with-current-buffer buffer
+        (setq window-sides-shown t))
+      ;; Install BUFFER in new window and return WINDOW.
+      (window--display-buffer buffer window 'window alist 'side))))

 (defun display-buffer-in-side-window (buffer alist)
   "Display BUFFER in a side window of the selected frame.
@@ -906,9 +918,27 @@ display-buffer-in-side-window
   the specified side.  A negative value means use a slot
   preceding (that is, above or on the left of) the middle slot.
   A positive value means use a slot following (that is, below or
-  on the right of) the middle slot.  The default is zero."
-  (let ((side (or (cdr (assq 'side alist)) 'bottom))
-	(slot (or (cdr (assq 'slot alist)) 0)))
+  on the right of) the middle slot.  The default is zero.
+
+If the current frame size or the settings of `window-sides-slots'
+do not permit making a new window, a suitable existing window may
+be reused and have its `window-slot' parameter value accordingly
+modified.
+
+Unless `display-buffer-mark-dedicated' is non-nil, softly
+dedicate the side window used to BUFFER.  Return nil if no
+suitable window is found.
+
+This function installs the `window-side' and `window-slot'
+parameters and makes them persistent.  It neither modifies ALIST
+nor installs any other window parameters unless they have been
+explicitly provided via a `window-parameter' entry in ALIST."
+  (let* ((side (or (cdr (assq 'side alist)) 'bottom))
+         (slot (or (cdr (assq 'slot alist)) 0))
+         (left-or-right (memq side '(left right)))
+         ;; Softly dedicate window to BUFFER unless
+         ;; `display-buffer-mark-dedicated' already asks for it.
+         (dedicated (or display-buffer-mark-dedicated 'side)))
     (cond
      ((not (memq side '(top bottom left right)))
       (error "Invalid side %s specified" side))
@@ -940,12 +970,12 @@ display-buffer-in-side-window

       (cond
        ((and (numberp max-slots) (<= max-slots 0))
-	;; No side-slots available on this side.  Don't create an error,
+	;; No side-slots available on this side.  Don't raise an error,
 	;; just return nil.
 	nil)
        ((not windows)
-	;; No major window exists on this side, make one.
-	(display-buffer-in-major-side-window buffer side slot alist))
+	;; No major side window exists on this side, make one.
+	(window--make-major-side-window buffer side slot alist))
        (t
 	;; Scan windows on SIDE.
 	(catch 'found
@@ -983,46 +1013,69 @@ display-buffer-in-side-window
 	;; window will be created before it.
 	;; `best-window' is the window with the smallest absolute difference
 	;; of its slot and SLOT.
-
-	;; Note: We dedicate the window used softly to its buffer to
-	;; avoid that "other" (non-side) buffer display functions steal
-	;; it from us.  This must eventually become customizable via
-	;; ALIST (or, better, avoided in the "other" functions).
 	(or (and this-window
 		 ;; Reuse `this-window'.
-		 (window--display-buffer buffer this-window 'reuse alist 'side))
+                 (with-current-buffer buffer
+                   (setq window-sides-shown t))
+		 (window--display-buffer
+                  buffer this-window 'reuse alist dedicated))
 	    (and (or (not max-slots) (< slots max-slots))
 		 (or (and next-window
 			  ;; Make new window before `next-window'.
-			  (let ((next-side
-				 (if (memq side '(left right)) 'above 'left))
+			  (let ((next-side (if left-or-right 'above 'left))
 				(window-combination-resize 'side))
-			    (setq window (split-window next-window nil next-side))
-			    ;; When the new window is deleted, its space
-			    ;; is returned to other side windows.
-			    (set-window-parameter
-			     window 'delete-window 'delete-side-window)
-			    window))
+			    (setq window
+                                  (split-window next-window nil next-side))))
 		     (and prev-window
 			  ;; Make new window after `prev-window'.
-			  (let ((prev-side
-				 (if (memq side '(left right)) 'below 'right))
+			  (let ((prev-side (if left-or-right 'below 'right))
 				(window-combination-resize 'side))
-			    (setq window (split-window prev-window nil prev-side))
-			    ;; When the new window is deleted, its space
-			    ;; is returned to other side windows.
-			    (set-window-parameter
-			     window 'delete-window 'delete-side-window)
-			    window)))
+			    (setq window
+                                  (split-window prev-window nil prev-side)))))
 		   (set-window-parameter window 'window-slot slot)
-		   (window--display-buffer buffer window 'window alist 'side))
+                   (with-current-buffer buffer
+                     (setq window-sides-shown t))
+		   (window--display-buffer
+                    buffer window 'window alist dedicated))
 	    (and best-window
 		 ;; Reuse `best-window'.
 		 (progn
 		   ;; Give best-window the new slot value.
 		   (set-window-parameter best-window 'window-slot slot)
-		   (window--display-buffer
-		    buffer best-window 'reuse alist 'side)))))))))
+                   (with-current-buffer buffer
+                     (setq window-sides-shown t))
+                   (window--display-buffer
+		    buffer best-window 'reuse alist dedicated)))))))))
+
+(defun window-toggle-side-windows (&optional frame)
+  "Toggle side windows on specified FRAME.
+FRAME must be a live frame and defaults to the selected one.
+
+If FRAME has at least one side window, save FRAME's state in the
+FRAME's `window-state' frame parameter and delete all side
+windows on FRAME afterwards.  Otherwise, if FRAME has a
+`window-state' parameter, use that to restore any side windows on
+FRAME leaving FRAME's main window alone.  Signal an error if
+FRAME has no side window and no saved state is found."
+  (interactive)
+  (let* ((frame (window-normalize-frame frame))
+         state)
+    (cond
+     ((window-with-parameter 'window-side nil frame)
+      ;; At least one side window exists.  Remove all side windows after
+      ;; saving FRAME's state in its `window-state' parameter.
+      (set-frame-parameter
+       frame 'window-state (window-state-get (frame-root-window frame)))
+      (let ((ignore-window-parameters t))
+        (delete-other-windows (window-main-window frame))))
+     ((setq state (frame-parameter frame 'window-state))
+      ;; A window state was saved for FRAME.  Restore it and put the
+      ;; current root window into its main window.
+      (let ((main-state (window-state-get (frame-root-window frame))))
+        (window-state-put state (frame-root-window frame) t)
+        (window-state-put main-state (window-main-window frame))))
+     (t
+      (error "No side windows state found")))))

 (defun window--side-check (&optional frame)
   "Check the side window configuration of FRAME.
@@ -3224,8 +3277,10 @@ adjust-window-trailing-edge
 	(setq left first-left)
 	(while (and left
 		    (or (window-size-fixed-p left horizontal 'preserved)
-			(<= (window-size left horizontal t)
-			    (window-min-size left horizontal 'preserved t))))
+			(and (< delta 0)
+                             (<= (window-size left horizontal t)
+                                 (window-min-size
+                                  left horizontal 'preserved t)))))
 	  (setq left
 		(or (window-left left)
 		    (progn
@@ -3245,7 +3300,8 @@ adjust-window-trailing-edge
 		  (or (window-size-fixed-p right horizontal)
 		      (and (> delta 0)
 			   (<= (window-size right horizontal t)
-			       (window-min-size right horizontal 'preserved t)))))
+			       (window-min-size
+                                right horizontal 'preserved t)))))
 	(setq right
 	      (or (window-right right)
 		  (progn
@@ -3259,8 +3315,10 @@ adjust-window-trailing-edge
 	(setq right first-right)
 	(while (and right
 		    (or (window-size-fixed-p right horizontal 'preserved)
-                        (<= (window-size right horizontal t)
-                            (window-min-size right horizontal 'preserved t))))
+                        (and (> delta 0)
+                             (<= (window-size right horizontal t)
+                                 (window-min-size
+                                  right horizontal 'preserved t)))))
 	  (setq right
 		(or (window-right right)
 		    (progn
@@ -3289,8 +3347,9 @@ adjust-window-trailing-edge
 	  ;; Start resizing.
 	  (window--resize-reset frame horizontal)
 	  ;; Try to enlarge LEFT first.
-	  (setq this-delta (window--resizable
-			    left delta horizontal ignore 'after nil nil pixelwise))
+	  (setq this-delta
+                (window--resizable
+                 left delta horizontal ignore 'after nil nil pixelwise))
 	  (unless (zerop this-delta)
 	    (window--resize-this-window
 	     left this-delta horizontal ignore t 'before
@@ -3740,7 +3799,9 @@ one-window-p
 (defun window-deletable-p (&optional window)
   "Return t if WINDOW can be safely deleted from its frame.
 WINDOW must be a valid window and defaults to the selected one.
-Return `frame' if deleting WINDOW should also delete its frame."
+
+Return `frame' if WINDOW is the root window of its frame and that
+frame can be safely deleted."
   (setq window (window-normalize-window window))

   (unless (or ignore-window-parameters
@@ -3767,10 +3828,14 @@ window-deletable-p
 		  (let ((minibuf (active-minibuffer-window)))
 		    (and minibuf (eq frame (window-frame minibuf)))))
 	'frame))
+     ((window-minibuffer-p window)
+      ;; If WINDOW is the minibuffer window of a non-minibuffer-only
+      ;; frame, it cannot be deleted separately.
+      nil)
      ((or ignore-window-parameters
-	  (not (eq window (window--major-non-side-window frame))))
-      ;; WINDOW can be deleted unless it is the major non-side window of
-      ;; its frame.
+	  (not (eq window (window-main-window frame))))
+      ;; Otherwise, WINDOW can be deleted unless it is the main window
+      ;; of its frame.
       t))))

 (defun window--in-subtree-p (window root)
@@ -3826,11 +3891,14 @@ delete-window
 	  (throw 'done (delete-window atom-root))))
        ((not parent)
 	(error "Attempt to delete minibuffer or sole ordinary window"))
-       ((eq window (window--major-non-side-window frame))
-	(error "Attempt to delete last non-side window")))
+       ((eq window (window-main-window frame))
+	(error "Attempt to delete main window of frame %s" frame)))

       (let* ((horizontal (window-left-child parent))
 	     (size (window-size window horizontal t))
+             (window-combination-resize
+              (or window-combination-resize
+                  (window-parameter parent 'window-side)))
 	     (frame-selected
 	      (window--in-subtree-p (frame-selected-window frame) window))
 	     ;; Emacs 23 preferably gives WINDOW's space to its left
@@ -3886,8 +3954,7 @@ delete-other-windows
   (setq window (window-normalize-window window))
   (let* ((frame (window-frame window))
 	 (function (window-parameter window 'delete-other-windows))
-	 (window-side (window-parameter window 'window-side))
-	 atom-root side-main)
+	 atom-root main)
     (window--check frame)
     (catch 'done
       (cond
@@ -3905,18 +3972,48 @@ delete-other-windows
 	(if (eq atom-root (frame-root-window frame))
 	    (error "Root of atomic window is root window of its frame")
 	  (throw 'done (delete-other-windows atom-root))))
-       ((memq window-side window-sides)
+       ((window-parameter window 'window-side)
 	(error "Cannot make side window the only window"))
        ((and (window-minibuffer-p window)
 	     (not (eq window (frame-root-window window))))
 	(error "Can't expand minibuffer to full frame")))

-      ;; If WINDOW is the major non-side window, do nothing.
-      (if (window-with-parameter 'window-side)
-	  (setq side-main (window--major-non-side-window frame))
-	(setq side-main (frame-root-window frame)))
-      (unless (eq window side-main)
-	(delete-other-windows-internal window side-main)
+      (cond
+       ((or ignore-window-parameters
+            (not (window-with-parameter 'no-delete-other-window nil frame)))
+        (setq main (frame-root-window frame)))
+       ((catch 'tag
+          (walk-window-tree
+           (lambda (other)
+             (when (or (and (window-parameter other 'window-side)
+                            (not (window-parameter
+                                  other 'no-delete-other-window)))
+                       (and (not (window-parameter other 'window-side))
+                            (window-parameter
+                             other 'no-delete-other-window)))
+               (throw 'tag nil))))
+          t)
+        (setq main (window-main-window frame)))
+       (t
+        ;; Delete other windows via `delete-window' because either a
+        ;; side window is or a non-side-window is not deletable.
+        (dolist (other (window-list frame))
+          (when (and (window-live-p other)
+                     (not (eq other window))
+                     (not (window-parameter
+                           other 'no-delete-other-window))
+                     ;; When WINDOW and the other window are part of the
+                     ;; same atomic window, don't delete the other.
+                     (or (not atom-root)
+                         (not (eq (window-atom-root other) atom-root))))
+            (condition-case nil
+                (delete-window other)
+              (error nil))))
+        (throw 'done nil)))
+
+      ;; If WINDOW is the main window of its frame do nothing.
+      (unless (eq window main)
+	(delete-other-windows-internal window main)
 	(run-window-configuration-change-hook frame)
 	(window--check frame))
       ;; Always return nil.
@@ -4066,6 +4163,7 @@ switch-to-prev-buffer
   (interactive)
   (let* ((window (window-normalize-window window t))
 	 (frame (window-frame window))
+         (window-side (window-parameter window 'window-side))
 	 (old-buffer (window-buffer window))
 	 ;; Save this since it's destroyed by `set-window-buffer'.
 	 (next-buffers (window-next-buffers window))
@@ -4076,7 +4174,7 @@ switch-to-prev-buffer
       (unless (setq window (minibuffer-selected-window))
 	(error "Window %s is a minibuffer window" window)))

-    (when (window-dedicated-p window)
+    (unless (memq (window-dedicated-p window) '(nil side))
       ;; Don't switch in dedicated window.
       (error "Window %s is dedicated to buffer %s" window old-buffer))

@@ -4106,23 +4204,27 @@ switch-to-prev-buffer
       ;; buffer we don't reverse the global buffer list to avoid showing
       ;; a buried buffer instead.  Otherwise, we must reverse the global
       ;; buffer list in order to make sure that switching to the
-      ;; previous/next buffer traverse it in opposite directions.
-      (dolist (buffer (if bury-or-kill
-			  (buffer-list frame)
-			(nreverse (buffer-list frame))))
-	(when (and (buffer-live-p buffer)
-		   (not (eq buffer old-buffer))
-                   (or (null pred) (funcall pred buffer))
-		   (not (eq (aref (buffer-name buffer) 0) ?\s))
-		   (or bury-or-kill (not (memq buffer next-buffers))))
-	  (if (and (not switch-to-visible-buffer)
-		   (get-buffer-window buffer frame))
-	      ;; Try to avoid showing a buffer visible in some other window.
-	      (unless visible
-		(setq visible buffer))
-	    (setq new-buffer buffer)
-	    (set-window-buffer-start-and-point window new-buffer)
-	    (throw 'found t))))
+      ;; previous/next buffer traverse it in opposite directions.  Skip
+      ;; this step for side windows.
+      (unless window-side
+        (dolist (buffer (if bury-or-kill
+                            (buffer-list frame)
+                          (nreverse (buffer-list frame))))
+          (when (and (buffer-live-p buffer)
+                     (not (eq buffer old-buffer))
+                     (or (null pred) (funcall pred buffer))
+                     (not (eq (aref (buffer-name buffer) 0) ?\s))
+                     ;; Don't show a buffer shown in a side window before.
+                     (not (buffer-local-value 'window-sides-shown buffer))
+                     (or bury-or-kill (not (memq buffer next-buffers))))
+            (if (and (not switch-to-visible-buffer)
+                     (get-buffer-window buffer frame))
+                ;; Try to avoid showing a buffer visible in some other window.
+                (unless visible
+                  (setq visible buffer))
+              (setq new-buffer buffer)
+              (set-window-buffer-start-and-point window new-buffer)
+              (throw 'found t)))))
       (unless bury-or-kill
 	;; Scan reverted next buffers last (must not use nreverse
 	;; here!).
@@ -4184,6 +4286,7 @@ switch-to-next-buffer
   (interactive)
   (let* ((window (window-normalize-window window t))
 	 (frame (window-frame window))
+         (window-side (window-parameter window 'window-side))
 	 (old-buffer (window-buffer window))
 	 (next-buffers (window-next-buffers window))
          (pred (frame-parameter frame 'buffer-predicate))
@@ -4193,7 +4296,7 @@ switch-to-next-buffer
       (unless (setq window (minibuffer-selected-window))
 	(error "Window %s is a minibuffer window" window)))

-    (when (window-dedicated-p window)
+    (unless (memq (window-dedicated-p window) '(nil side))
       ;; Don't switch in dedicated window.
       (error "Window %s is dedicated to buffer %s" window old-buffer))

@@ -4211,20 +4314,23 @@ switch-to-next-buffer
 	   window new-buffer (nth 1 entry) (nth 2 entry))
 	  (throw 'found t)))
       ;; Scan the buffer list of WINDOW's frame next, skipping previous
-      ;; buffers entries.
-      (dolist (buffer (buffer-list frame))
-	(when (and (buffer-live-p buffer)
-		   (not (eq buffer old-buffer))
-                   (or (null pred) (funcall pred buffer))
-		   (not (eq (aref (buffer-name buffer) 0) ?\s))
-		   (not (assq buffer (window-prev-buffers window))))
-	  (if (and (not switch-to-visible-buffer)
-		   (get-buffer-window buffer frame))
-	      ;; Try to avoid showing a buffer visible in some other window.
-	      (setq visible buffer)
-	    (setq new-buffer buffer)
-	    (set-window-buffer-start-and-point window new-buffer)
-	    (throw 'found t))))
+      ;; buffers entries.  Skip this step for side windows.
+      (unless window-side
+        (dolist (buffer (buffer-list frame))
+          (when (and (buffer-live-p buffer)
+                     (not (eq buffer old-buffer))
+                     (or (null pred) (funcall pred buffer))
+                     (not (eq (aref (buffer-name buffer) 0) ?\s))
+                     ;; Don't show a buffer shown in a side window before.
+                     (not (buffer-local-value 'window-sides-shown buffer))
+                     (not (assq buffer (window-prev-buffers window))))
+            (if (and (not switch-to-visible-buffer)
+                     (get-buffer-window buffer frame))
+                ;; Try to avoid showing a buffer visible in some other window.
+                (setq visible buffer)
+              (setq new-buffer buffer)
+              (set-window-buffer-start-and-point window new-buffer)
+              (throw 'found t)))))
       ;; Scan WINDOW's reverted previous buffers last (must not use
       ;; nreverse here!)
       (dolist (entry (reverse (window-prev-buffers window)))
@@ -5286,12 +5392,17 @@ window--state-get-1
 		     (scroll-bars . ,(window-scroll-bars window))
 		     (vscroll . ,(window-vscroll window))
 		     (dedicated . ,(window-dedicated-p window))
-		     (point . ,(if writable point
-                                 (copy-marker point
-                                              (buffer-local-value
-                                               'window-point-insertion-type
-                                               buffer))))
-		     (start . ,(if writable start (copy-marker start)))))))))
+		     (point . ,(if writable
+                                   point
+                                 (with-current-buffer buffer
+                                   (copy-marker point
+                                                (buffer-local-value
+                                                 'window-point-insertion-type
+                                                 buffer)))))
+		     (start . ,(if writable
+                                   start
+                                 (with-current-buffer buffer
+                                   (copy-marker start))))))))))
 	 (tail
 	  (when (memq type '(vc hc))
 	    (let (list)
@@ -5363,7 +5474,8 @@ window--state-put-1
      ((memq type '(vc hc))
       (let* ((horizontal (eq type 'hc))
 	     (total (window-size window horizontal pixelwise))
-	     (first t)
+             (first t)
+             (window-combination-limit (cdr (assq 'combination-limit state)))
 	     size new)
 	(dolist (item state)
 	  ;; Find the next child window.  WINDOW always points to the
@@ -5406,12 +5518,9 @@ window--state-put-1
 				       (frame-char-height (window-frame window))
 				     1)))))
 	      (if (window-sizable-p window (- size) horizontal 'safe pixelwise)
-		  (let* ((window-combination-limit
-			  (assq 'combination-limit item)))
-		    ;; We must inherit the combination limit, otherwise
-		    ;; we might mess up handling of atomic and side
-		    ;; window.
-		    (setq new (split-window window size horizontal pixelwise)))
+                  (progn
+                    (setq new (split-window window size horizontal pixelwise))
+                    (setq window-combination-limit nil))
 		;; Give up if we can't resize window down to safe sizes.
 		(error "Cannot resize window %s" window))

@@ -5462,7 +5571,8 @@ window--state-put-2
 		   (nth 3 scroll-bars) (nth 5 scroll-bars)))
 		(set-window-vscroll window (cdr (assq 'vscroll state)))
 		;; Adjust vertically.
-		(if (memq window-size-fixed '(t height))
+		(if (or (memq window-size-fixed '(t height))
+                        (window-preserved-size window))
 		    ;; A fixed height window, try to restore the
 		    ;; original size.
 		    (let ((delta
@@ -5484,7 +5594,8 @@ window--state-put-2
 				window delta nil ignore nil nil nil pixelwise))
 		      (window-resize window delta nil ignore pixelwise))))
 		;; Adjust horizontally.
-		(if (memq window-size-fixed '(t width))
+		(if (or (memq window-size-fixed '(t width))
+                        (window-preserved-size window t))
 		    ;; A fixed width window, try to restore the original
 		    ;; size.
 		    (let ((delta
@@ -5494,8 +5605,8 @@ window--state-put-2
 			      (window-size window t pixelwise)))
 			  window-size-fixed)
 		      (when (window--resizable-p
-			     window delta nil nil nil nil nil pixelwise)
-			(window-resize window delta nil nil pixelwise)))
+			     window delta t nil nil nil nil pixelwise)
+			(window-resize window delta t nil pixelwise)))
 		  ;; Else check whether the window is not wide enough.
 		  (let* ((min-size (window-min-size window t ignore pixelwise))
 			 (delta (- min-size (window-size window t pixelwise))))
@@ -5540,16 +5651,14 @@ window-state-put
   ;; When WINDOW is internal, reduce it to a live one to put STATE into,
   ;; see Bug#16793.
   (unless (window-live-p window)
-    (let ((root (frame-root-window window)))
-      (if (eq window root)
-	  (setq window (frame-first-window root))
-	(setq root window)
-	(setq window (catch 'live
-		       (walk-window-subtree
-			(lambda (window)
-			  (when (window-live-p window)
-			    (throw 'live window)))
-			root))))
+    (let ((root window))
+      (setq window (catch 'live
+                     (walk-window-subtree
+                      (lambda (window)
+                        (when (and (window-live-p window)
+                                   (not (window-parameter window 'window-side)))
+                          (throw 'live window)))
+                      root)))
       (delete-other-windows-internal window root)))

   (set-window-dedicated-p window nil)
@@ -6314,15 +6423,15 @@ window--display-buffer
 	(set-window-dedicated-p window dedicated))
       (when (memq type '(window frame))
 	(set-window-prev-buffers window nil)))
-    (let ((parameter (window-parameter window 'quit-restore))
+    (let ((quit-restore (window-parameter window 'quit-restore))
 	  (height (cdr (assq 'window-height alist)))
 	  (width (cdr (assq 'window-width alist)))
 	  (size (cdr (assq 'window-size alist)))
 	  (preserve-size (cdr (assq 'preserve-size alist))))
       (cond
        ((or (eq type 'frame)
-	    (and (eq (car parameter) 'same)
-		 (eq (nth 1 parameter) 'frame)))
+	    (and (eq (car quit-restore) 'same)
+		 (eq (nth 1 quit-restore) 'frame)))
 	;; Adjust size of frame if asked for.
 	(cond
 	 ((not size))
@@ -6340,8 +6449,8 @@ window--display-buffer
 	 ((functionp size)
 	  (ignore-errors (funcall size window)))))
        ((or (eq type 'window)
-	    (and (eq (car parameter) 'same)
-		 (eq (nth 1 parameter) 'window)))
+	    (and (eq (car quit-restore) 'same)
+		 (eq (nth 1 quit-restore) 'window)))
 	;; Adjust height of window if asked for.
 	(cond
 	 ((not height))
@@ -6377,8 +6486,12 @@ window--display-buffer
 	;; Preserve window size if asked for.
 	(when (consp preserve-size)
 	  (window-preserve-size window t (car preserve-size))
-	  (window-preserve-size window nil (cdr preserve-size))))))
-
+	  (window-preserve-size window nil (cdr preserve-size)))))
+      ;; Assign any window parameters specified.
+      (let ((parameters (cdr (assq 'window-parameters alist))))
+        (dolist (parameter parameters)
+          (set-window-parameter
+           window (car parameter) (cdr parameter)))))
     window))

 (defun window--maybe-raise-frame (frame)
@@ -6602,6 +6715,9 @@ display-buffer
     preserve the width of the window, (nil . t) to preserve its
     height or (t . t) to preserve both.

+ `window-parameters' -- Value specifies an alist of window
+                        parameters to give the chosen window.
+
 The ACTION argument to `display-buffer' can also have a non-nil
 and non-list value.  This means to display the buffer in a window
 other than the selected one, even if it is already displayed in
@@ -6954,7 +7070,7 @@ display-buffer-at-bottom
 	(and (not (frame-parameter nil 'unsplittable))
 	     (setq window
 		   (condition-case nil
-		       (split-window (window--major-non-side-window))
+		       (split-window (window-main-window))
 		     (error nil)))
 	     (window--display-buffer
 	      buffer window 'window alist display-buffer-mark-dedicated))


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-22  9:07 martin rudalics
@ 2016-09-22 20:54 ` Juri Linkov
  2016-09-24 19:05   ` martin rudalics
  2016-09-23  8:38 ` Eli Zaretskii
  1 sibling, 1 reply; 27+ messages in thread
From: Juri Linkov @ 2016-09-22 20:54 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> The attached patch fixes some longstanding bugs/issues with side windows
> and provides the lacking documentation.  Comments welcome.

Thanks, this is a long-awaited feature.  Does this mean that now
are possible all these exciting things discussed in the past?
Like the tab bar?



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-22  9:07 martin rudalics
  2016-09-22 20:54 ` Juri Linkov
@ 2016-09-23  8:38 ` Eli Zaretskii
  2016-09-23  9:14   ` Eli Zaretskii
  2016-09-24 19:06   ` martin rudalics
  1 sibling, 2 replies; 27+ messages in thread
From: Eli Zaretskii @ 2016-09-23  8:38 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Thu, 22 Sep 2016 11:07:24 +0200
> From: martin rudalics <rudalics@gmx.at>
> 
> The attached patch fixes some longstanding bugs/issues with side windows
> and provides the lacking documentation.  Comments welcome.

Thanks a lot for working on this!

This will need a NEWS entry.

A question: would it make sense to invert the meaning of the 'slot'
parameter when the main window shows a buffer whose
bidi-paragraph-direction is right-to-left?  The idea is that when the
main window shows R2L text, the entire geometry of the window
arrangement should switch direction, at least optionally, otherwise
applications that want that will have to include tedious code to
recompute the slots on the fly.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-23  8:38 ` Eli Zaretskii
@ 2016-09-23  9:14   ` Eli Zaretskii
  2016-09-24 19:06   ` martin rudalics
  1 sibling, 0 replies; 27+ messages in thread
From: Eli Zaretskii @ 2016-09-23  9:14 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel

> Date: Fri, 23 Sep 2016 11:38:30 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: emacs-devel@gnu.org
> 
> A question: would it make sense to invert the meaning of the 'slot'
> parameter when the main window shows a buffer whose
> bidi-paragraph-direction is right-to-left?

To clarify: I meant this only for the horizontal slot numbers, of
course, not the vertical slot numbers.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-22 20:54 ` Juri Linkov
@ 2016-09-24 19:05   ` martin rudalics
  0 siblings, 0 replies; 27+ messages in thread
From: martin rudalics @ 2016-09-24 19:05 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

 > Thanks, this is a long-awaited feature.  Does this mean that now
 > are possible all these exciting things discussed in the past?
 > Like the tab bar?

I hope so.  You will notice that in my example I display *Buffer List*
in the top window which is silly.  That's obviously the place reserved
for your tab bar ;-)

martin



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-23  8:38 ` Eli Zaretskii
  2016-09-23  9:14   ` Eli Zaretskii
@ 2016-09-24 19:06   ` martin rudalics
  2016-09-24 19:27     ` Eli Zaretskii
  1 sibling, 1 reply; 27+ messages in thread
From: martin rudalics @ 2016-09-24 19:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 > A question: would it make sense to invert the meaning of the 'slot'
 > parameter when the main window shows a buffer whose
 > bidi-paragraph-direction is right-to-left?  The idea is that when the
 > main window shows R2L text, the entire geometry of the window
 > arrangement should switch direction, at least optionally, otherwise
 > applications that want that will have to include tedious code to
 > recompute the slots on the fly.

Suppose the main window shows a left-to-right buffer and we have two
bottom side windows.  Switching to a right-to-left buffer in the main
window would now mean to exchange the buffers shown in the side windows.
We would also have to renumber these windows, resize them maybe,
exchange their parameters and some of those properties stored in window
configurations.  And we would have to adjust all overlays with a
`window' property in those windows.  It's certainly possible to do all
that but it's not entirely trivial.

Personally, I think that such layout decisions should be made before the
first side window is created.  I doubt that you change the menubar
layout whenever you switch `bidi-paragraph-direction'.  So some variable
‘bidi-default-direction’ would be much simpler to handle (with the
obvious deficiency that you can't change the layout on-the-fly when you
set that variable).  But in practice I never work with bidirectional
text so I can't really tell.

martin




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-24 19:06   ` martin rudalics
@ 2016-09-24 19:27     ` Eli Zaretskii
  2016-10-05  8:39       ` martin rudalics
  0 siblings, 1 reply; 27+ messages in thread
From: Eli Zaretskii @ 2016-09-24 19:27 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Sat, 24 Sep 2016 21:06:07 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  > A question: would it make sense to invert the meaning of the 'slot'
>  > parameter when the main window shows a buffer whose
>  > bidi-paragraph-direction is right-to-left?  The idea is that when the
>  > main window shows R2L text, the entire geometry of the window
>  > arrangement should switch direction, at least optionally, otherwise
>  > applications that want that will have to include tedious code to
>  > recompute the slots on the fly.
> 
> Suppose the main window shows a left-to-right buffer and we have two
> bottom side windows.  Switching to a right-to-left buffer in the main
> window would now mean to exchange the buffers shown in the side windows.
> We would also have to renumber these windows, resize them maybe,
> exchange their parameters and some of those properties stored in window
> configurations.  And we would have to adjust all overlays with a
> `window' property in those windows.  It's certainly possible to do all
> that but it's not entirely trivial.

What's the alternative? that the application programmer does all that
in their application code?  What are the chances of them getting this
right?

> Personally, I think that such layout decisions should be made before the
> first side window is created.

That might be impossible in the general case, because the same window
arrangement could be used for displaying buffers of different
directions.  One example is an email client that shows messages in the
main window.

> I doubt that you change the menubar layout whenever you switch
> `bidi-paragraph-direction'.

Some applications out there actually do that.  Emacs doesn't, but only
because I deliberately decided it wasn't TRT (there's a FIXME comment
about that in the sources).  Menu bars are different, because they are
not really associated with any particular window, they are associated
with a frame.

> But in practice I never work with bidirectional text so I can't
> really tell.

I think we should at least allow for such a behavior as an option.

Thanks.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-09-24 19:27     ` Eli Zaretskii
@ 2016-10-05  8:39       ` martin rudalics
  2016-10-05 10:35         ` Eli Zaretskii
  2016-10-05 13:13         ` Eli Zaretskii
  0 siblings, 2 replies; 27+ messages in thread
From: martin rudalics @ 2016-10-05  8:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 >> Personally, I think that such layout decisions should be made before the
 >> first side window is created.
 >
 > That might be impossible in the general case, because the same window
 > arrangement could be used for displaying buffers of different
 > directions.  One example is an email client that shows messages in the
 > main window.

I now committed my changes.  The option to change the direction of side
windows is called `window-sides-reversed' and allows to change the
direction permanently or have it depend on the frame's main window.

 >> I doubt that you change the menubar layout whenever you switch
 >> `bidi-paragraph-direction'.
 >
 > Some applications out there actually do that.  Emacs doesn't, but only
 > because I deliberately decided it wasn't TRT (there's a FIXME comment
 > about that in the sources).  Menu bars are different, because they are
 > not really associated with any particular window, they are associated
 > with a frame.

Well, the situation with side windows is not that much different.  You
could change the menubar layout whenever the selected (non-minibuffer)
window or all windows on a frame show right-to-left text.

 > I think we should at least allow for such a behavior as an option.

Please test the new option.  As a side effect I also added a completely
new command ‘window-swap-states’ which could be of general use.

martin




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
@ 2016-10-05 10:25 Angelo Graziosi
  0 siblings, 0 replies; 27+ messages in thread
From: Angelo Graziosi @ 2016-10-05 10:25 UTC (permalink / raw)
  To: rudalics, Emacs developers

Martin Rudalics wrote:
> I now committed my changes.

Leaving aside your commit, where can one find the documentation about 
this? Ho to use and so on. One needs some practical examples, adding 
this and this to the init file you will get this, adding this, instead, 
you will get this etc..

   Angelo



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
@ 2016-10-05 10:26 Angelo Graziosi
  2016-10-05 10:51 ` Eli Zaretskii
  0 siblings, 1 reply; 27+ messages in thread
From: Angelo Graziosi @ 2016-10-05 10:26 UTC (permalink / raw)
  To: rudalics, Emacs developers

Martin Rudalics wrote:
> I now committed my changes.

Leaving aside your commit, where can one find the documentation about 
this? Ho to use and so on. One needs some practical examples, adding 
this and this to the init file you will get this, adding this, instead, 
you will get this etc..

   Angelo



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05  8:39       ` martin rudalics
@ 2016-10-05 10:35         ` Eli Zaretskii
  2016-10-05 13:13         ` Eli Zaretskii
  1 sibling, 0 replies; 27+ messages in thread
From: Eli Zaretskii @ 2016-10-05 10:35 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Wed, 05 Oct 2016 10:39:38 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  >> Personally, I think that such layout decisions should be made before the
>  >> first side window is created.
>  >
>  > That might be impossible in the general case, because the same window
>  > arrangement could be used for displaying buffers of different
>  > directions.  One example is an email client that shows messages in the
>  > main window.
> 
> I now committed my changes.  The option to change the direction of side
> windows is called `window-sides-reversed' and allows to change the
> direction permanently or have it depend on the frame's main window.

Thank you!

>  >> I doubt that you change the menubar layout whenever you switch
>  >> `bidi-paragraph-direction'.
>  >
>  > Some applications out there actually do that.  Emacs doesn't, but only
>  > because I deliberately decided it wasn't TRT (there's a FIXME comment
>  > about that in the sources).  Menu bars are different, because they are
>  > not really associated with any particular window, they are associated
>  > with a frame.
> 
> Well, the situation with side windows is not that much different.

It could be similar or different, depending on the application.

> You could change the menubar layout whenever the selected
> (non-minibuffer) window or all windows on a frame show right-to-left
> text.

That causes an annoying direction switches.

When I worked on bidi, I decided to postpone changing the
directionality of the menu bar and tool bar until such time as we have
infrastructure to display their labels in languages other than
English.  IMO, having the menu/tool bar displayed R2L only makes sense
when the labels are in R2L script.

>  > I think we should at least allow for such a behavior as an option.
> 
> Please test the new option.  As a side effect I also added a completely
> new command ‘window-swap-states’ which could be of general use.

Thanks, I will, but it might take some time until I get to that.  Too
many things on my plate right now.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05 10:26 Side Windows Angelo Graziosi
@ 2016-10-05 10:51 ` Eli Zaretskii
  2016-10-05 11:01   ` Angelo Graziosi
  0 siblings, 1 reply; 27+ messages in thread
From: Eli Zaretskii @ 2016-10-05 10:51 UTC (permalink / raw)
  To: Angelo Graziosi; +Cc: rudalics, emacs-devel

> From: Angelo Graziosi <angelo.graziosi@alice.it>
> Date: Wed, 5 Oct 2016 12:26:53 +0200
> 
> Martin Rudalics wrote:
> > I now committed my changes.
> 
> Leaving aside your commit, where can one find the documentation about 
> this? Ho to use and so on. One needs some practical examples, adding 
> this and this to the init file you will get this, adding this, instead, 
> you will get this etc..

Martin's commit includes changes to the manuals.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05 10:51 ` Eli Zaretskii
@ 2016-10-05 11:01   ` Angelo Graziosi
  2016-10-05 11:24     ` Kaushal Modi
  2016-10-05 13:03     ` Eli Zaretskii
  0 siblings, 2 replies; 27+ messages in thread
From: Angelo Graziosi @ 2016-10-05 11:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, emacs-devel



Il 05/10/2016 12:51, Eli Zaretskii ha scritto:
>> From: Angelo Graziosi <angelo.graziosi@alice.it>
>> Date: Wed, 5 Oct 2016 12:26:53 +0200
>>
>> Martin Rudalics wrote:
>>> I now committed my changes.
>>
>> Leaving aside your commit, where can one find the documentation about
>> this? Ho to use and so on. One needs some practical examples, adding
>> this and this to the init file you will get this, adding this, instead,
>> you will get this etc..
>
> Martin's commit includes changes to the manuals.
>

Yes, I understood this.. but where I read manuals? I tried this 
https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html 
but, apparently, I didn't find topics related to this new adding..



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05 11:01   ` Angelo Graziosi
@ 2016-10-05 11:24     ` Kaushal Modi
  2016-10-05 13:03     ` Eli Zaretskii
  1 sibling, 0 replies; 27+ messages in thread
From: Kaushal Modi @ 2016-10-05 11:24 UTC (permalink / raw)
  To: Angelo Graziosi, Eli Zaretskii; +Cc: martin rudalics, Emacs developers

[-- Attachment #1: Type: text/plain, Size: 663 bytes --]

On Wed, Oct 5, 2016, 7:02 AM Angelo Graziosi <angelo.graziosi@alice.it>
wrote:

>
> Yes, I understood this.. but where I read manuals? I tried this
> https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html
> but, apparently, I didn't find topics related to this new adding..
>

The gnu.org shows the manual only for the latest released emacs version.

For checking out the emacs/elisp manual updates made to the master branch
and emacs-25 branch (not yet released part), you just build emacs normally
as you would do, and access the manuals from within emacs using M-x info or
"C-h i".

Do "C-h i h" to learn how to use M-x info.

> --

Kaushal Modi

[-- Attachment #2: Type: text/html, Size: 1480 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05 11:01   ` Angelo Graziosi
  2016-10-05 11:24     ` Kaushal Modi
@ 2016-10-05 13:03     ` Eli Zaretskii
  1 sibling, 0 replies; 27+ messages in thread
From: Eli Zaretskii @ 2016-10-05 13:03 UTC (permalink / raw)
  To: Angelo Graziosi; +Cc: rudalics, emacs-devel

> Cc: rudalics@gmx.at, emacs-devel@gnu.org
> From: Angelo Graziosi <angelo.graziosi@alice.it>
> Date: Wed, 5 Oct 2016 13:01:50 +0200
> 
> > Martin's commit includes changes to the manuals.
> >
> 
> Yes, I understood this.. but where I read manuals? I tried this 
> https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html 
> but, apparently, I didn't find topics related to this new adding..

When you build the master branch, the build generates the manuals in
Info format, which you can read with "C-u C-h i".



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05  8:39       ` martin rudalics
  2016-10-05 10:35         ` Eli Zaretskii
@ 2016-10-05 13:13         ` Eli Zaretskii
  2016-10-05 14:20           ` martin rudalics
  1 sibling, 1 reply; 27+ messages in thread
From: Eli Zaretskii @ 2016-10-05 13:13 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Wed, 05 Oct 2016 10:39:38 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
> I now committed my changes.

One comment on the documentation you wrote is that you never say what
is the "normal" return value of display-buffer-in-side-window.  The
documentation does tell that it returns nil in some exceptional cases,
but without knowing the "normal" value, that detail is less helpful.

Can you add that?  I think it should be both in the doc string and in
the manual.

Thanks.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Side Windows
  2016-10-05 13:13         ` Eli Zaretskii
@ 2016-10-05 14:20           ` martin rudalics
  0 siblings, 0 replies; 27+ messages in thread
From: martin rudalics @ 2016-10-05 14:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 > One comment on the documentation you wrote is that you never say what
 > is the "normal" return value of display-buffer-in-side-window.  The
 > documentation does tell that it returns nil in some exceptional cases,
 > but without knowing the "normal" value, that detail is less helpful.
 >
 > Can you add that?  I think it should be both in the doc string and in
 > the manual.

Done.  And thanks for the doc fixes.

martin



^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2016-10-05 14:20 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-05 10:26 Side Windows Angelo Graziosi
2016-10-05 10:51 ` Eli Zaretskii
2016-10-05 11:01   ` Angelo Graziosi
2016-10-05 11:24     ` Kaushal Modi
2016-10-05 13:03     ` Eli Zaretskii
  -- strict thread matches above, loose matches on Subject: below --
2016-10-05 10:25 Angelo Graziosi
2016-09-22  9:07 martin rudalics
2016-09-22 20:54 ` Juri Linkov
2016-09-24 19:05   ` martin rudalics
2016-09-23  8:38 ` Eli Zaretskii
2016-09-23  9:14   ` Eli Zaretskii
2016-09-24 19:06   ` martin rudalics
2016-09-24 19:27     ` Eli Zaretskii
2016-10-05  8:39       ` martin rudalics
2016-10-05 10:35         ` Eli Zaretskii
2016-10-05 13:13         ` Eli Zaretskii
2016-10-05 14:20           ` martin rudalics
2010-04-13 19:53 Gtk tabs in emacs, new branch grischka
2010-04-13 23:31 ` Side windows (was: Gtk tabs in emacs, new branch.) Juri Linkov
2010-04-14  3:18   ` Eli Zaretskii
2010-04-14 15:24     ` Side windows Jason Rumney
2010-04-14 16:52       ` Juri Linkov
2010-04-14 18:19         ` Eli Zaretskii
2010-04-14 23:54           ` Juri Linkov
2010-04-15  3:18             ` Eli Zaretskii
2010-04-15 23:46               ` Juri Linkov
2010-04-16  6:33                 ` Eli Zaretskii
2010-04-14  5:15   ` Jan Djärv
2010-04-16 14:03   ` grischka
2010-04-16 20:48     ` Juri Linkov

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.