Get width of current monitor in Emacs Lisp - emacs

I have a two-monitor setup (running Ubuntu).
The Emacs Lisp function display-pixel-width gives me the combined width of the two monitors. How can I get the width of the current monitor (i.e., the monitor displaying the current frame)?

If you are using 24.3 or earlier:
display-pixel-width is a compiled Lisp function in `frame.el'.
(display-pixel-width &optional DISPLAY)
Return the width of DISPLAY's screen in pixels. For character
terminals, each character counts as a single pixel.
Additionally, if you are using 24.4 or later:
** Multi-monitor support has been added.
*** New functions display-monitor-attributes-list and frame-monitor-attributes
can be used to obtain information about
each physical monitor on multi-monitor setups.
Use an external process
You can also parse the output of xwininfo or xrandr (use call-process).
Maximize emacs
Finally, you can maximize emacs (either interactively or using modify-frame-parameters; version 24.4 also has toggle-frame-fullscreen and toggle-frame-maximized) and query its frame size using frame-pixel-height and frame-pixel-width.
See also
How do I find the display size of my system in Emacs?
Can I detect the display size/resolution in Emacs?

display-pixel-width takes an argument to let you specify the display. From its documentation (C-h f display-pixel-width RET):
(display-pixel-width &optional DISPLAY)
Return the width of DISPLAY's screen in pixels. For character
terminals, each character counts as a single pixel.
There's also the similar x-display-pixel-width, which may work if the above doesn't.

Related

Resizing EchoArea of Emacsclient

I am facing a strange problem. After I change the KDE window rules for emacs according to http://www.emacswiki.org/emacs/KdeMaximized, that is, I created a special window setting:
the size of echoarea (the area shared with minibuffer) is doubled by default whenever the font size is larger than 115 (1/10 pt):
,
while normally it should be like this:
Moreover, this only occurs when emacsclient is maximized and without menubar (it is fine when fullscreened or not maximized or with menubar). Maybe it is just a problem with KDE? But I couldn't find other way to fully maximize KDE without creating special window settings.
Surely a workaround is to set font size to be at most 115, but that looks too small on my 13.3 ultrabook and I usually set it to 125.
So I am just wondering if there is a way to resize the EchoArea (or change the font size of EchoArea.) by emacs settings? I tried adjusting the font size of the minibuffer, but it does not work since only the minibuffer font is changed while the Echoarea is not affected.
I am using emacs 24.3.
Thanks!
Explanation
Emacs cannot fully use arbitrary screen sizes because it (for the most part) displays a grid of characters.
As a simple example, consider characters that are each 10 by 10 pixels, and screen real estate of 1024 by 768. You'll have four pixels of width and eight pixels of height that cannot be used by Emacs.
The article you linked to is about forcing Emacs into a particular screen size. From the page:
Once you try to maximize the window, emacs resizes itself to a slightly smaller portion of the screen. This is because emacs rejects the geometry given to it by KWin, because it’s not an integral multiple of the width/height of one character.
When you tell KDE to force a particular size, the Emacs frame ("window" in non-Emacs terminology) will be the size you want, but the windows inside it ("splits" in non-Emacs terminology) may not fit properly. This usually leads to "wasted space" at the bottom of the screen like you are seeing.
As you noticed, changing your font size can give different results. If your character width is 8 pixels, for instance, you won't have any wasted horizontal space since 1024 divides by 8 evenly (128 times).
Similarly, going fullscreen and enabling the menubar both alter the amount of vertical space that Emacs has available for its windows.
Workaround
One workaround might be to adjust the size of your KDE taskbar. I believe it can be adjusted with single pixel granularity. If you adjust it smaller by a few pixels one at a time you should find a small adjustment that will make Emacs use its space more efficiently.
A you suggested, you might try to alter the font size of the minibuffer:
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup)
(defun my-minibuffer-setup ()
(set (make-local-variable 'face-remapping-alist)
'((default :height 0.9))))
(via Altering the font size for the Emacs minibuffer separately from default emacs?)
This will make the font size just a bit smaller. Try playing with the height and see if it can resolve the issue...

How to determine the visible buffer width in characters

I'm using a custom modeline and I'm starting to get how to configure it but here I'm stuck as to how to get the info I want: I'd like to show, in each buffer's modeline, the width in characters of the buffer.
I'm also using linum-mode (with always at least two columns used) and ideally I'd like to deduce the number of characters used by linum from the width.
The function (window-width) is what you're looking for, this doesn't include the characters used by linum-mode however you can get their width from (window-margins)

emacs windows, distribute the width through the frame

I used once a very nice emacs function that set all my windows (emacs windows, not frames) width evenly.
If you open emacs and do C-x 3 twice in a row, you get three vertical windows. Then running the function I am looking for makes the width of these windows the same.
I can't for the life of me find this function again.
Wouldn't someone help me to:
find the name of the function
give me the keyboard shortcut if any
tell me what I should have done to find the answer by myself
Thanks!
You're looking for M-x balance-windows.

Horizontal split for pop-to-buffer in Emacs 23?

I have a few scripts that use the function pop-to-buffer a lot. It used to split the window horizontally, but now in Emacs 23 it splits the window vertically. I've dug through some of the elisp code but it's not jumping out at me - how can I change this behavior of Emacs 23 to split horizontally again?
It's listed in the NEWS for Emacs (C-h N):
*** display-buffer' tries to be smarter when splitting windows. The
new option
split-window-preferred-function' lets
you specify your own function to pop
up new windows. Its default value
split-window-sensibly' can split a
window either vertically or
horizontally, whichever seems more
suitable in the current configuration.
You can tune the behavior of
split-window-sensibly by customizing
split-height-threshold' and the new
option `split-width-threshold'. Both
options now take the value nil to
inhibit splitting in one direction.
Setting split-width-threshold to nil
inhibits horizontal splitting and gets
you the behavior of Emacs 22 in this
respect. In any case, display-buffer
may now split the largest window
vertically even when it is not as wide
as the containing frame.
I think what you want is:
(setq split-width-threshold nil)
(but I think you're using the vertical versus horizontal splitting the opposite of what Emacs terminology is (which is counterintuitive to me as well))

Maximizing an Emacs frame to just one monitor with elisp

I use maxframe.el to maximize my Emacs frames.
It works great on all three major platforms, except on my dual-head Mac setup (Macbook Pro 15-inch laptop with 23-inch monitor).
When maximizing an Emacs frame, the frame expands to fill the width of both monitors and the height of the larger monitor.
Obviously, I would like the frame to maximize to fill only the monitor it's on. How can I detect the resolutions of the two individual monitors using elisp?
Thanks,
Jacob
EDIT: As Denis points out, setting mf-max-width is a reasonable workaround. But (as I should have mentioned) I was hoping for a solution that works on both monitors and with any resolution. Maybe something OSX-specific in the style of the Windows-specific w32-send-sys-command.
I quickly scanned the reference that you provided to maxframe.el and I don't think that you're using the same technique that I use. Does the following code snippet help you?
(defun toggle-fullscreen ()
"toggles whether the currently selected frame consumes the entire display or is decorated with a window border"
(interactive)
(let ((f (selected-frame)))
(modify-frame-parameters f `((fullscreen . ,(if (eq nil (frame-parameter f 'fullscreen)) 'fullboth nil))))))
Does customising `mf-max-width' work? Its documentation:
"*The maximum display width to support. This helps better support the true
nature of display-pixel-width. Since multiple monitors will result in a
very large display pixel width, this value is used to set the stop point for
maximizing the frame. This could also be used to set a fixed frame size
without going over the display dimensions."
This sort of thing is the job of your window manager, not the job of emacs. (For example, Xmonad handles full-screen emacs just fine.)