Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use X Windows with Emacs on Windows 10 Bash?

Tags:

I am using the Bash on Ubuntu on Windows program to use Emacs for C++. Right now, I can code everything using the keyboard shortcuts, however, I want to select text with my mouse or set the mark with my mouse instead of always having to use my keyboard.

To get the X Windows System, I already did sudo apt-get install xserver -xorg but emacs still runs in a terminal editor.

I don't know what other commands to use or how to get X Windows to start running.

like image 932
novice Avatar asked Aug 27 '16 14:08

novice


2 Answers

Windows bash does not support X Server. However, using a Windows X Server port such as MobaXTerm, XMing or vcXsrv in conjunction with Windows bash works. Some things work out of the box (gvim did,) emacs requires more effort.

Here's how I've made it work:

  • Install MobaXterm. Most probably you can make it work with XMing as well, but I have tested only with MobaXterm. Update: Tested with vcXsrv and XMing (paid version.) Works essentially the same, I will probably stick with MobaXTerm.

  • Install emacs 25.1 snapshot. The reason: Ubuntu 14.04 comes with emacs 24.3, which doesn't work with Windows bash and MobaXTerm X server (no idea why, and it's too old anyway.)

Install the snapshot using the following commands:

sudo add-apt-repository ppa:ubuntu-elisp/ppa
sudo apt-get update
sudo apt-get install emacs-snapshot

Then run

sudo update-alternatives --config emacs

and select emacs-snapshot

Make sure you set the DISPLAY

export DISPLAY=localhost:0.0

Run MobaXTerm (you don't need anything to do in it, just start it - it will start X Server when needed.)

Run emacs in bash and enjoy.

One problem remains, and it persists across all three packages I've tested (MobaXTerm, XMing and vcXsrv). Emacs sticks to the initial frame size, and doesn't resize its frame when the window is resized. Same problem with the menu bar - when menu bar is disabled, emacs doesn't reclaim its space, it remains as a grey rectangle. This problem seems to be peculiar to emacs on Windows bash - gvim and other GUI programs seem to work fine. Also, running emacs 25.1 on Linux using any X Server on Windows works fine. I have tried to build emacs with different GUI settings (GTK 2.0 etc.) but emacs make on Windows bash gets stuck. If I find a workaround for this I will post an update.

Update 09/24/2017 According to Jarett the following in your init.el should fix the frame resizing problem:

(setq frame-resize-pixelwise t)

I don't have Windows with bash active anymore, so I can't test it.

like image 137
Yuri Steinschreiber Avatar answered Oct 19 '22 07:10

Yuri Steinschreiber


Thanks for @Yuri's nice answer, it works! After some further try&errors I found a way to fix the white border issue. You will need to rebuild from Emacs v24.5 source code (I tried some v25 versions in the git repository but all failed, if you are using git repository, checkout tag "emacs-24.5-rc3"). During the configuration stage, you will need to choose "lucid" (or "athena", same thing) x-toolkit instead of the current "gtk3". Notice that the "motif" has the same problem.

First, download Emacs source code and install "libxaw7-dev" package. The "libncurses5-dev" is just in case you don't have it. Assume we do everything in the directory ~/build-emacs24:

mkdir ~/build-emacs24
cd ~/build-emacs24
wget https://ftp.gnu.org/gnu/emacs/emacs-24.5.tar.xz
sudo apt-get install libxaw7-dev libncurses5-dev
tar xvf emacs-24.5.tar.xz

Now we have "emacs-24.5" directory extracted. In order to prevent the D-BUS issue reported elsewhere let's configure without it, and installed it in /usr/local/bin (by default):

cd emacs-24.5
./configure --without-dbus --without-gconf --without-gsettings --with-x-toolkit=athena 

Now, we are almost ready to build Emacs. But before that, we need to tweak the kernel a bit or the build will soon fail. (Let's skip the details, if you are interested, it's explained in the "etc/PROBLEMS" in your emacs source code.) You only need this during the build stage. Once your new emacs installed you don't need to do this again.

sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"

Now let's go into the long build process, you might experience an overall system slowdown during the build, you can reduce the number of threads used in the build (here I use "4" for a 2 cores 4-threads Intel CPU, don't use a number larger than supported threads (cat /proc/cpuinfo) or it will become even slower.)

time nice make -j 4

Takes only a few minutes? More to come, now install it (remember the "sudo" here):

sudo make install 

The whole build and install takes less than 10 minutes on my machine, not too bad. Now we have a working Emacs 24.5 located at "/usr/local/bin/emacs". If you have everything setup as @Yuri's answer, you should be able to launch it now:

/usr/local/bin/emacs &

Now you can maximize it and do things you want. Here is a screen shot, noticed the upper right corner, it's maximized:

enter image description here

Don't worry about the colors, it's my own theme selection.

There is still one more problem. Let's again workaround it. Sometimes you selected a menu item and the "white border" attacks again!

enter image description here

It's now smaller but still annoying.

enter image description here

Fortunately this time we can let it go away. Maximize/restore the window and it will go away. After a few rounds it sometimes stop happening again, but not always. This is still annoying. Since resizing the window can fix this issue, why don't we make it automatic? Maybe a not-too-bad workaround?

Now edit your "~/.emacs" file and add the following code (: use your new Emacs, of course ;) :

(defvar fix-frame-white-border-last-check 0)

(defun current-sec ()
  (let ((currtime (current-time)))
    (logior (lsh (car currtime) 16) (cadr currtime))))

(defun fix-frame-white-border-uow (&optional frame)
  (when (> (- (current-sec) fix-frame-white-border-last-check) 2)
    (setf frame (or frame (selected-frame)))
    (let ((width  (frame-width frame))
          (height (frame-height frame)))
      (set-frame-size frame (1- width) height)
      (set-frame-size frame width height))
    (setq fix-frame-white-border-last-check (current-sec))))

(advice-add 'menu-bar-open :after #'fix-frame-white-border-uow)
(add-hook 'menu-bar-update-hook #'fix-frame-white-border-uow)

The code is not perfect, but it works. It will resize your frame a bit and restore it right away when you use the menu. It also prevent itself from frequent resizing.

like image 38
Luke Lee Avatar answered Oct 19 '22 07:10

Luke Lee