diff --git a/docs/changelog.rst b/docs/changelog.rst index 20e672661..a8e26c031 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,10 @@ To update |kitty|, :doc:`follow the instructions `. - panel kitten: Fix the contents of the panel kitten not being positioned correctly on the vertical axis +- Linux: Disable the Wayland backend on GNOME by default as GNOME has no + support for server side decorations. Can be controlled by + :opt:`linux_display_server`. + - Add an option to control the default :opt:`update_check_interval` when building kitty packages diff --git a/kittens/panel/main.py b/kittens/panel/main.py index 0718f22e1..ab80a6da3 100644 --- a/kittens/panel/main.py +++ b/kittens/panel/main.py @@ -2,12 +2,13 @@ # vim:fileencoding=utf-8 # License: GPL v3 Copyright: 2018, Kovid Goyal +import os import shutil import subprocess import sys from kitty.cli import parse_args -from kitty.constants import is_macos, is_wayland +from kitty.constants import is_macos OPTIONS = r''' --lines @@ -121,7 +122,7 @@ def initial_window_size_func(opts, *a): def main(sys_args): global args - if is_macos or is_wayland: + if is_macos or not os.environ.get('DISPLAY'): raise SystemExit('Currently the panel kitten is supported only on X11 desktops') if not shutil.which('xprop'): raise SystemExit('The xprop program is required for the panel kitten') diff --git a/kitty/cli.py b/kitty/cli.py index c7d32244c..ee5142dbe 100644 --- a/kitty/cli.py +++ b/kitty/cli.py @@ -714,22 +714,25 @@ def create_opts(args, debug_config=False, accumulate_bad_lines=None): from .config import load_config config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config)) if debug_config: - print(version(add_rev=True)) - print(' '.join(os.uname())) + from io import StringIO + dbuf = StringIO() + print(version(add_rev=True), file=dbuf) + print(' '.join(os.uname()), file=dbuf) if is_macos: import subprocess - print(' '.join(subprocess.check_output(['sw_vers']).decode('utf-8').splitlines()).strip()) - else: - print('Running under:', green('Wayland' if is_wayland else 'X11')) + print(' '.join(subprocess.check_output(['sw_vers']).decode('utf-8').splitlines()).strip(), file=dbuf) if os.path.exists('/etc/issue'): - print(open('/etc/issue', encoding='utf-8', errors='replace').read().strip()) + print(open('/etc/issue', encoding='utf-8', errors='replace').read().strip(), file=dbuf) if os.path.exists('/etc/lsb-release'): - print(open('/etc/lsb-release', encoding='utf-8', errors='replace').read().strip()) + print(open('/etc/lsb-release', encoding='utf-8', errors='replace').read().strip(), file=dbuf) config = tuple(x for x in config if os.path.exists(x)) if config: - print(green('Loaded config files:'), ', '.join(config)) + print(green('Loaded config files:'), ', '.join(config), file=dbuf) overrides = (a.replace('=', ' ', 1) for a in args.override or ()) opts = load_config(*config, overrides=overrides, accumulate_bad_lines=accumulate_bad_lines) if debug_config: + if not is_macos: + print('Running under:', green('Wayland' if is_wayland(opts) else 'X11'), file=dbuf) + print(dbuf.getvalue()) compare_opts(opts) return opts diff --git a/kitty/config_data.py b/kitty/config_data.py index 79e6a98e6..94b4c3d43 100644 --- a/kitty/config_data.py +++ b/kitty/config_data.py @@ -965,6 +965,12 @@ o('macos_custom_beam_cursor', False, long_text=_(''' Enable/disable custom mouse cursor for macOS that is easier to see on both light and dark backgrounds. WARNING: this might make your mouse cursor invisible on dual GPU machines.''')) + +o('linux_display_server', 'auto', option_type=choices('auto', 'x11', 'wayland'), long_text=_(''' +Choose between Wayland and X11 backends. By default, an +appropriate backend based on the system state is chosen +automatically. Set it to :code:`x11` or :code:`wayland` +to force the choice.''')) # }}} g('shortcuts') # {{{ diff --git a/kitty/constants.py b/kitty/constants.py index 71d829e01..7ba74b910 100644 --- a/kitty/constants.py +++ b/kitty/constants.py @@ -132,9 +132,34 @@ def glfw_path(module): return os.path.join(base, 'glfw-{}.so'.format(module)) -is_wayland = False -if os.environ.get('WAYLAND_DISPLAY') and 'KITTY_DISABLE_WAYLAND' not in os.environ and os.path.exists(glfw_path('wayland')): - is_wayland = True +def detect_if_wayland_ok(): + if 'WAYLAND_DISPLAY' not in os.environ: + return False + if 'KITTY_DISABLE_WAYLAND' in os.environ: + return False + if not os.path.exists(glfw_path('wayland')): + return False + cd = os.environ.get('XDG_CURRENT_DESKTOP') + if cd: + cd = frozenset(cd.split(':')) + if 'GNOME' in cd: + # GNOME does not support xdg-decorations + # https://gitlab.gnome.org/GNOME/mutter/issues/217 + return False + return True + + +def is_wayland(opts=None): + if is_macos: + return False + if opts is None: + return is_wayland.ans + if opts.linux_display_server == 'auto': + ans = detect_if_wayland_ok() + else: + ans = opts.linux_display_server == 'wayland' + setattr(is_wayland, 'ans', ans) + return ans supports_primary_selection = not is_macos diff --git a/kitty/main.py b/kitty/main.py index f1959e319..30ea6b0a3 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -84,8 +84,8 @@ def load_all_shaders(semi_transparent=0): load_borders_program() -def init_glfw(debug_keyboard=False): - glfw_module = 'cocoa' if is_macos else ('wayland' if is_wayland else 'x11') +def init_glfw(opts, debug_keyboard=False): + glfw_module = 'cocoa' if is_macos else ('wayland' if is_wayland(opts) else 'x11') if not glfw_init(glfw_path(glfw_module), debug_keyboard): raise SystemExit('GLFW initialization failed') return glfw_module @@ -116,7 +116,7 @@ def _run_app(opts, args, bad_lines=()): new_os_window_trigger = get_new_os_window_trigger(opts) if is_macos and opts.macos_custom_beam_cursor: set_custom_ibeam_cursor() - if not is_wayland and not is_macos: # no window icons on wayland + if not is_wayland() and not is_macos: # no window icons on wayland with open(logo_data_file, 'rb') as f: set_default_window_icon(f.read(), 256, 256) load_shader_programs.use_selection_fg = opts.selection_foreground is not None @@ -139,7 +139,7 @@ def _run_app(opts, args, bad_lines=()): def run_app(opts, args, bad_lines=()): set_scale(opts.box_drawing_scale) - set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback) + set_options(opts, is_wayland(), args.debug_gl, args.debug_font_fallback) set_font_family(opts, debug_font_matching=args.debug_font_fallback) try: _run_app(opts, args, bad_lines) @@ -259,7 +259,7 @@ def _main(): return bad_lines = [] opts = create_opts(args, accumulate_bad_lines=bad_lines) - init_glfw(args.debug_keyboard) + init_glfw(opts, args.debug_keyboard) setup_environment(opts, args) try: with setup_profiling(args): diff --git a/kitty/tabs.py b/kitty/tabs.py index e8f5b9cef..5ffb93d1c 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -222,7 +222,7 @@ class Tab: # {{{ if env: fenv.update(env) fenv['KITTY_WINDOW_ID'] = str(next_window_id()) - if not is_macos and not is_wayland: + if not is_macos and not is_wayland(): try: fenv['WINDOWID'] = str(x11_window_id(self.os_window_id)) except Exception: diff --git a/kitty/utils.py b/kitty/utils.py index e18ea2c03..80d354c3a 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -207,7 +207,7 @@ def end_startup_notification_x11(ctx): def init_startup_notification(window_handle, startup_id=None): - if is_macos or is_wayland: + if is_macos or is_wayland(): return if window_handle is None: log_error('Could not perform startup notification as window handle not present') @@ -222,7 +222,7 @@ def init_startup_notification(window_handle, startup_id=None): def end_startup_notification(ctx): if not ctx: return - if is_macos or is_wayland: + if is_macos or is_wayland(): return try: end_startup_notification_x11(ctx)