GUI Emacs全屏不覆盖整个屏幕

时间:2013-05-26 07:27:36

标签: emacs fullscreen

我也遇到过这样的讨论:http://www.reddit.com/r/emacs/comments/15gd16/osx_a_window_sizing_problem/但我现在在Windows上(GUI Emacs在Gnome或KDE中运行时没有这种行为)。

问题在于Emacs'窗口不会填满整个屏幕。我尝试了不同的字体,但无法找到一个好的组合(实际上,我试过的那些都没有填满整个屏幕)。所以,我在想......也许,有没有人想出一个解决方案呢?当另一个程序的一些随机位出现在迷你缓冲区之下时,它看起来很邋。。

2 个答案:

答案 0 :(得分:4)

更新2015 :Emacs 24.4包含使用toggle-frame-fullscreen对Windows的真正全屏支持。您可以使用GNU版本的Windows而不进行任何修改(或者,可能是任何其他版本)。


问题是GUI以整个字符调整窗口大小。这只是Windows上的一个问题,因为您没有转换为原生全屏的frame-parameter,因此必须通过调整大小和定位来完成全屏模式。

您需要EmacsW32修补版本。

从此download page获取最新的安装程序(目前为Emacs-24-BzrP110217-EmacsW32-1.58.exe)。

这与emacs-fullscreen-w32之类的内容(使用Windows API删除标题栏)一起使用,将为您提供真正的全屏。

相信我,没有其他方式可以摆脱Windows上的差距。

就我个人而言,我不喜欢在我的.emacs回购中围绕某人的EXE,因此我使用以下C#程序(我从this bitbucket project获得):

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace toggleTitle
{
    class Program
    {
        // Constants from WinUser.h
        const int GWL_STYLE = -16;
        const int GWL_EXSTYLE = -20;

        const int SW_MAXIMIZE = 3;

        const uint WS_CAPTION = 0x00C00000;
        const uint WS_BORDER = 0x00800000;
        const uint WS_SIZEBOX = 0x000040000;

        // Imports from user32.dll
        [DllImport("User32", CharSet = CharSet.Auto)]
        private static extern int SetWindowLong(IntPtr hWnd, int Index, int Value);

        [DllImport("User32", CharSet = CharSet.Auto)]
        private static extern int GetWindowLong(IntPtr hWnd, int Index);

        [DllImport("user32.dll")]
        private static extern int ShowWindow(int hwnd, int command);


        // -- main functions
        static int GetWindowStyle(int hwnd) {
            return GetWindowLong(new IntPtr(hwnd), GWL_STYLE);
        }

        static void ToggleWindowCaption(int hwnd) {
        IntPtr intPtrHWND = new IntPtr(hwnd);
            int currentStyle = GetWindowStyle(hwnd);
            int newStyle = currentStyle ^ (int) WS_CAPTION;
            newStyle = newStyle ^ (int)WS_BORDER;
            newStyle = newStyle ^ (int)WS_SIZEBOX;
            SetWindowLong(intPtrHWND, GWL_STYLE, newStyle);
            WinApi.SetWinFullScreen(intPtrHWND);
            //ShowWindow(hwnd, SW_MAXIMIZE);
        }

        static List<Process> FindWindows(Regex regexpToMatch) {
            List<Process> results = new List<Process>();
            foreach (Process win in Process.GetProcesses()) {
                if (regexpToMatch.IsMatch(win.MainWindowTitle)) {
                    results.Add(win);
                }
            }
            return results;
        }

        static void Main(string[] args) {
            System.Console.WriteLine("== toggle windows ==");
            if (args.Length < 1) {
                Console.WriteLine("Usage: togglecaption <hwnd>");
                return;
            }
            int windowHwnd = Int32.Parse(args[0]);

            foreach (Process proc in Process.GetProcesses()) {
                if (proc.MainWindowHandle == new IntPtr(windowHwnd)) {
                    System.Console.WriteLine(proc.MainWindowTitle);
                    Console.WriteLine("Toggled WS_CAPTION on: " + proc.MainWindowTitle);
                    ToggleWindowCaption(windowHwnd);
                    return;
                }
            }

            Console.WriteLine("hwnd not found. Exiting.");
        }
    }

    public class WinApi
    {
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        public static extern int GetSystemMetrics(int which);

        [DllImport("user32.dll")]
        public static extern void
        SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
                     int X, int Y, int width, int height, uint flags);        

        private const int SM_CXSCREEN = 0;
        private const int SM_CYSCREEN = 1;
        private static IntPtr HWND_TOP = IntPtr.Zero;
        private const int SWP_SHOWWINDOW = 64; // 0×0040
        private const int SWP_NOSIZE = 1;
        private const int SWP_NOMOVE = 2;

        public static int ScreenX
        {
            get { return GetSystemMetrics(SM_CXSCREEN);}
        }

        public static int ScreenY
        {
            get { return GetSystemMetrics(SM_CYSCREEN);}
        }

        public static void SetWinFullScreen(IntPtr hwnd)
        {
            SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE);
            SetWindowPos(hwnd, HWND_TOP, 0, 0, ScreenX + 7, ScreenY + 7, SWP_SHOWWINDOW | SWP_NOMOVE);
        }
    }
}

这是用简单的

构建的
csc /out:w32toggletitle.exe *.cs

如果您的路径中有.NET Framework目录。

我将生成的EXE放在我的路径中,并使用以下elisp代码来调用它(也适用于各种来源):

(setq gpc/frame-box-before-fullscreen nil)

(defun toggle-titlebar ()
  "Toggles the titlebar on the current frame (Windows only)."
  (interactive)
  (call-process (dot-emacs "winpatch/bin/w32toggletitle.exe")
                nil nil nil
                (frame-parameter (selected-frame) 'window-id)))

(defun toggle-fullscreen ()
  "Toggle fullscreen."
  (interactive)
  (if (frame-parameter nil 'fullscreen)
      (fullscreen-off)
    (fullscreen-on)))

(defun fullscreen-on ()
  "Makes emacs frame occupy the full screen, even on Windows."
  (interactive)
  (setq gpc/frame-box-before-fullscreen
        `((top . ,(frame-parameter nil 'top))
          (left . ,(frame-parameter nil 'left))
          (width . ,(frame-parameter nil 'width))
          (height . ,(frame-parameter nil 'height))))
  (when (eq window-system 'w32)
    (unless (frame-parameter nil 'fullscreen)
      (toggle-titlebar))
    (w32-send-sys-command 61488))
  (set-frame-parameter nil 'fullscreen 'fullboth))

(defun fullscreen-off ()
  "Restore frame from fullscreen mode (Windows only... I think)"
  (interactive)
  (when (eq window-system 'w32)
    (w32-send-sys-command 61728)
    ;; HACK to test if titlebar is on or off
    (if (frame-parameter nil 'fullscreen)
      (toggle-titlebar)))
  (set-frame-parameter nil 'fullscreen nil)
  (modify-frame-parameters nil gpc/frame-box-before-fullscreen))

然后我用

(global-set-key (kbd "<f11>") 'toggle-fullscreen)

在GUI模式下,以便F11按预期工作,包括保存/恢复窗口位置。

我个人花了太多时间在这上面,所以我希望这可以拯救别人的死胡同。

最重要的是,如果你想在Windows上使用真正的emacs全屏,请使用Lennart的补丁。 GNU构建和Cygwin w32构建都强制窗口大小为整个字符。

答案 1 :(得分:0)

此解决方案比harpo更简单,并且无法解决基于字符而非分辨率调整Emacs大小的问题。然而,我的解决方案的优点是你不需要重新编译Emacs,并且它适用于最近版本的Emacs(我使用24.3。)

我在自己寻找解决方案时偶然发现了这篇文章,看到Emacs发布的harpo链接已经过时了,我想我会尝试自己解决这个问题。

经过一些研究,我发现我可以使用单个AutoHotKey脚本制作看似强大的解决方案。

我在the Emacs wiki发布了该解决方案,但我将其重新发布在此处,以防其他人在Google搜索相同的关键字时偶然发现这篇文章。这是来自维基的帖子:

  

我涉足AutoHotKey脚本以使其正常工作,   这是我的解决方案:

     

SetTitleMatchMode 1;仅匹配窗口名称的开头   WinMaximize,emacs @; emacs @指的是WinSet窗口的标题,   风格,-0x40000,emacs @;删除厚框WinSet,Style,   -0x800000,emacs @;删除边框的其余部分

     

将此文件放入文本文件中,将扩展名更改为.ahk和右侧   单击并选择编译以编译它(您需要AutoHotKey   安装)。第3行和第4行禁用粗边框   (WS_THICKFRAME)和边界(WS_BORDER)分别。如果完成了   这个顺序,我没有透过背景照射的间隙。在   为了在每次启动emacs时自动执行此操作,请将其添加到   你的.emacs

(shell-command "<name of compiled ahk script>")
  

&lt;&gt;和内容被文件名替换(带扩展名)   编译的ahk脚本。确保编译的脚本在您的   path(搜索在搜索引擎中更改环境变量   如果你不知道该怎么做)。我正在使用GNU发行版   Emacs 24.3,使用2560x1600分辨率和Terminus字体(大小   9)。我在Windows 8.1上运行它。请注意,我还添加了

(tool-bar-mode -1)
  

到我的.emacs(这是问题一直发生的时候。)

     

我已尝试过其他字体和不同的字体大小。这个   看起来很健壮。