2

我也遇到过这个讨论:http ://www.reddit.com/r/emacs/comments/15gd16/osx_a_window_sizing_problem/但我现在在 Windows 上(GUI Emacs 在 Gnome 或KDE)。

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

4

2 回答 2

4

2015 年更新:Emacs 24.4 包括对使用toggle-frame-fullscreen. 您可以不加修改地使用适用于 Windows 的 GNU 构建(或者,可能是任何其他构建)。


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

您需要EmacsW32修补版本。

从此下载页面获取最新的安装程序(当前为 Emacs-24-BzrP110217-EmacsW32-1.58.exe) 。

这与诸如emacs-fullscreen-w32之类的东西(使用 Windows API 删除标题栏)结合使用,将为您提供真正的全屏显示。

相信我,没有其他方法可以消除 Windows 上的差距。

就个人而言,我不喜欢在我的.emacsrepo 中使用某人的 EXE,所以我使用以下 C# 程序(我从这个 bitbucket 项目中获得):

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 构建都将窗口大小强制为整个字符。

于 2013-05-26T16:47:58.343 回答
0

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

我在自己寻找解决方案时偶然发现了这篇文章,并且看到链接到的 Emacs 版本 harpo 已经过时,我想我会尝试自己制作一个解决方案。

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

我在Emacs wiki上发布了解决方案,但我在这里重新发布它,以防其他人在 Google 中搜索相同的关键字时偶然发现这篇文章。这是我在 wiki 上的帖子:

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

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

将其放入一个文本文件,将扩展名更改为 .ahk 并右键单击并选择编译以编译它(您需要安装 AutoHotKey)。第 3 行和第 4 行分别禁用粗边框 (WS_THICKFRAME) 和边框 (WS_BORDER)。如果按此顺序完成,我不会在背景闪耀的地方留下任何空隙。为了在您每次启动 emacs 时自动执行此操作,请将其添加到您的 .emacs

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

<> 和内容被编译的 ahk 脚本的文件名(带扩展名)替换。确保已编译的脚本在您的路径中(如果您不知道如何执行此操作,请在搜索引擎中搜索更改的环境变量)。我正在使用 Emacs 24.3 的 GNU 发行版,使用 2560x1600 分辨率和 Terminus 字体(大小 9)。我在 Windows 8.1 上运行它。请注意,我还添加了

(tool-bar-mode -1)

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

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

于 2014-04-14T17:42:04.303 回答