mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-18 06:27:55 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f8c392571 |
@@ -302,9 +302,9 @@
|
||||
"name": "wayland",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "wayland-1.23.1.tar.xz",
|
||||
"hash": "sha256:864fb2a8399e2d0ec39d56e9d9b753c093775beadc6022ce81f441929a81e5ed",
|
||||
"urls": ["https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.23.1/downloads/{filename}"]
|
||||
"filename": "wayland-1.23.0.tar.xz",
|
||||
"hash": "sha256:05b3e1574d3e67626b5974f862f36b5b427c7ceeb965cb36a4e6c2d342e45ab2",
|
||||
"urls": ["https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.23.0/downloads/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -312,9 +312,9 @@
|
||||
"name": "wayland-protocols",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "wayland-protocols-1.44.tar.xz",
|
||||
"hash": "sha256:3df1107ecf8bfd6ee878aeca5d3b7afd81248a48031e14caf6ae01f14eebb50e",
|
||||
"urls": ["https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/1.44/downloads/{filename}"]
|
||||
"filename": "wayland-protocols-1.41.tar.xz",
|
||||
"hash": "sha256:2786b6b1b79965e313f2c289c12075b9ed700d41844810c51afda10ee329576b",
|
||||
"urls": ["https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/1.41/downloads/{filename}"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,18 +9,6 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
Recent major new features
|
||||
---------------------------
|
||||
|
||||
Access kitty with a single keypress [0.42]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. include:: quake-screenshots.rst
|
||||
|
||||
kitty now has a Quake like floating, translucent terminal window, so you can access
|
||||
all that kitty goodness instantly with a single keypress.
|
||||
|
||||
See the screenshots on the side and head over to the :doc:`kitten page for details
|
||||
on how to set it up </kittens/quick-access-terminal>`.
|
||||
|
||||
|
||||
Multiple sized text [0.40]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -106,58 +94,29 @@ consumption to do the same tasks.
|
||||
Detailed list of changes
|
||||
-------------------------------------
|
||||
|
||||
0.42.1 [2025-05-17]
|
||||
0.42.0 [future]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Fix ambiguous width and private use characters not being rendered when used with variable width text-sizing protocol escape codes
|
||||
- The :doc:`panel kitten </kittens/panel>` can now be used to :ref:`quake`
|
||||
|
||||
- Quick access terminal: Restore focus to previously active window when hiding the quick access terminal window on macOS (:iss:`8627`)
|
||||
|
||||
- Wayland: Fix an abort if the terminal program sets a window title longer than 2KB that contains CSI escape sequences and multibyte UTF-8 (:iss:`8619`)
|
||||
|
||||
- Quick access terminal: Allow toggling the window to full screen using the standard kitty :sc:`toggle_fullscreen` shortcut (:iss:`8626`)
|
||||
|
||||
- Quick access terminal: Allow configuring the monitor to display the panel on in Wayland/X11 (:iss:`8630`)
|
||||
|
||||
- A new setting :opt:`remember_window_position` to optionally use the position of the last closed kitty OS Window as the position of the first kitty OS Window when running a new kitty instance (:pull:`8601`)
|
||||
|
||||
- Panel kitten: A new ``center-sized`` value for :option:`--edge <kitty +kitten panel --edge>` to allow easily creating sized and centered panels
|
||||
|
||||
- Wayland: The `kitty --name` flag now sets the XDG *window tag* on compositors
|
||||
that support the `xdg-toplevel-tag <https://wayland.app/protocols/xdg-toplevel-tag-v1>`__ protocol.
|
||||
|
||||
|
||||
0.42.0 [2025-05-11]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- A new kitten: :doc:`quick-access-terminal </kittens/quick-access-terminal>` to :ref:`quake`
|
||||
|
||||
- The :doc:`panel kitten </kittens/panel>` works on macOS and X11 as well as Wayland (:iss:`2590`)
|
||||
- The :doc:`panel kitten </kittens/panel>` now works on macOS as well as Wayland (:iss:`2590`)
|
||||
|
||||
- **Behavior change**: Now kitty does full grapheme segmentation following the
|
||||
Unicode 16 spec when splitting text into cells (:iss:`8533`)
|
||||
|
||||
- **Behavior change**: The :ref:`automatic color switching functionality <auto_color_scheme>` now also controls background image settings (:iss:`8603`)
|
||||
|
||||
- panel kitten: Allow using :option:`kitty +kitten panel --single-instance` to create multiple panels in one process (:iss:`8549`)
|
||||
|
||||
- launch: Allow creating desktop panels such as those created by the :doc:`panel kitten </kittens/panel>` (:iss:`8549`)
|
||||
|
||||
- Remote control: Allow modifying desktop panels and showing/hiding OS Windows
|
||||
using the ``kitten @ resize-os-window`` command (:iss:`8550`)
|
||||
using the `kitten @ resize-os-window` command (:iss:`8550`)
|
||||
|
||||
- Remote control launch: Allow waiting for a program launched in a new window
|
||||
to exit and get the exit code via the `kitty +launch
|
||||
--wait-for-child-to-exit` command line flag (:disc:`8573`)
|
||||
|
||||
- Allow starting kitty with the OS window hidden via :option:`kitty --start-as=hidden <kitty --start-as>`, useful for single instance mode (:iss:`3466`)
|
||||
- Allow starting kitty with the OS window hidden via :option:`kitty --start-as`\=hidden useful for single instance mode (:iss:`3466`)
|
||||
|
||||
- Allow configuring the mouse unhide behavior when using :opt:`mouse_hide_wait` (:pull:`8508`)
|
||||
|
||||
- diff kitten: Add half page and full page scroll vim-like bindings (:pull:`8514`)
|
||||
|
||||
- diff kitten: Allow diffing named pipes (:iss:`8597`)
|
||||
|
||||
- Fix a regression that caused automatic color themes to not be re-applied after config file reload (:iss:`8530`)
|
||||
|
||||
- Wayland: When the compositor supports the `xdg-system-bell
|
||||
@@ -166,8 +125,8 @@ Detailed list of changes
|
||||
|
||||
- panel kitten: Allow specifying panel size in pixels in addition to cells
|
||||
|
||||
- Fix a regression in 0.36.0 that caused using = with single letter command
|
||||
line flags to no longer work correctly (:iss:`8556`)
|
||||
- Fix a regression in 0.36.0 that caused using = with single letter options to
|
||||
no longer work correctly (:iss:`8556`)
|
||||
|
||||
- Single instance: Preserve environment variables from invoking environment in
|
||||
newly created window (:disc:`8567`)
|
||||
@@ -177,12 +136,6 @@ Detailed list of changes
|
||||
|
||||
- macOS: Fix text color in visual window select ignoring the color theme (:iss:`8579`)
|
||||
|
||||
- Launch action: Allow using an env var that resolves to a full command-line as the program to launch (:pull:`8613`)
|
||||
|
||||
- :ac:`change_font_size` allow multiplying/dividing the current font size in addition to incrementing it (:iss:`8616`)
|
||||
|
||||
- Box drawing: Improve appearance of rounder corners, giving them a uniform line width (:iss:`8299`)
|
||||
|
||||
0.41.1 [2025-04-03]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
import time
|
||||
from functools import lru_cache, partial
|
||||
from typing import Any, Callable, Dict, Iterable, Iterator, List, Tuple
|
||||
@@ -30,6 +31,7 @@ if kitty_src not in sys.path:
|
||||
from kitty.conf.types import Definition, expand_opt_references # noqa
|
||||
from kitty.constants import str_version, website_url # noqa
|
||||
from kitty.fast_data_types import Shlex, TEXT_SIZE_CODE # noqa
|
||||
from kittens.panel.main import default_quake_cmdline # noqa
|
||||
|
||||
# config {{{
|
||||
# -- Project information -----------------------------------------------------
|
||||
@@ -62,7 +64,7 @@ extensions = [
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinx_copybutton',
|
||||
'sphinx_inline_tabs',
|
||||
'sphinxext.opengraph',
|
||||
"sphinxext.opengraph",
|
||||
]
|
||||
|
||||
# URL for OpenGraph tags
|
||||
@@ -120,6 +122,9 @@ string_replacements = {
|
||||
'_kitty_install_cmd': 'curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin',
|
||||
'_build_go_version': go_version('../go.mod'),
|
||||
'_text_size_code': str(TEXT_SIZE_CODE),
|
||||
'_default_quake_cmdline': textwrap.fill(
|
||||
default_quake_cmdline, break_on_hyphens=False, break_long_words=False, initial_indent=' ' * 4, subsequent_indent=' ' * 8, width=77,
|
||||
).replace('\n', ' \\\n'),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -470,8 +470,7 @@ You need to make sure that the environment variables you define in your shell's
|
||||
rc files are either also defined system wide or via the :opt:`env` directive in
|
||||
:file:`kitty.conf`. Common environment variables that cause issues are those
|
||||
related to localization, such as :envvar:`LANG`, ``LC_*`` and loading of
|
||||
configuration files such as ``XDG_*``, :envvar:`KITTY_CONFIG_DIRECTORY` and,
|
||||
most importantly, ``PATH`` to locate binaries.
|
||||
configuration files such as ``XDG_*``, :envvar:`KITTY_CONFIG_DIRECTORY`.
|
||||
|
||||
To see the environment variables that kitty sees, you can add the following
|
||||
mapping to :file:`kitty.conf`::
|
||||
|
||||
@@ -1003,8 +1003,8 @@ take, and the default value they take when missing. All integers are 32-bit.
|
||||
Key Value Default Description
|
||||
======= ==================== ========= =================
|
||||
``a`` Single character. ``t`` The overall action this graphics command is performing.
|
||||
``(a, c, d, f, ``t`` - transmit data, ``T`` - transmit data and display image,
|
||||
p, q, t, T)`` ``q`` - query terminal, ``p`` - put (display) previous transmitted image,
|
||||
``(a, c, d, f, `` ``t`` - transmit data, ``T`` - transmit data and display image,
|
||||
``p, q, t, T)`` ``q`` - query terminal, ``p`` - put (display) previous transmitted image,
|
||||
``d`` - delete image, ``f`` - transmit data for animation frames,
|
||||
``a`` - control animation, ``c`` - compose animation frames
|
||||
|
||||
|
||||
@@ -149,14 +149,14 @@ user presses, for example, :kbd:`ctrl+shift+a` the escape code would be ``CSI
|
||||
97;modifiers u``. It *must not* be ``CSI 65; modifiers u``.
|
||||
|
||||
If *alternate key reporting* is requested by the program running in the
|
||||
terminal, the terminal can send two additional Unicode codepoints, the *shifted
|
||||
key* and *base layout key*, separated by colons. The shifted key is simply the
|
||||
upper-case version of ``unicode-codepoint``, or more technically, the shifted
|
||||
version, in the currently active keyboard layout. So `a` becomes `A` and so on,
|
||||
based on the current keyboard layout. This is needed to be able to match
|
||||
against a shortcut such as :kbd:`ctrl+plus` which depending on the type of
|
||||
keyboard could be either :kbd:`ctrl+shift+equal` or :kbd:`ctrl+plus`. Note that
|
||||
the shifted key must be present only if shift is also present in the modifiers.
|
||||
terminal, the terminal can send two additional Unicode codepoints, the
|
||||
*shifted key* and *base layout key*, separated by colons.
|
||||
The shifted key is simply the upper-case version of ``unicode-codepoint``, or
|
||||
more technically, the shifted version. So `a` becomes `A` and so on, based on
|
||||
the current keyboard layout. This is needed to be able to match against a
|
||||
shortcut such as :kbd:`ctrl+plus` which depending on the type of keyboard could
|
||||
be either :kbd:`ctrl+shift+equal` or :kbd:`ctrl+plus`. Note that the shifted
|
||||
key must be present only if shift is also present in the modifiers.
|
||||
|
||||
The *base layout key* is the key corresponding to the physical key in the
|
||||
standard PC-101 key layout. So for example, if the user is using a Cyrillic
|
||||
|
||||
@@ -124,5 +124,5 @@ that is, they are used to set the variable value for some font characteristic.
|
||||
|
||||
|
||||
In addition to these keys, any four letter key is treated as the name of a
|
||||
variable characteristic of the font. Its value is used to set the value for
|
||||
variable characteristic of the font. It's value is used to set the value for
|
||||
the name.
|
||||
|
||||
@@ -8,43 +8,52 @@ Draw a GPU accelerated dock panel on your desktop
|
||||
Overview
|
||||
--------------
|
||||
|
||||
.. include:: ../quake-screenshots.rst
|
||||
|
||||
Draw the desktop wallpaper or docks and panels using arbitrary
|
||||
terminal programs, For example, have `btop
|
||||
<https://github.com/aristocratos/btop>`__ or `cava
|
||||
<https://github.com/karlstav/cava/>`__ be your desktop wallpaper.
|
||||
You can use this kitten to draw a GPU accelerated panel on the edge of your
|
||||
screen or as the desktop wallpaper, that shows the output from an arbitrary
|
||||
terminal program.
|
||||
|
||||
It is useful for showing status information or notifications on your desktop
|
||||
using terminal programs instead of GUI toolkits.
|
||||
using terminal programs instead of GUI toolkits. It can also be used for a
|
||||
:ref:`Quake like quick access terminal <quake>`.
|
||||
|
||||
.. figure:: ../screenshots/panel.png
|
||||
:alt: Screenshot, showing a sample panel
|
||||
:align: center
|
||||
:width: 100%
|
||||
|
||||
Screenshot, showing a sample panel
|
||||
|
||||
|
||||
The screenshot to the side shows some uses of the panel kitten to draw various
|
||||
desktop components such as the background, a quick access floating terminal and
|
||||
a dock panel showing system information (Linux only).
|
||||
The screenshot above shows a sample panel that displays the current desktop and
|
||||
window title as well as miscellaneous system information such as network
|
||||
activity, CPU load, date/time, etc.
|
||||
|
||||
.. versionadded:: 0.42.0
|
||||
Support for macOS and support for Wayland was added in 0.34.0
|
||||
|
||||
Support for macOS, see :ref:`compatibility matrix <panel_compat>` for details.
|
||||
and X11 (background and overlay).
|
||||
.. note::
|
||||
|
||||
.. versionadded:: 0.34.0
|
||||
|
||||
Support for Wayland. See :ref:`below <panel_compat>` for which
|
||||
Wayland compositors work.
|
||||
This kitten currently only works on macOS and Wayland compositors
|
||||
that support the `wlr layer shell protocol
|
||||
<https://wayland.app/protocols/wlr-layer-shell-unstable-v1#compositor-support>`__
|
||||
(which is almost all of them except GNOME). On macOS the panels do not
|
||||
prevent other windows from floating over them because of limitations in
|
||||
Cocoa. On X11, only the ``top`` and ``bottom`` panels are widely supported,
|
||||
the other types depend on the window manager used.
|
||||
|
||||
Using this kitten is simple, for example::
|
||||
|
||||
kitten panel sh -c 'printf "\n\n\nHello, world."; sleep 5s'
|
||||
kitty +kitten panel sh -c 'printf "\n\n\nHello, world."; sleep 5s'
|
||||
|
||||
This will show ``Hello, world.`` at the top edge of your screen for five
|
||||
seconds. Here, the terminal program we are running is :program:`sh` with a script
|
||||
to print out ``Hello, world!``. You can make the terminal program as complex as
|
||||
you like, as demonstrated in the screenshots.
|
||||
you like, as demonstrated in the screenshot above.
|
||||
|
||||
If you are on Wayland or macOS, you can, for instance, run::
|
||||
If you are on Wayland or macOS, you can, for instance run::
|
||||
|
||||
kitten panel --edge=background htop
|
||||
kitty +kitten panel --edge=background htop
|
||||
|
||||
to display ``htop`` as your desktop background. Remember this works in everything
|
||||
but GNOME and also, in sway, you have to disable the background wallpaper as
|
||||
@@ -53,13 +62,40 @@ sway renders that over the panel kitten surface.
|
||||
There are projects that make use of this facility to implement generalised
|
||||
panels and desktop components:
|
||||
|
||||
.. _panel_projects:
|
||||
|
||||
* `kitty panel <https://github.com/5hubham5ingh/kitty-panel>`__
|
||||
* `pawbar <https://github.com/codelif/pawbar>`__
|
||||
|
||||
|
||||
.. _remote_control_panel:
|
||||
.. _quake:
|
||||
|
||||
Make a Quake like quick access terminal
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 0.42.0
|
||||
Support for quake mode, works only on macOS and Wayland, except for GNOME.
|
||||
|
||||
This kitten can be used to make a quick access terminal, that appears and
|
||||
disappears at a key press. To do so use the following command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
_default_quake_cmdline
|
||||
|
||||
Run this command in a terminal, and a quick access kitty panel will show up at
|
||||
the top of your screen. Run it again, and the panel will be hidden.
|
||||
|
||||
Simply bind this command to some key press in your window manager or desktop
|
||||
environment settings and then you have a quick access terminal at a single key press.
|
||||
You can use the various panel options to configure the size, appearance and
|
||||
position of the quick access panel. In particular, the :option:`kitty +kitten panel --config` and
|
||||
:option:`kitty +kitten panel --override` options can be used to theme the terminal appropriately,
|
||||
making it look different from regular kitty terminal instances.
|
||||
|
||||
.. note::
|
||||
If you want to start the quake terminal hidden, use
|
||||
:option:`kitty +kitten panel --start-as-hidden`, useful if you are starting it in the background
|
||||
during computer startup.
|
||||
|
||||
|
||||
Controlling panels via remote control
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -67,7 +103,7 @@ Controlling panels via remote control
|
||||
You can control panels via the kitty :doc:`remote control </remote-control>` facility. Create a panel
|
||||
with remote control enabled::
|
||||
|
||||
kitten panel -o allow_remote_control=socket-only --lines=2 \
|
||||
kitty +kitten panel -o allow_remote_control=socket-only --lines=2 \
|
||||
--listen-on=unix:/tmp/panel kitten run-shell
|
||||
|
||||
|
||||
@@ -89,138 +125,3 @@ To create a new panel running the program top, in the same instance
|
||||
|
||||
|
||||
.. include:: ../generated/cli-kitten-panel.rst
|
||||
|
||||
|
||||
.. _quake_ss:
|
||||
|
||||
How the screenshots were generated
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The system statistics in the background were created using::
|
||||
|
||||
kitten panel --edge=background -o background_opacity=0.2 -o background=black btop
|
||||
|
||||
This creates a kitty background window and inside it runs the `btop
|
||||
<https://github.com/aristocratos/btop>`__ program to display the statistics.
|
||||
|
||||
The floating quick access window was created by running::
|
||||
|
||||
kitten quick-access-terminal kitten run-shell \
|
||||
zsh -c 'printf "\e]66;s=4;Quick access kitty in Hyprland\a\n\n\n\nAlso uses kitty to draw desktop background\n"'
|
||||
|
||||
This starts the quick access window and inside it runs ``kitten run-shell``, which
|
||||
in turn first runs ``zsh`` to print out the message and then starts the users login
|
||||
shell.
|
||||
|
||||
The Linux dock panel was::
|
||||
|
||||
kitten panel kitty +launch my-panel.py
|
||||
|
||||
This creates the panel window and runs the ``my-panel.py`` script inside it
|
||||
using the Python interpreter that comes bundled with kitty. Unfortunately the
|
||||
actual script is not public, but there are :ref:`public projects implementing
|
||||
general purpose panels using kitty <panel_projects>`.
|
||||
|
||||
|
||||
.. _panel_compat:
|
||||
|
||||
Compatibility with various platforms
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. only:: man
|
||||
|
||||
See the HTML documentation for the compatibility matrix.
|
||||
|
||||
.. only:: not man
|
||||
|
||||
Generated with the help of the :file:`panels.py` test script.
|
||||
|
||||
.. tab:: Wayland
|
||||
|
||||
Below is a list of the status of various Wayland compositors. The panel kitten
|
||||
relies of the `wlr layer shell protocol
|
||||
<https://wayland.app/protocols/wlr-layer-shell-unstable-v1#compositor-support>`__,
|
||||
which is technically supported by almost all Wayland compositors, but the
|
||||
implementation in some of them is quite buggy.
|
||||
|
||||
🟢 **Hyprland**
|
||||
Fully working, no known issues
|
||||
|
||||
🟢 **KDE** (kwin)
|
||||
Fully working, no known issues. KDE uses an `undocumented mapping <https://invent.kde.org/plasma/kwin/-/blob/3dc5cee6b34792486b343098e55e7f2b90dfcd00/src/layershellv1window.cpp#L24>`__ under Wayland to set the window type from the :code:`kitten panel --app-id` flag. You might want to use :code:`--app-id=dock` so that KDE treats the window as a dock panel, and disables window
|
||||
appearing/disappearing animations for it.
|
||||
|
||||
🟠 **Sway**
|
||||
Partially working. Issues include:
|
||||
* Renders its configured background over the background window instead of
|
||||
under it. This is likely because it uses the wlr protocol for
|
||||
backgrounds itself.
|
||||
* Hiding a dock panel (unmapping the window) does not release the space
|
||||
used by the dock.
|
||||
|
||||
🟠 **niri**
|
||||
Breaks when hiding (unmapping) layer shell windows. This means the quick
|
||||
access terminal is non-functional, but background and dock panels work.
|
||||
More technically, keyboard focus gets stuck in the hidden window and when trying
|
||||
to remap the hidden window niri never sends configure events for the remapped surface.
|
||||
|
||||
🟠 **labwc**
|
||||
Breaks when hiding (unmapping) layer shell windows. This means the quick
|
||||
access terminal is non-functional, but background and dock panels work.
|
||||
More technically, when unmapping the surface (attaching a NULL buffer to
|
||||
it) labwc continues to send configure events to the unmapped surface,
|
||||
leading to Wayland protocol errors and a crash of labwc.
|
||||
|
||||
🔴 **GNOME** (mutter)
|
||||
Does not implement the wlr protocol at all, nothing works.
|
||||
|
||||
.. tab:: macOS
|
||||
|
||||
Mostly everything works, with the notable exception that dock panels do not
|
||||
prevent other windows from covering them. This is because Apple does not
|
||||
provide and way to do this in their APIs.
|
||||
|
||||
.. tab:: X11
|
||||
|
||||
Support is highly dependent on the quirks of individual window
|
||||
managers. See the matrix below:
|
||||
|
||||
.. list-table:: Compatibility matrix
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
|
||||
* - WM
|
||||
- Desktop
|
||||
- Dock
|
||||
- Quick
|
||||
- Notes
|
||||
|
||||
* - KDE
|
||||
- 🟠
|
||||
- 🟢
|
||||
- 🟢
|
||||
- transparency does not work for :option:`--edge=background <--edge>`
|
||||
|
||||
* - GNOME
|
||||
- 🟢
|
||||
- 🟢
|
||||
- 🟢
|
||||
-
|
||||
|
||||
* - XFCE
|
||||
- 🟢
|
||||
- 🟢
|
||||
- 🟢
|
||||
-
|
||||
|
||||
* - i3
|
||||
- 🔴
|
||||
- 🟠
|
||||
- 🔴
|
||||
- only top and bottom dock panels, without transparency
|
||||
|
||||
* - xmonad
|
||||
- 🔴
|
||||
- 🔴
|
||||
- 🔴
|
||||
- doesn't support the needed NET_WM protocols
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
.. _quake:
|
||||
|
||||
Make a Quake like quick access terminal
|
||||
====================================================================================================
|
||||
|
||||
.. highlight:: sh
|
||||
|
||||
.. only:: man
|
||||
|
||||
Overview
|
||||
--------------
|
||||
|
||||
|
||||
.. include:: ../quake-screenshots.rst
|
||||
|
||||
.. versionadded:: 0.42.0
|
||||
See :ref:`here for what platforms it works on <panel_compat>`.
|
||||
|
||||
This kitten can be used to make a quick access terminal, that appears and
|
||||
disappears at a key press. To do so use the following command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
kitten quick-access-terminal
|
||||
|
||||
Run this command in a terminal, and a quick access kitty window will show up at
|
||||
the top of your screen. Run it again, and the window will be hidden.
|
||||
|
||||
To make the terminal appear and disappear at a key press:
|
||||
|
||||
.. |macOs| replace:: :guilabel:`System Preferences->Keyboard->Keyboard Shortcuts->Services->General`
|
||||
|
||||
.. only:: not man
|
||||
|
||||
.. tab:: Linux
|
||||
|
||||
Simply bind the above command to some key press in your window manager or desktop
|
||||
environment settings and then you have a quick access terminal at a single key press.
|
||||
|
||||
.. tab:: macOS
|
||||
|
||||
In kitty, run the above command to show the quick access window, then close
|
||||
it by running the command again or pressing :kbd:`ctrl+d`. Now go to |macOS| and set a shortcut for
|
||||
the :guilabel:`Quick access to kitty` entry.
|
||||
|
||||
.. only:: man
|
||||
|
||||
In Linux, simply assign the above command to a global shortcut in your
|
||||
window manager. In macOS, go to |macOS| and set a shortcut
|
||||
for the :guilabel:`Quick access to kitty` entry.
|
||||
|
||||
Configuration
|
||||
------------------------
|
||||
|
||||
You can configure the appearance and behavior of the quick access window
|
||||
by creating a :file:`quick-access-terminal.conf` file in your
|
||||
:ref:`kitty config folder <confloc>`. In particular, you can use the
|
||||
:opt:`kitty_conf <kitten-quick_access_terminal.kitty_conf>` option to change
|
||||
various kitty settings, just for the quick access window.
|
||||
|
||||
.. note::
|
||||
|
||||
This kitten uses the :doc:`panel kitten </kittens/panel>` under the
|
||||
hood. You can use the :ref:`techniques described there <remote_control_panel>`
|
||||
for remote controlling the quick access window, remember to add
|
||||
``kitty_override allow_remote_control=socket-only`` and ``kitty_override
|
||||
listen_on=unix:/tmp/whatever`` to
|
||||
:file:`quick-access-terminal.conf`.
|
||||
|
||||
See below for the supported configuration directives:
|
||||
|
||||
|
||||
.. include:: /generated/conf-kitten-quick_access_terminal.rst
|
||||
|
||||
|
||||
.. include:: /generated/cli-kitten-quick_access_terminal.rst
|
||||
|
||||
|
||||
Sample quick-access-terminal.conf
|
||||
---------------------------------------
|
||||
|
||||
You can download a sample :file:`quick-access-terminal.conf` file with all default settings and
|
||||
comments describing each setting by clicking: :download:`sample quick-access-terminal.conf
|
||||
</generated/conf/quick_access_terminal.conf>`.
|
||||
@@ -70,8 +70,7 @@ This works by creating three files: :file:`dark-theme.auto.conf`,
|
||||
:file:`light-theme.auto.conf` and :file:`no-preference-theme.auto.conf` in the
|
||||
kitty config directory. When these files exist, kitty queries the OS for its color scheme
|
||||
and uses the appropriate file. Note that the colors in these files override all other
|
||||
colors, and also all background image settings,
|
||||
even those specified using the :option:`kitty --override` command line flag.
|
||||
colors, even those specified using the :option:`kitty --override` command line flag.
|
||||
kitty will also automatically change colors when the OS color scheme changes,
|
||||
for example, during night/day transitions.
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ Extend with kittens
|
||||
kittens/themes
|
||||
kittens/choose-fonts
|
||||
kittens/hints
|
||||
kittens/quick-access-terminal
|
||||
kittens/panel
|
||||
kittens/remote_file
|
||||
kittens/hyperlinked_grep
|
||||
kittens/transfer
|
||||
@@ -53,16 +51,6 @@ Some prominent kittens:
|
||||
filenames, words, lines, etc. from the terminal screen.
|
||||
|
||||
|
||||
:doc:`Quick access terminal <kittens/quick-access-terminal>`
|
||||
Get access to a quick access floating, semi-transparent kitty window
|
||||
with a single keypress.
|
||||
|
||||
|
||||
:doc:`Panel <kittens/panel>`
|
||||
Draw the desktop wallpaper or docks and panels using arbitrary
|
||||
terminal programs.
|
||||
|
||||
|
||||
:doc:`Remote file <kittens/remote_file>`
|
||||
Edit, open, or download remote files over SSH easily, by simply clicking on
|
||||
the filename.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
.. only:: not man
|
||||
|
||||
.. sidebar::
|
||||
|
||||
**Screenshots**
|
||||
|
||||
.. figure:: /screenshots/quake-macos.webp
|
||||
:alt: Screenshot, showing the kitty floating quick access terminal above the background which is the program btop, running inside kitty, on macOS
|
||||
:align: center
|
||||
:width: 100%
|
||||
|
||||
macOS
|
||||
|
||||
|
||||
.. figure:: /screenshots/quake-hypr.webp
|
||||
:alt: Screenshot, showing the kitty floating quick access terminal above the background which is the program btop, running inside kitty, on Hyprland in Linux
|
||||
:align: center
|
||||
:width: 100%
|
||||
|
||||
Linux
|
||||
|
||||
.. figure:: /screenshots/panel.png
|
||||
:alt: Screenshot, showing a sample panel
|
||||
:align: center
|
||||
:width: 100%
|
||||
|
||||
A sample panel on Linux
|
||||
|
||||
How the screenshots :ref:`were generated <quake_ss>`.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 460 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 MiB |
@@ -259,9 +259,9 @@ def completion_for_launch_wrappers(*names: str) -> None:
|
||||
|
||||
def generate_completions_for_kitty() -> None:
|
||||
print('package completion\n')
|
||||
print('import "github.com/kovidgoyal/kitty/tools/cli"')
|
||||
print('import "github.com/kovidgoyal/kitty/tools/cmd/tool"')
|
||||
print('import "github.com/kovidgoyal/kitty/tools/cmd/at"')
|
||||
print('import "kitty/tools/cli"')
|
||||
print('import "kitty/tools/cmd/tool"')
|
||||
print('import "kitty/tools/cmd/at"')
|
||||
|
||||
print('func kitty(root *cli.Command) {')
|
||||
|
||||
@@ -450,6 +450,15 @@ def go_code_for_remote_command(name: str, cmd: RemoteCommand, template: str) ->
|
||||
|
||||
# kittens {{{
|
||||
|
||||
@lru_cache
|
||||
def wrapped_kittens() -> tuple[str, ...]:
|
||||
with open('shell-integration/ssh/kitty') as f:
|
||||
for line in f:
|
||||
if line.startswith(' wrapped_kittens="'):
|
||||
val = line.strip().partition('"')[2][:-1]
|
||||
return tuple(sorted(filter(None, val.split())))
|
||||
raise Exception('Failed to read wrapped kittens from kitty wrapper script')
|
||||
|
||||
|
||||
def generate_conf_parser(kitten: str, defn: Definition) -> None:
|
||||
with replace_if_needed(f'kittens/{kitten}/conf_generated.go'):
|
||||
@@ -458,7 +467,7 @@ def generate_conf_parser(kitten: str, defn: Definition) -> None:
|
||||
|
||||
|
||||
def generate_extra_cli_parser(name: str, spec: str) -> None:
|
||||
print('import "github.com/kovidgoyal/kitty/tools/cli"')
|
||||
print('import "kitty/tools/cli"')
|
||||
go_opts = tuple(go_options_for_seq(parse_option_spec(spec)[0]))
|
||||
print(f'type {name}_options struct ''{')
|
||||
for opt in go_opts:
|
||||
@@ -508,7 +517,7 @@ def kitten_clis() -> None:
|
||||
has_underscore = '_' in kitten
|
||||
print(f'package {kitten}')
|
||||
print('import "fmt"')
|
||||
print('import "github.com/kovidgoyal/kitty/tools/cli"')
|
||||
print('import "kitty/tools/cli"')
|
||||
print('var _ = fmt.Sprintf')
|
||||
print('func create_cmd(root *cli.Command, run_func func(*cli.Command, *Options, []string)(int, error)) {')
|
||||
print('ans := root.AddSubCommand(&cli.Command{')
|
||||
@@ -530,7 +539,7 @@ def kitten_clis() -> None:
|
||||
for opt in gopts:
|
||||
print(opt.as_option('ans'))
|
||||
od.append(opt.struct_declaration())
|
||||
ser.append('\n'.join(opt.as_string_for_commandline()))
|
||||
ser.append(opt.as_string_for_commandline())
|
||||
if ac is not None:
|
||||
print(''.join(ac.as_go_code('ans.ArgCompleter', ' = ')))
|
||||
if not kcd:
|
||||
@@ -544,11 +553,8 @@ def kitten_clis() -> None:
|
||||
print('\n'.join(od))
|
||||
print('}')
|
||||
print('func (opts Options) AsCommandLine() (ans []string) {')
|
||||
if ser:
|
||||
print('\t sval := ""')
|
||||
print('\t _ = sval')
|
||||
for x in ser:
|
||||
print('\t' + x)
|
||||
for x in ser:
|
||||
print('\t' + x)
|
||||
print('return')
|
||||
print('}')
|
||||
|
||||
@@ -723,7 +729,7 @@ def update_at_commands() -> None:
|
||||
odef = '\n'.join(opt_def)
|
||||
code = f'''
|
||||
package at
|
||||
import "github.com/kovidgoyal/kitty/tools/cli"
|
||||
import "kitty/tools/cli"
|
||||
type rc_global_options struct {{
|
||||
{sdef}
|
||||
}}
|
||||
@@ -751,7 +757,7 @@ def update_completion() -> None:
|
||||
|
||||
with replace_if_needed('tools/cmd/edit_in_kitty/launch_generated.go'):
|
||||
print('package edit_in_kitty')
|
||||
print('import "github.com/kovidgoyal/kitty/tools/cli"')
|
||||
print('import "kitty/tools/cli"')
|
||||
print('func AddCloneSafeOpts(cmd *cli.Command) {')
|
||||
completion_for_launch_wrappers('cmd')
|
||||
print(''.join(CompletionSpec.from_string('type:file mime:text/* group:"Text files"').as_go_code('cmd.ArgCompleter', ' = ')))
|
||||
|
||||
1
glfw/cocoa_platform.h
vendored
1
glfw/cocoa_platform.h
vendored
@@ -125,7 +125,6 @@ typedef struct _GLFWwindowNS
|
||||
id delegate;
|
||||
id view;
|
||||
id layer;
|
||||
pid_t previous_front_most_application;
|
||||
|
||||
bool maximized;
|
||||
bool retina;
|
||||
|
||||
@@ -1621,12 +1621,6 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
|
||||
@implementation GLFWWindow
|
||||
|
||||
static void
|
||||
handle_screen_size_change(_GLFWwindow *window, NSNotification *notification UNUSED) {
|
||||
if (!window || !window->ns.layer_shell.is_active) return;
|
||||
_glfwPlatformSetLayerShellConfig(window, NULL);
|
||||
}
|
||||
|
||||
- (instancetype)initWithGlfwWindow:(NSRect)contentRect
|
||||
styleMask:(NSWindowStyleMask)style
|
||||
backing:(NSBackingStoreType)backingStoreType
|
||||
@@ -1636,13 +1630,6 @@ handle_screen_size_change(_GLFWwindow *window, NSNotification *notification UNUS
|
||||
if (self != nil) {
|
||||
glfw_window = initWindow;
|
||||
self.tabbingMode = NSWindowTabbingModeDisallowed;
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserverForName:NSApplicationDidChangeScreenParametersNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification * _Nonnull notification) {
|
||||
handle_screen_size_change(glfw_window, notification);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -1650,7 +1637,6 @@ handle_screen_size_change(_GLFWwindow *window, NSNotification *notification UNUS
|
||||
- (void) removeGLFWWindow
|
||||
{
|
||||
glfw_window = NULL;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item {
|
||||
@@ -1940,22 +1926,6 @@ screen_for_window_center(_GLFWwindow *window) {
|
||||
return NSScreen.mainScreen;
|
||||
}
|
||||
|
||||
const GLFWLayerShellConfig*
|
||||
_glfwPlatformGetLayerShellConfig(_GLFWwindow *window) {
|
||||
return &window->ns.layer_shell.config;
|
||||
}
|
||||
|
||||
static NSScreen*
|
||||
screen_for_name(const char *name) {
|
||||
int count = 0;
|
||||
GLFWmonitor **monitors = glfwGetMonitors(&count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
const char *q = glfwGetMonitorName(monitors[i]);
|
||||
if (q && strcmp(q, name) == 0) return ((_GLFWmonitor*)monitors[i])->ns.screen;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
_glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
|
||||
#define config window->ns.layer_shell.config
|
||||
@@ -1986,10 +1956,6 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig
|
||||
// HACK: Changing the style mask can cause the first responder to be cleared
|
||||
[nswindow makeFirstResponder:window->ns.view];
|
||||
NSScreen *screen = screen_for_window_center(window);
|
||||
if (config.output_name[0]) {
|
||||
NSScreen *q = screen_for_name(config.output_name);
|
||||
if (q) screen = q;
|
||||
}
|
||||
unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing;
|
||||
float xscale = (float)config.expected.xscale, yscale = (float)config.expected.yscale;
|
||||
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||
@@ -2031,11 +1997,6 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig
|
||||
x += width - panel_width + 1.;
|
||||
width = panel_width;
|
||||
break;
|
||||
case GLFW_EDGE_CENTER_SIZED:
|
||||
x += (width - panel_width) / 2;
|
||||
y += (height - panel_height) / 2;
|
||||
width = panel_width; height = panel_height;
|
||||
break;
|
||||
default: // top left
|
||||
y += height - panel_height + 1.;
|
||||
height = panel_height; width = panel_width;
|
||||
@@ -2045,10 +2006,8 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig
|
||||
if (height < 1.) height = NSWidth(screen.visibleFrame);
|
||||
}
|
||||
|
||||
if (config.edge != GLFW_EDGE_CENTER_SIZED) {
|
||||
x += config.requested_left_margin; width -= config.requested_left_margin + config.requested_right_margin;
|
||||
y += config.requested_bottom_margin; height -= config.requested_top_margin + config.requested_bottom_margin;
|
||||
}
|
||||
x += config.requested_left_margin; width -= config.requested_left_margin + config.requested_right_margin;
|
||||
y += config.requested_bottom_margin; height -= config.requested_top_margin + config.requested_bottom_margin;
|
||||
|
||||
[nswindow setAnimationBehavior:animation_behavior];
|
||||
[nswindow setLevel:level];
|
||||
@@ -2228,39 +2187,14 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
NSRunningApplication *app = [[NSWorkspace sharedWorkspace] frontmostApplication];
|
||||
window->ns.previous_front_most_application = 0;
|
||||
if (app && app.processIdentifier != getpid()) window->ns.previous_front_most_application = app.processIdentifier;
|
||||
if (window->ns.layer_shell.is_active && window->ns.layer_shell.config.type == GLFW_LAYER_SHELL_BACKGROUND) {
|
||||
[window->ns.object orderBack:nil];
|
||||
} else [window->ns.object orderFront:nil];
|
||||
debug("Previously active application pid: %d bundle identifier: %s\n",
|
||||
window->ns.previous_front_most_application, app ? app.bundleIdentifier.UTF8String : "");
|
||||
}
|
||||
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
{
|
||||
[window->ns.object orderOut:nil];
|
||||
pid_t prev_app_pid = window->ns.previous_front_most_application; window->ns.previous_front_most_application = 0;
|
||||
NSRunningApplication *app;
|
||||
if (window->ns.layer_shell.is_active && prev_app_pid > 0 && (app = [NSRunningApplication runningApplicationWithProcessIdentifier:prev_app_pid])) {
|
||||
unsigned num_visible = 0;
|
||||
for (_GLFWwindow *w = _glfw.windowListHead; w; w = w->next) {
|
||||
if (_glfwPlatformWindowVisible(w)) num_visible++;
|
||||
}
|
||||
if (!num_visible) {
|
||||
// yieldActivationToApplication was introduced in macOS 14 (Sonoma)
|
||||
SEL selector = NSSelectorFromString(@"yieldActivationToApplication:");
|
||||
if ([NSApp respondsToSelector:selector]) {
|
||||
[NSApp performSelector:selector withObject:app];
|
||||
[app activateWithOptions:0];
|
||||
} else {
|
||||
#define NSApplicationActivateIgnoringOtherApps 2
|
||||
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
#undef NSApplicationActivateIgnoringOtherApps
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window UNUSED)
|
||||
@@ -3304,7 +3238,6 @@ glfwGetCocoaKeyEquivalent(uint32_t glfw_key, int glfw_mods, int *cocoa_mods) {
|
||||
return _glfwPlatformGetNativeKeyForKey(glfw_key);
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void) { return true; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
|
||||
11
glfw/dbus_glfw.c
vendored
11
glfw/dbus_glfw.c
vendored
@@ -214,6 +214,13 @@ typedef struct {
|
||||
void *user_data;
|
||||
} MethodResponse;
|
||||
|
||||
static const char*
|
||||
format_message_error(DBusError *err) {
|
||||
static char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "[%s] %s", err->name ? err->name : "", err->message);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
method_reply_received(DBusPendingCall *pending, void *user_data) {
|
||||
MethodResponse *res = (MethodResponse*)user_data;
|
||||
@@ -221,7 +228,7 @@ method_reply_received(DBusPendingCall *pending, void *user_data) {
|
||||
if (msg) {
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (dbus_set_error_from_message(&err, msg)) res->callback(NULL, &err, res->user_data);
|
||||
if (dbus_set_error_from_message(&err, msg)) res->callback(NULL, format_message_error(&err), res->user_data);
|
||||
else res->callback(msg, NULL, res->user_data);
|
||||
}
|
||||
}
|
||||
@@ -236,7 +243,7 @@ call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_p
|
||||
DBusError error; dbus_error_init(&error);
|
||||
RAII_MSG(reply, dbus_connection_send_with_reply_and_block(session_bus, msg, timeout, &error));
|
||||
if (dbus_error_is_set(&error)) {
|
||||
callback(reply, &error, user_data);
|
||||
callback(reply, error.message, user_data);
|
||||
return false;
|
||||
} else if (reply) {
|
||||
callback(reply, NULL, user_data);
|
||||
|
||||
2
glfw/dbus_glfw.h
vendored
2
glfw/dbus_glfw.h
vendored
@@ -33,7 +33,7 @@
|
||||
static inline void cleanup_msg(void *p) { DBusMessage *m = *(DBusMessage**)p; if (m) dbus_message_unref(m); m = NULL; }
|
||||
#define RAII_MSG(name, initializer) __attribute__((cleanup(cleanup_msg))) DBusMessage *name = initializer
|
||||
|
||||
typedef void(*dbus_pending_callback)(DBusMessage *msg, const DBusError *err, void* data);
|
||||
typedef void(*dbus_pending_callback)(DBusMessage *msg, const char* err, void* data);
|
||||
|
||||
typedef struct {
|
||||
EventLoopData* eld;
|
||||
|
||||
@@ -323,12 +323,16 @@ def generate_wrappers(glfw_header: str) -> None:
|
||||
void glfwWaylandRunWithActivationToken(GLFWwindow *handle, GLFWactivationcallback cb, void *cb_data)
|
||||
bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color)
|
||||
void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle)
|
||||
bool glfwWaylandIsLayerShellSupported(void)
|
||||
bool glfwWaylandIsWindowFullyCreated(GLFWwindow *handle)
|
||||
bool glfwWaylandBeep(GLFWwindow *handle)
|
||||
GLFWLayerShellConfig* glfwWaylandLayerShellConfig(GLFWwindow *handle)
|
||||
pid_t glfwWaylandCompositorPID(void)
|
||||
unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
||||
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
||||
void glfwSetX11WindowAsDock(int32_t x11_window_id)
|
||||
void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12])
|
||||
'''.splitlines():
|
||||
if line:
|
||||
functions.append(Function(line.strip(), check_fail=False))
|
||||
|
||||
15
glfw/glfw3.h
vendored
15
glfw/glfw3.h
vendored
@@ -1056,7 +1056,6 @@ typedef enum {
|
||||
|
||||
#define GLFW_WAYLAND_APP_ID 0x00025001
|
||||
#define GLFW_WAYLAND_BGCOLOR 0x00025002
|
||||
#define GLFW_WAYLAND_WINDOW_TAG 0x00025003
|
||||
/*! @} */
|
||||
|
||||
#define GLFW_NO_API 0
|
||||
@@ -1303,24 +1302,19 @@ typedef struct GLFWkeyevent
|
||||
|
||||
typedef enum { GLFW_LAYER_SHELL_NONE, GLFW_LAYER_SHELL_BACKGROUND, GLFW_LAYER_SHELL_PANEL, GLFW_LAYER_SHELL_TOP, GLFW_LAYER_SHELL_OVERLAY } GLFWLayerShellType;
|
||||
|
||||
typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_CENTER, GLFW_EDGE_NONE, GLFW_EDGE_CENTER_SIZED } GLFWEdge;
|
||||
typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_CENTER, GLFW_EDGE_NONE } GLFWEdge;
|
||||
|
||||
typedef enum { GLFW_FOCUS_NOT_ALLOWED, GLFW_FOCUS_EXCLUSIVE, GLFW_FOCUS_ON_DEMAND} GLFWFocusPolicy;
|
||||
|
||||
typedef struct GLFWLayerShellConfig {
|
||||
GLFWLayerShellType type;
|
||||
GLFWEdge edge;
|
||||
struct {
|
||||
GLFWEdge edge;
|
||||
int requested_top_margin, requested_left_margin, requested_bottom_margin, requested_right_margin;
|
||||
} previous;
|
||||
bool was_toggled_to_fullscreen;
|
||||
char output_name[128];
|
||||
char output_name[64];
|
||||
GLFWFocusPolicy focus_policy;
|
||||
unsigned x_size_in_cells, x_size_in_pixels;
|
||||
unsigned y_size_in_cells, y_size_in_pixels;
|
||||
int requested_top_margin, requested_left_margin, requested_bottom_margin, requested_right_margin;
|
||||
int requested_exclusive_zone, hide_on_focus_loss;
|
||||
int requested_exclusive_zone;
|
||||
unsigned override_exclusive_zone;
|
||||
void (*size_callback)(GLFWwindow *window, float xscale, float yscale, unsigned *cell_width, unsigned *cell_height, double *left_edge_spacing, double *top_edge_spacing, double *right_edge_spacing, double *bottom_edge_spacing);
|
||||
struct { float xscale, yscale; } expected;
|
||||
@@ -1983,7 +1977,6 @@ GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun function);
|
||||
GLFWAPI GLFWcurrentselectionfun glfwSetCurrentSelectionCallback(GLFWcurrentselectionfun callback);
|
||||
GLFWAPI GLFWhascurrentselectionfun glfwSetHasCurrentSelectionCallback(GLFWhascurrentselectionfun callback);
|
||||
GLFWAPI GLFWimecursorpositionfun glfwSetIMECursorPositionCallback(GLFWimecursorpositionfun callback);
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void);
|
||||
|
||||
/*! @brief Terminates the GLFW library.
|
||||
*
|
||||
@@ -2386,7 +2379,6 @@ GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, flo
|
||||
* @ingroup monitor
|
||||
*/
|
||||
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
|
||||
GLFWAPI const char* glfwGetMonitorDescription(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Sets the user pointer of the specified monitor.
|
||||
*
|
||||
@@ -2881,7 +2873,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G
|
||||
GLFWAPI bool glfwToggleFullscreen(GLFWwindow *window, unsigned int flags);
|
||||
GLFWAPI bool glfwIsFullscreen(GLFWwindow *window, unsigned int flags);
|
||||
GLFWAPI bool glfwAreSwapsAllowed(const GLFWwindow* window);
|
||||
GLFWAPI const GLFWLayerShellConfig* glfwGetLayerShellConfig(GLFWwindow* handle);
|
||||
GLFWAPI bool glfwSetLayerShellConfig(GLFWwindow* handle, const GLFWLayerShellConfig *value);
|
||||
|
||||
/*! @brief Destroys the specified window and its context.
|
||||
|
||||
12
glfw/ibus_glfw.c
vendored
12
glfw/ibus_glfw.c
vendored
@@ -373,9 +373,9 @@ read_ibus_address(_GLFWIBUSData *ibus) {
|
||||
}
|
||||
|
||||
void
|
||||
input_context_created(DBusMessage *msg, const DBusError *err, void *data) {
|
||||
if (err) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to create input context with error: %s: %s", err->name, err->message);
|
||||
input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
if (errmsg) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to create input context with error: %s", errmsg);
|
||||
return;
|
||||
}
|
||||
const char *path = NULL;
|
||||
@@ -488,15 +488,15 @@ glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h) {
|
||||
}
|
||||
|
||||
void
|
||||
key_event_processed(DBusMessage *msg, const DBusError *err, void *data) {
|
||||
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
uint32_t handled = 0;
|
||||
_GLFWIBUSKeyEvent *ev = (_GLFWIBUSKeyEvent*)data;
|
||||
// Restore key's text from the text embedded in the structure.
|
||||
ev->glfw_ev.text = ev->__embedded_text;
|
||||
bool is_release = ev->glfw_ev.action == GLFW_RELEASE;
|
||||
bool failed = false;
|
||||
if (err) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s: %s", err->name, err->message);
|
||||
if (errmsg) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
|
||||
failed = true;
|
||||
} else {
|
||||
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);
|
||||
|
||||
10
glfw/internal.h
vendored
10
glfw/internal.h
vendored
@@ -331,7 +331,7 @@ struct _GLFWwndconfig
|
||||
char instanceName[256];
|
||||
} x11;
|
||||
struct {
|
||||
char appId[256], windowTag[256];
|
||||
char appId[256];
|
||||
uint32_t bgcolor;
|
||||
} wl;
|
||||
};
|
||||
@@ -490,7 +490,7 @@ struct _GLFWwindow
|
||||
//
|
||||
struct _GLFWmonitor
|
||||
{
|
||||
const char *name, *description;
|
||||
char* name;
|
||||
void* userPointer;
|
||||
|
||||
// Physical dimensions in millimeters.
|
||||
@@ -668,10 +668,6 @@ struct _GLFWlibrary
|
||||
//
|
||||
extern _GLFWlibrary _glfw;
|
||||
|
||||
typedef struct GeometryRect { int x, y, width, height; } GeometryRect;
|
||||
typedef struct MonitorGeometry {
|
||||
GeometryRect full, workarea;
|
||||
} MonitorGeometry;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
@@ -719,7 +715,6 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
int count, const GLFWimage* images);
|
||||
bool _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value);
|
||||
const GLFWLayerShellConfig* _glfwPlatformGetLayerShellConfig(_GLFWwindow* window);
|
||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
|
||||
@@ -883,7 +878,6 @@ unsigned long long _glfwPlatformAddTimer(monotonic_t interval, bool repeats, GLF
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, monotonic_t interval, bool enabled);
|
||||
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
|
||||
int _glfwPlatformSetWindowBlur(_GLFWwindow* handle, int value);
|
||||
MonitorGeometry _glfwPlatformGetMonitorGeometry(_GLFWmonitor* monitor);
|
||||
|
||||
char* _glfw_strdup(const char* source);
|
||||
|
||||
|
||||
40
glfw/linux_desktop_settings.c
vendored
40
glfw/linux_desktop_settings.c
vendored
@@ -24,47 +24,15 @@ static int theme_size = -1;
|
||||
static GLFWColorScheme appearance = GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
||||
static bool cursor_theme_changed = false, appearance_initialized = false;
|
||||
|
||||
#define HANDLER(name_) static void name_(DBusMessage *msg, const DBusError* err, void *data) { \
|
||||
#define HANDLER(name) static void name(DBusMessage *msg, const char* errmsg, void *data) { \
|
||||
(void)data; \
|
||||
if (err) { \
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s: %s", #name_, err->name, err->message); \
|
||||
if (errmsg) { \
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s", #name, errmsg); \
|
||||
return; \
|
||||
}
|
||||
|
||||
HANDLER(get_color_scheme_legacy)
|
||||
DBusMessageIter iter, variant_iter, variant_iter2;
|
||||
if (!dbus_message_iter_init(msg, &iter)) return;
|
||||
dbus_message_iter_recurse(&iter, &variant_iter);
|
||||
int type = dbus_message_iter_get_arg_type(&variant_iter);
|
||||
if (type != DBUS_TYPE_VARIANT) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Read for color-scheme did not return a variant"); return;
|
||||
}
|
||||
dbus_message_iter_recurse(&variant_iter, &variant_iter2);
|
||||
if (type != DBUS_TYPE_VARIANT) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Read for color-scheme did not return a nested variant"); return;
|
||||
}
|
||||
uint32_t val;
|
||||
dbus_message_iter_get_basic(&variant_iter2, &val);
|
||||
if (val < 3) appearance = val;
|
||||
}
|
||||
|
||||
static void
|
||||
get_color_scheme(DBusMessage *msg, const DBusError* err, void *data) {
|
||||
(void) data;
|
||||
if (err) {
|
||||
if (strcmp("org.freedesktop.DBus.Error.UnknownMethod", err->name) == 0) {
|
||||
DBusConnection *session_bus = glfw_dbus_session_bus();
|
||||
if (session_bus) {
|
||||
const char *namespace = FDO_DESKTOP_NAMESPACE, *key = FDO_APPEARANCE_KEY;
|
||||
glfw_dbus_call_blocking_method(session_bus, DESKTOP_SERVICE, DESKTOP_PATH, DESKTOP_INTERFACE, "Read", DBUS_TIMEOUT_USE_DEFAULT,
|
||||
get_color_scheme_legacy, NULL, DBUS_TYPE_STRING, &namespace, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s: %s", "get_color_scheme", err->name, err->message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
HANDLER(get_color_scheme)
|
||||
uint32_t val;
|
||||
DBusMessageIter iter, variant_iter;
|
||||
if (!dbus_message_iter_init(msg, &iter)) return;
|
||||
|
||||
10
glfw/linux_notify.c
vendored
10
glfw/linux_notify.c
vendored
@@ -32,9 +32,9 @@ glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedf
|
||||
}
|
||||
|
||||
void
|
||||
notification_created(DBusMessage *msg, const DBusError* err, void *data) {
|
||||
if (err) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to create notification error: %s: %s", err->name, err->message);
|
||||
notification_created(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
if (errmsg) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to create notification error: %s", errmsg);
|
||||
if (data) free(data);
|
||||
return;
|
||||
}
|
||||
@@ -95,9 +95,9 @@ cancel_user_notification(DBusConnection *session_bus, uint32_t *id) {
|
||||
}
|
||||
|
||||
static void
|
||||
got_capabilities(DBusMessage *msg, const DBusError* err, void* data UNUSED) {
|
||||
got_capabilities(DBusMessage *msg, const char* err, void* data UNUSED) {
|
||||
if (err) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to get server capabilities error: %s: %s", err->name, err->message);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to get server capabilities error: %s", err);
|
||||
return;
|
||||
}
|
||||
#define check_call(func, err, ...) if (!func(__VA_ARGS__)) { _glfwInputError(GLFW_PLATFORM_ERROR, "Notify: GetCapabilities: %s", err); return; }
|
||||
|
||||
15
glfw/monitor.c
vendored
15
glfw/monitor.c
vendored
@@ -186,8 +186,7 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor)
|
||||
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||
|
||||
free(monitor->modes);
|
||||
free((void*)monitor->name);
|
||||
free((void*)monitor->description);
|
||||
free(monitor->name);
|
||||
free(monitor);
|
||||
}
|
||||
|
||||
@@ -394,19 +393,9 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
|
||||
assert(monitor != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return monitor->name ? monitor->name : "";
|
||||
return monitor->name;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetMonitorDescription(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return monitor->description ? monitor->description : "";
|
||||
}
|
||||
|
||||
|
||||
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
"unstable/idle-inhibit/idle-inhibit-unstable-v1.xml",
|
||||
"staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml",
|
||||
"staging/xdg-system-bell/xdg-system-bell-v1.xml",
|
||||
"staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml",
|
||||
|
||||
"kwin-blur-v1.xml",
|
||||
"wlr-layer-shell-unstable-v1.xml"
|
||||
|
||||
13
glfw/window.c
vendored
13
glfw/window.c
vendored
@@ -495,10 +495,6 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value)
|
||||
strncpy(_glfw.hints.window.wl.appId, value,
|
||||
sizeof(_glfw.hints.window.wl.appId) - 1);
|
||||
return;
|
||||
case GLFW_WAYLAND_WINDOW_TAG:
|
||||
strncpy(_glfw.hints.window.wl.windowTag, value,
|
||||
sizeof(_glfw.hints.window.wl.windowTag) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint);
|
||||
@@ -555,15 +551,6 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
|
||||
window->shouldClose = value;
|
||||
}
|
||||
|
||||
GLFWAPI const GLFWLayerShellConfig* glfwGetLayerShellConfig(GLFWwindow* handle) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
return _glfwPlatformGetLayerShellConfig(window);
|
||||
}
|
||||
|
||||
|
||||
GLFWAPI bool glfwSetLayerShellConfig(GLFWwindow* handle, const GLFWLayerShellConfig *value) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
5
glfw/wl_init.c
vendored
5
glfw/wl_init.c
vendored
@@ -605,8 +605,6 @@ static void registryHandleGlobal(void* data UNUSED,
|
||||
}
|
||||
else if (is(xdg_system_bell_v1)) {
|
||||
_glfw.wl.xdg_system_bell_v1 = wl_registry_bind(registry, name, &xdg_system_bell_v1_interface, 1);
|
||||
} else if (is(xdg_toplevel_tag_manager_v1)) {
|
||||
_glfw.wl.xdg_toplevel_tag_manager_v1 = wl_registry_bind(registry, name, &xdg_toplevel_tag_manager_v1_interface, 1);
|
||||
}
|
||||
#undef is
|
||||
}
|
||||
@@ -718,7 +716,6 @@ get_compositor_missing_capabilities(void) {
|
||||
C(cursor_shape, wp_cursor_shape_manager_v1); C(layer_shell, zwlr_layer_shell_v1);
|
||||
C(single_pixel_buffer, wp_single_pixel_buffer_manager_v1); C(preferred_scale, has_preferred_buffer_scale);
|
||||
C(idle_inhibit, idle_inhibit_manager); C(icon, xdg_toplevel_icon_manager_v1); C(bell, xdg_system_bell_v1);
|
||||
C(window-tag, xdg_toplevel_tag_manager_v1);
|
||||
if (_glfw.wl.xdg_wm_base_version < 6) p += snprintf(p, sizeof(buf) - (p - buf), "%s ", "window-state-suspended");
|
||||
if (_glfw.wl.xdg_wm_base_version < 5) p += snprintf(p, sizeof(buf) - (p - buf), "%s ", "window-capabilities");
|
||||
#undef C
|
||||
@@ -897,8 +894,6 @@ void _glfwPlatformTerminate(void)
|
||||
xdg_toplevel_icon_manager_v1_destroy(_glfw.wl.xdg_toplevel_icon_manager_v1);
|
||||
if (_glfw.wl.xdg_system_bell_v1)
|
||||
xdg_system_bell_v1_destroy(_glfw.wl.xdg_system_bell_v1);
|
||||
if (_glfw.wl.xdg_toplevel_tag_manager_v1)
|
||||
xdg_toplevel_tag_manager_v1_destroy(_glfw.wl.xdg_toplevel_tag_manager_v1);
|
||||
if (_glfw.wl.wp_single_pixel_buffer_manager_v1)
|
||||
wp_single_pixel_buffer_manager_v1_destroy(_glfw.wl.wp_single_pixel_buffer_manager_v1);
|
||||
if (_glfw.wl.wp_cursor_shape_manager_v1)
|
||||
|
||||
24
glfw/wl_monitor.c
vendored
24
glfw/wl_monitor.c
vendored
@@ -41,15 +41,20 @@ static void outputHandleGeometry(void* data,
|
||||
int32_t physicalWidth,
|
||||
int32_t physicalHeight,
|
||||
int32_t subpixel UNUSED,
|
||||
const char* make UNUSED,
|
||||
const char* model UNUSED,
|
||||
const char* make,
|
||||
const char* model,
|
||||
int32_t transform UNUSED)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
char name[1024];
|
||||
|
||||
monitor->wl.x = x;
|
||||
monitor->wl.y = y;
|
||||
monitor->widthMM = physicalWidth;
|
||||
monitor->heightMM = physicalHeight;
|
||||
|
||||
snprintf(name, sizeof(name), "%s %s", make, model);
|
||||
monitor->name = _glfw_strdup(name);
|
||||
}
|
||||
|
||||
static void outputHandleMode(void* data,
|
||||
@@ -100,20 +105,15 @@ static void outputHandleName(void* data,
|
||||
struct wl_output* output UNUSED,
|
||||
const char* name) {
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
if (name) {
|
||||
if (monitor->name) free((void*)monitor->name);
|
||||
monitor->name = _glfw_strdup(name);
|
||||
}
|
||||
if (name) strncpy(monitor->wl.friendly_name, name, sizeof(monitor->wl.friendly_name)-1);
|
||||
}
|
||||
|
||||
static void outputHandleDescription(void* data,
|
||||
struct wl_output* output UNUSED,
|
||||
const char* description) {
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
if (description) {
|
||||
if (monitor->description) free((void*)monitor->description);
|
||||
monitor->description = _glfw_strdup(description);
|
||||
}
|
||||
if (description) strncpy(monitor->wl.description, description, sizeof(monitor->wl.description)-1);
|
||||
|
||||
}
|
||||
|
||||
static const struct wl_output_listener outputListener = {
|
||||
@@ -142,8 +142,8 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
||||
return;
|
||||
}
|
||||
|
||||
// The actual name of this output will be set in the handlers.
|
||||
monitor = _glfwAllocMonitor("unnamed", 0, 0);
|
||||
// The actual name of this output will be set in the geometry handler.
|
||||
monitor = _glfwAllocMonitor(NULL, 0, 0);
|
||||
|
||||
output = wl_registry_bind(_glfw.wl.registry,
|
||||
name,
|
||||
|
||||
5
glfw/wl_platform.h
vendored
5
glfw/wl_platform.h
vendored
@@ -68,7 +68,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "wayland-xdg-toplevel-icon-v1-client-protocol.h"
|
||||
#include "wayland-xdg-system-bell-v1-client-protocol.h"
|
||||
#include "wayland-xdg-toplevel-tag-v1-client-protocol.h"
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
@@ -211,7 +210,7 @@ typedef struct _GLFWwindowWayland
|
||||
double cursorPosX, cursorPosY, allCursorPosX, allCursorPosY;
|
||||
|
||||
char* title;
|
||||
char appId[256], windowTag[256];
|
||||
char appId[256];
|
||||
|
||||
// We need to track the monitors the window spans on to calculate the
|
||||
// optimal scaling factor.
|
||||
@@ -341,7 +340,6 @@ typedef struct _GLFWlibraryWayland
|
||||
struct xdg_activation_v1* xdg_activation_v1;
|
||||
struct xdg_toplevel_icon_manager_v1* xdg_toplevel_icon_manager_v1;
|
||||
struct xdg_system_bell_v1* xdg_system_bell_v1;
|
||||
struct xdg_toplevel_tag_manager_v1* xdg_toplevel_tag_manager_v1;
|
||||
struct wp_cursor_shape_manager_v1* wp_cursor_shape_manager_v1;
|
||||
struct wp_cursor_shape_device_v1* wp_cursor_shape_device_v1;
|
||||
struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1;
|
||||
@@ -408,6 +406,7 @@ typedef struct _GLFWmonitorWayland
|
||||
{
|
||||
struct wl_output* output;
|
||||
uint32_t name;
|
||||
char friendly_name[64], description[64];
|
||||
int currentMode;
|
||||
|
||||
int x;
|
||||
|
||||
61
glfw/wl_window.c
vendored
61
glfw/wl_window.c
vendored
@@ -971,25 +971,13 @@ find_output_by_name(const char* name) {
|
||||
if (!name || !name[0]) return NULL;
|
||||
for (int i = 0; i < _glfw.monitorCount; i++) {
|
||||
_GLFWmonitor *m = _glfw.monitors[i];
|
||||
if (strcmp(m->name, name) == 0) return m->wl.output;
|
||||
if (strcmp(m->wl.friendly_name, name) == 0) return m->wl.output;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static enum zwlr_layer_shell_v1_layer
|
||||
get_layer_shell_layer(const _GLFWwindow *window) {
|
||||
enum zwlr_layer_shell_v1_layer which_layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; // Default to background
|
||||
switch (window->wl.layer_shell.config.type) {
|
||||
case GLFW_LAYER_SHELL_BACKGROUND: case GLFW_LAYER_SHELL_NONE: break;
|
||||
case GLFW_LAYER_SHELL_PANEL: which_layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; break;
|
||||
case GLFW_LAYER_SHELL_TOP: which_layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP; break;
|
||||
case GLFW_LAYER_SHELL_OVERLAY: which_layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; break;
|
||||
}
|
||||
return which_layer;
|
||||
}
|
||||
|
||||
static void
|
||||
layer_set_properties(const _GLFWwindow *window, bool during_creation, uint32_t width, uint32_t height) {
|
||||
layer_set_properties(const _GLFWwindow *window, uint32_t width, uint32_t height) {
|
||||
#define config window->wl.layer_shell.config
|
||||
enum zwlr_layer_surface_v1_anchor which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
int exclusive_zone = config.requested_exclusive_zone;
|
||||
@@ -1028,13 +1016,12 @@ layer_set_properties(const _GLFWwindow *window, bool during_creation, uint32_t w
|
||||
if (!config.override_exclusive_zone) exclusive_zone = width;
|
||||
break;
|
||||
case GLFW_EDGE_CENTER:
|
||||
break;
|
||||
case GLFW_EDGE_CENTER_SIZED:
|
||||
panel_width = width; panel_height = height;
|
||||
which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||
break;
|
||||
case GLFW_EDGE_NONE:
|
||||
which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||
panel_width = width; panel_height = height;
|
||||
panel_width = width;
|
||||
panel_height = height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1044,7 +1031,6 @@ layer_set_properties(const _GLFWwindow *window, bool during_creation, uint32_t w
|
||||
zwlr_layer_surface_v1_set_anchor(surface, which_anchor);
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(surface, exclusive_zone);
|
||||
zwlr_layer_surface_v1_set_margin(surface, config.requested_top_margin, config.requested_right_margin, config.requested_bottom_margin, config.requested_left_margin);
|
||||
if (!during_creation) zwlr_layer_surface_v1_set_layer(surface, get_layer_shell_layer(window));
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(surface, focus_policy);
|
||||
#undef surface
|
||||
#undef config
|
||||
@@ -1055,10 +1041,8 @@ calculate_layer_size(_GLFWwindow *window, uint32_t *width, uint32_t *height) {
|
||||
const GLFWLayerShellConfig *config = &window->wl.layer_shell.config;
|
||||
GLFWvidmode m = {0};
|
||||
if (window->wl.monitorsCount) _glfwPlatformGetVideoMode(window->wl.monitors[0], &m);
|
||||
int monitor_width = m.width, monitor_height = m.height;
|
||||
const int y_margin = config->requested_bottom_margin + config->requested_top_margin, x_margin = config->requested_left_margin + config->requested_right_margin;
|
||||
monitor_width = monitor_width > x_margin ? monitor_width - x_margin : 0;
|
||||
monitor_height = monitor_height > y_margin ? monitor_height - y_margin : 0;
|
||||
const int monitor_width = MAX(0, m.width - x_margin), monitor_height = MAX(0, m.height - y_margin);
|
||||
float xscale = (float)config->expected.xscale, yscale = (float)config->expected.yscale;
|
||||
if (window->wl.window_fully_created) _glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||
unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing;
|
||||
@@ -1070,9 +1054,9 @@ calculate_layer_size(_GLFWwindow *window, uint32_t *width, uint32_t *height) {
|
||||
if (!*height) *height = monitor_height;
|
||||
return;
|
||||
}
|
||||
debug("Calculating layer shell window size at scale: %f\n", xscale);
|
||||
const unsigned xsz = config->x_size_in_pixels ? (unsigned)(config->x_size_in_pixels * xscale) : (cell_width * config->x_size_in_cells);
|
||||
const unsigned ysz = config->y_size_in_pixels ? (unsigned)(config->y_size_in_pixels * yscale) : (cell_height * config->y_size_in_cells);
|
||||
debug("Calculating layer shell window size at scale: %f cell_size: %u %u sz: %u %u\n", xscale, cell_width, cell_height, xsz, ysz);
|
||||
if (config->edge == GLFW_EDGE_LEFT || config->edge == GLFW_EDGE_RIGHT) {
|
||||
if (!*height) *height = monitor_height;
|
||||
double spacing = spacing_x;
|
||||
@@ -1092,7 +1076,6 @@ calculate_layer_size(_GLFWwindow *window, uint32_t *width, uint32_t *height) {
|
||||
*width = (uint32_t)(1. + spacing_x);
|
||||
*height = (uint32_t)(1. + spacing_y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1105,6 +1088,8 @@ layer_surface_handle_configure(void* data, struct zwlr_layer_surface_v1* surface
|
||||
window->wl.once.surface_configured = true;
|
||||
update_fully_created_on_configure(window);
|
||||
}
|
||||
GLFWvidmode m = {0};
|
||||
if (window->wl.monitorsCount) _glfwPlatformGetVideoMode(window->wl.monitors[0], &m);
|
||||
calculate_layer_size(window, &width, &height);
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
if ((int)width != window->wl.width || (int)height != window->wl.height) {
|
||||
@@ -1113,7 +1098,7 @@ layer_surface_handle_configure(void* data, struct zwlr_layer_surface_v1* surface
|
||||
window->wl.width = width; window->wl.height = height;
|
||||
resizeFramebuffer(window);
|
||||
_glfwInputWindowDamage(window);
|
||||
layer_set_properties(window, false, window->wl.width, window->wl.height);
|
||||
layer_set_properties(window, window->wl.width, window->wl.height);
|
||||
if (window->wl.wp_viewport) wp_viewport_set_destination(window->wl.wp_viewport, window->wl.width, window->wl.height);
|
||||
}
|
||||
commit_window_surface_if_safe(window);
|
||||
@@ -1142,15 +1127,22 @@ create_layer_shell_surface(_GLFWwindow *window) {
|
||||
}
|
||||
window->decorated = false; // shell windows must not have decorations
|
||||
struct wl_output *wl_output = find_output_by_name(window->wl.layer_shell.config.output_name);
|
||||
enum zwlr_layer_shell_v1_layer which_layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; // Default to background
|
||||
switch (window->wl.layer_shell.config.type) {
|
||||
case GLFW_LAYER_SHELL_BACKGROUND: break; case GLFW_LAYER_SHELL_NONE: break;
|
||||
case GLFW_LAYER_SHELL_PANEL: which_layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; break;
|
||||
case GLFW_LAYER_SHELL_TOP: which_layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP; break;
|
||||
case GLFW_LAYER_SHELL_OVERLAY: which_layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; break;
|
||||
}
|
||||
#define ls window->wl.layer_shell.zwlr_layer_surface_v1
|
||||
ls = zwlr_layer_shell_v1_get_layer_surface(
|
||||
_glfw.wl.zwlr_layer_shell_v1, window->wl.surface, wl_output, get_layer_shell_layer(window), window->wl.appId[0] ? window->wl.appId : "kitty");
|
||||
_glfw.wl.zwlr_layer_shell_v1, window->wl.surface, wl_output, which_layer, "kitty");
|
||||
if (!ls) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: layer-surface creation failed");
|
||||
return false;
|
||||
}
|
||||
zwlr_layer_surface_v1_add_listener(ls, &zwlr_layer_surface_v1_listener, window);
|
||||
layer_set_properties(window, true, window->wl.width, window->wl.height);
|
||||
layer_set_properties(window, window->wl.width, window->wl.height);
|
||||
if (window->wl.wp_viewport) wp_viewport_set_destination(window->wl.wp_viewport, window->wl.width, window->wl.height);
|
||||
commit_window_surface(window);
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
@@ -1198,10 +1190,8 @@ create_window_desktop_surface(_GLFWwindow* window)
|
||||
zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, &xdgDecorationListener, window);
|
||||
}
|
||||
|
||||
if (window->wl.appId[0])
|
||||
if (strlen(window->wl.appId))
|
||||
xdg_toplevel_set_app_id(window->wl.xdg.toplevel, window->wl.appId);
|
||||
if (window->wl.windowTag[0] && _glfw.wl.xdg_toplevel_tag_manager_v1)
|
||||
xdg_toplevel_tag_manager_v1_set_toplevel_tag(_glfw.wl.xdg_toplevel_tag_manager_v1, window->wl.xdg.toplevel, window->wl.windowTag);
|
||||
|
||||
if (window->wl.title)
|
||||
xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title);
|
||||
@@ -1737,7 +1727,7 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
window->wl.visible = true;
|
||||
} else {
|
||||
// workaround for kwin layer shell bug: https://bugs.kde.org/show_bug.cgi?id=503121
|
||||
if (is_layer_shell(window)) layer_set_properties(window, false, window->wl.width, window->wl.height);
|
||||
if (is_layer_shell(window)) layer_set_properties(window, window->wl.width, window->wl.height);
|
||||
window->wl.visible = true;
|
||||
commit_window_surface(window);
|
||||
}
|
||||
@@ -1762,7 +1752,7 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig
|
||||
if (value) window->wl.layer_shell.config = *value;
|
||||
uint32_t width, height;
|
||||
calculate_layer_size(window, &width, &height);
|
||||
layer_set_properties(window, false, width, height);
|
||||
layer_set_properties(window, width, height);
|
||||
commit_window_surface(window);
|
||||
return true;
|
||||
}
|
||||
@@ -2895,12 +2885,11 @@ GLFWAPI void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle) {
|
||||
if (csd_change_title(window)) commit_window_surface_if_safe(window);
|
||||
}
|
||||
|
||||
const GLFWLayerShellConfig*
|
||||
_glfwPlatformGetLayerShellConfig(_GLFWwindow *window) {
|
||||
return &window->wl.layer_shell.config;
|
||||
GLFWAPI GLFWLayerShellConfig* glfwWaylandLayerShellConfig(GLFWwindow *handle) {
|
||||
return &((_GLFWwindow*)handle)->wl.layer_shell.config;
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void) { return _glfw.wl.zwlr_layer_shell_v1 != NULL; }
|
||||
GLFWAPI bool glfwWaylandIsLayerShellSupported(void) { return _glfw.wl.zwlr_layer_shell_v1 != NULL; }
|
||||
|
||||
GLFWAPI bool glfwWaylandIsWindowFullyCreated(GLFWwindow *handle) { return handle != NULL && ((_GLFWwindow*)handle)->wl.window_fully_created; }
|
||||
|
||||
|
||||
72
glfw/x11_init.c
vendored
72
glfw/x11_init.c
vendored
@@ -47,11 +47,16 @@
|
||||
//
|
||||
static Atom getAtomIfSupported(Atom* supportedAtoms,
|
||||
unsigned long atomCount,
|
||||
const Atom atom)
|
||||
const char* atomName)
|
||||
{
|
||||
for (unsigned long i = 0; i < atomCount; i++) {
|
||||
if (supportedAtoms[i] == atom) return atom;
|
||||
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
||||
|
||||
for (unsigned long i = 0; i < atomCount; i++)
|
||||
{
|
||||
if (supportedAtoms[i] == atom)
|
||||
return atom;
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -115,36 +120,39 @@ static void detectEWMH(void)
|
||||
|
||||
// See which of the atoms we support that are supported by the WM
|
||||
|
||||
#define ALL_ATOMS \
|
||||
S(NET_WM_STATE) S(NET_WM_STATE_ABOVE) S(NET_WM_STATE_BELOW) S(NET_WM_STATE_FULLSCREEN) \
|
||||
S(NET_WM_STATE_MAXIMIZED_VERT) S(NET_WM_STATE_MAXIMIZED_HORZ) S(NET_WM_STATE_DEMANDS_ATTENTION) \
|
||||
S(NET_WM_STATE_SKIP_TASKBAR) S(NET_WM_STATE_SKIP_PAGER) S(NET_WM_STATE_STICKY) \
|
||||
\
|
||||
S(NET_WM_FULLSCREEN_MONITORS) S(NET_WM_STRUT_PARTIAL) \
|
||||
\
|
||||
S(NET_WM_WINDOW_TYPE) S(NET_WM_WINDOW_TYPE_NORMAL) S(NET_WM_WINDOW_TYPE_DOCK) S(NET_WM_WINDOW_TYPE_DESKTOP) \
|
||||
S(NET_WM_WINDOW_TYPE_UTILITY) S(NET_WM_WINDOW_TYPE_SPLASH) S(NET_WM_WINDOW_TYPE_DIALOG) S(NET_WM_WINDOW_TYPE_MENU) \
|
||||
S(NET_WM_WINDOW_TYPE_NOTIFICATION) \
|
||||
\
|
||||
S(NET_WORKAREA) S(NET_CURRENT_DESKTOP) S(NET_ACTIVE_WINDOW) S(NET_FRAME_EXTENTS) S(NET_REQUEST_FRAME_EXTENTS) \
|
||||
\
|
||||
S(NET_WM_ALLOWED_ACTIONS) S(NET_WM_ACTION_MOVE) S(NET_WM_ACTION_RESIZE) S(NET_WM_ACTION_MINIMIZE) \
|
||||
S(NET_WM_ACTION_SHADE) S(NET_WM_ACTION_STICK) S(NET_WM_ACTION_MAXIMIZE_HORZ) S(NET_WM_ACTION_MAXIMIZE_VERT) \
|
||||
S(NET_WM_ACTION_FULLSCREEN) S(NET_WM_ACTION_CHANGE_DESKTOP) S(NET_WM_ACTION_CLOSE) S(NET_WM_ACTION_ABOVE) \
|
||||
S(NET_WM_ACTION_BELOW) S(NET_WM_ACTION_ABOVE_BELOW)
|
||||
_glfw.x11.NET_WM_STATE =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE_DOCK =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_DOCK");
|
||||
_glfw.x11.NET_WORKAREA =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||
_glfw.x11.NET_CURRENT_DESKTOP =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
||||
_glfw.x11.NET_ACTIVE_WINDOW =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
||||
_glfw.x11.NET_FRAME_EXTENTS =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
|
||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
_glfw.x11.NET_WM_STRUT_PARTIAL =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STRUT_PARTIAL");
|
||||
|
||||
static const char* atom_names[40] = {
|
||||
#define S(x) "_" #x,
|
||||
ALL_ATOMS
|
||||
};
|
||||
#undef S
|
||||
Atom atoms[arraysz(atom_names)];
|
||||
XInternAtoms(_glfw.x11.display, (char**)atom_names, arraysz(atom_names), False, atoms);
|
||||
unsigned i = 0;
|
||||
#define S(name) _glfw.x11.name = getAtomIfSupported(supportedAtoms, atomCount, atoms[i++]);
|
||||
ALL_ATOMS
|
||||
#undef S
|
||||
#undef ALL_ATOMS
|
||||
XFree(supportedAtoms);
|
||||
}
|
||||
|
||||
|
||||
103
glfw/x11_monitor.c
vendored
103
glfw/x11_monitor.c
vendored
@@ -350,79 +350,96 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor UNUSED,
|
||||
*yscale = _glfw.x11.contentScaleY;
|
||||
}
|
||||
|
||||
MonitorGeometry
|
||||
_glfwPlatformGetMonitorGeometry(_GLFWmonitor *monitor) {
|
||||
MonitorGeometry ans = {0};
|
||||
if (!monitor) return ans;
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) {
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
|
||||
{
|
||||
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
|
||||
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr =
|
||||
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
ans.full.x = ci->x;
|
||||
ans.full.y = ci->y;
|
||||
areaX = ci->x;
|
||||
areaY = ci->y;
|
||||
|
||||
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||
|
||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) {
|
||||
ans.full.width = mi->height;
|
||||
ans.full.height = mi->width;
|
||||
} else {
|
||||
ans.full.width = mi->width;
|
||||
ans.full.height = mi->height;
|
||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||
{
|
||||
areaWidth = mi->height;
|
||||
areaHeight = mi->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
areaWidth = mi->width;
|
||||
areaHeight = mi->height;
|
||||
}
|
||||
|
||||
XRRFreeCrtcInfo(ci);
|
||||
XRRFreeScreenResources(sr);
|
||||
} else {
|
||||
ans.full.width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
|
||||
ans.full.height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
|
||||
}
|
||||
ans.workarea = *(&ans.full);
|
||||
else
|
||||
{
|
||||
areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
|
||||
areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
|
||||
}
|
||||
|
||||
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP) {
|
||||
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP)
|
||||
{
|
||||
Atom* extents = NULL;
|
||||
Atom* desktop = NULL;
|
||||
const unsigned long extentCount = _glfwGetWindowPropertyX11(
|
||||
_glfw.x11.root, _glfw.x11.NET_WORKAREA, XA_CARDINAL, (unsigned char**) &extents);
|
||||
const unsigned long extentCount =
|
||||
_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_WORKAREA,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &extents);
|
||||
|
||||
if (_glfwGetWindowPropertyX11(_glfw.x11.root, _glfw.x11.NET_CURRENT_DESKTOP, XA_CARDINAL, (unsigned char**) &desktop) > 0) {
|
||||
if (extentCount >= 4 && *desktop < extentCount / 4) {
|
||||
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_CURRENT_DESKTOP,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &desktop) > 0)
|
||||
{
|
||||
if (extentCount >= 4 && *desktop < extentCount / 4)
|
||||
{
|
||||
const int globalX = extents[*desktop * 4 + 0];
|
||||
const int globalY = extents[*desktop * 4 + 1];
|
||||
const int globalWidth = extents[*desktop * 4 + 2];
|
||||
const int globalHeight = extents[*desktop * 4 + 3];
|
||||
|
||||
if (ans.workarea.x < globalX) {
|
||||
ans.workarea.width -= globalX - ans.workarea.x;
|
||||
ans.workarea.x = globalX;
|
||||
if (areaX < globalX)
|
||||
{
|
||||
areaWidth -= globalX - areaX;
|
||||
areaX = globalX;
|
||||
}
|
||||
if (ans.workarea.y < globalY) {
|
||||
ans.workarea.height -= globalY - ans.workarea.y;
|
||||
ans.workarea.y = globalY;
|
||||
|
||||
if (areaY < globalY)
|
||||
{
|
||||
areaHeight -= globalY - areaY;
|
||||
areaY = globalY;
|
||||
}
|
||||
if (ans.workarea.x + ans.workarea.width > globalX + globalWidth)
|
||||
ans.workarea.width = globalX - ans.workarea.x + globalWidth;
|
||||
if (ans.workarea.y + ans.workarea.height > globalY + globalHeight)
|
||||
ans.workarea.height = globalY - ans.workarea.y + globalHeight;
|
||||
|
||||
if (areaX + areaWidth > globalX + globalWidth)
|
||||
areaWidth = globalX - areaX + globalWidth;
|
||||
if (areaY + areaHeight > globalY + globalHeight)
|
||||
areaHeight = globalY - areaY + globalHeight;
|
||||
}
|
||||
}
|
||||
if (extents) XFree(extents);
|
||||
if (desktop) XFree(desktop);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) {
|
||||
MonitorGeometry ans = _glfwPlatformGetMonitorGeometry(monitor);
|
||||
if (extents)
|
||||
XFree(extents);
|
||||
if (desktop)
|
||||
XFree(desktop);
|
||||
}
|
||||
|
||||
if (xpos)
|
||||
*xpos = ans.workarea.x;
|
||||
*xpos = areaX;
|
||||
if (ypos)
|
||||
*ypos = ans.workarea.y;
|
||||
*ypos = areaY;
|
||||
if (width)
|
||||
*width = ans.workarea.width;
|
||||
*width = areaWidth;
|
||||
if (height)
|
||||
*height = ans.workarea.height;
|
||||
*height = areaHeight;
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
13
glfw/x11_platform.h
vendored
13
glfw/x11_platform.h
vendored
@@ -205,10 +205,6 @@ typedef struct _GLFWwindowX11
|
||||
// The last position the cursor was warped to by GLFW
|
||||
int warpCursorPosX, warpCursorPosY;
|
||||
|
||||
struct {
|
||||
bool is_active;
|
||||
GLFWLayerShellConfig config;
|
||||
} layer_shell;
|
||||
} _GLFWwindowX11;
|
||||
|
||||
typedef struct MimeAtom {
|
||||
@@ -251,22 +247,19 @@ typedef struct _GLFWlibraryX11
|
||||
Atom WM_STATE;
|
||||
Atom WM_DELETE_WINDOW;
|
||||
Atom NET_WM_NAME;
|
||||
Atom NET_WM_ALLOWED_ACTIONS, NET_WM_ACTION_MOVE, NET_WM_ACTION_RESIZE, NET_WM_ACTION_MINIMIZE, NET_WM_ACTION_SHADE, NET_WM_ACTION_STICK, NET_WM_ACTION_MAXIMIZE_HORZ, NET_WM_ACTION_MAXIMIZE_VERT, NET_WM_ACTION_FULLSCREEN, NET_WM_ACTION_CHANGE_DESKTOP, NET_WM_ACTION_CLOSE, NET_WM_ACTION_ABOVE, NET_WM_ACTION_BELOW, NET_WM_ACTION_ABOVE_BELOW;
|
||||
Atom NET_WM_ICON_NAME;
|
||||
Atom NET_WM_ICON;
|
||||
Atom NET_WM_PID;
|
||||
Atom NET_WM_PING;
|
||||
Atom NET_WM_WINDOW_TYPE, NET_WM_WINDOW_TYPE_NORMAL, NET_WM_WINDOW_TYPE_DOCK, NET_WM_WINDOW_TYPE_DESKTOP, NET_WM_WINDOW_TYPE_UTILITY, NET_WM_WINDOW_TYPE_SPLASH, NET_WM_WINDOW_TYPE_DIALOG, NET_WM_WINDOW_TYPE_MENU, NET_WM_WINDOW_TYPE_NOTIFICATION;
|
||||
Atom NET_WM_WINDOW_TYPE;
|
||||
Atom NET_WM_WINDOW_TYPE_NORMAL;
|
||||
Atom NET_WM_WINDOW_TYPE_DOCK;
|
||||
Atom NET_WM_STATE;
|
||||
Atom NET_WM_STATE_ABOVE;
|
||||
Atom NET_WM_STATE_BELOW;
|
||||
Atom NET_WM_STATE_FULLSCREEN;
|
||||
Atom NET_WM_STATE_MAXIMIZED_VERT;
|
||||
Atom NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
Atom NET_WM_STATE_DEMANDS_ATTENTION;
|
||||
Atom NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom NET_WM_STATE_SKIP_PAGER;
|
||||
Atom NET_WM_STATE_STICKY;
|
||||
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom NET_WM_WINDOW_OPACITY;
|
||||
|
||||
305
glfw/x11_window.c
vendored
305
glfw/x11_window.c
vendored
@@ -530,204 +530,19 @@ static void enableCursor(_GLFWwindow* window)
|
||||
updateCursorImage(window);
|
||||
}
|
||||
|
||||
typedef unsigned long strut_type;
|
||||
|
||||
typedef struct WindowGeometry {
|
||||
int x, y, width, height;
|
||||
bool needs_strut;
|
||||
strut_type struts[12];
|
||||
} WindowGeometry;
|
||||
|
||||
#define config (window->x11.layer_shell.config)
|
||||
|
||||
static _GLFWmonitor*
|
||||
find_monitor_by_name(const char* name) {
|
||||
if (!name || !name[0]) return (_GLFWmonitor*)glfwGetPrimaryMonitor();;
|
||||
for (int i = 0; i < _glfw.monitorCount; i++) {
|
||||
_GLFWmonitor *m = _glfw.monitors[i];
|
||||
if (strcmp(m->name, name) == 0) return m;
|
||||
}
|
||||
return (_GLFWmonitor*)glfwGetPrimaryMonitor();;
|
||||
}
|
||||
|
||||
|
||||
static WindowGeometry
|
||||
calculate_layer_geometry(_GLFWwindow *window) {
|
||||
_GLFWmonitor *monitor = find_monitor_by_name(config.output_name);
|
||||
MonitorGeometry mg = _glfwPlatformGetMonitorGeometry((_GLFWmonitor*)glfwGetPrimaryMonitor());
|
||||
WindowGeometry ans = {0};
|
||||
debug_rendering("Monitor: %s full: %dx%d@%dx%d workarea: %dx%d@%dx%d\n", monitor->name,
|
||||
mg.full.width, mg.full.height, mg.full.x, mg.full.y, mg.workarea.width, mg.workarea.height, mg.workarea.x, mg.workarea.y);
|
||||
ans.width = mg.full.width; ans.height = mg.full.height;
|
||||
ans.x = mg.full.x; ans.y = mg.full.y;
|
||||
ans.needs_strut = config.type == GLFW_LAYER_SHELL_PANEL;
|
||||
if (config.type == GLFW_LAYER_SHELL_BACKGROUND) {
|
||||
ans.x += config.requested_left_margin; ans.y += config.requested_top_margin;
|
||||
ans.width -= config.requested_left_margin + config.requested_right_margin;
|
||||
ans.height -= config.requested_top_margin + config.requested_bottom_margin;
|
||||
return ans;
|
||||
}
|
||||
float xscale = (float)config.expected.xscale, yscale = (float)config.expected.yscale;
|
||||
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||
unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing;
|
||||
config.size_callback((GLFWwindow*)window, xscale, yscale, &cell_width, &cell_height, &left_edge_spacing, &top_edge_spacing, &right_edge_spacing, &bottom_edge_spacing);
|
||||
double spacing_x = left_edge_spacing + right_edge_spacing;
|
||||
double spacing_y = top_edge_spacing + bottom_edge_spacing;
|
||||
double xsz = config.x_size_in_pixels ? (unsigned)(config.x_size_in_pixels * xscale) : (cell_width * config.x_size_in_cells);
|
||||
double ysz = config.y_size_in_pixels ? (unsigned)(config.y_size_in_pixels * yscale) : (cell_height * config.y_size_in_cells);
|
||||
ans.width = (int)(1. + spacing_x + xsz); ans.height = (int)(1. + spacing_y + ysz);
|
||||
GeometryRect m = config.type == GLFW_LAYER_SHELL_TOP || config.type == GLFW_LAYER_SHELL_OVERLAY ? mg.workarea : mg.full;
|
||||
static const struct {
|
||||
unsigned left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x;
|
||||
} s = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
|
||||
switch (config.edge) {
|
||||
case GLFW_EDGE_LEFT:
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.height = m.height - config.requested_bottom_margin - config.requested_top_margin;
|
||||
ans.struts[s.left] = ans.width; ans.struts[s.left_end_y] = ans.height;
|
||||
break;
|
||||
case GLFW_EDGE_RIGHT:
|
||||
ans.x = m.x + m.width - config.requested_right_margin - ans.width;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.height = m.height - config.requested_bottom_margin - config.requested_top_margin;
|
||||
ans.struts[s.right] = ans.width; ans.struts[s.right_end_y] = ans.height;
|
||||
break;
|
||||
case GLFW_EDGE_TOP:
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.width = m.width - config.requested_right_margin - config.requested_left_margin;
|
||||
ans.struts[s.top] = ans.height; ans.struts[s.top_end_x] = ans.width;
|
||||
break;
|
||||
case GLFW_EDGE_BOTTOM:
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.height - config.requested_bottom_margin - ans.height;
|
||||
ans.width = m.width - config.requested_right_margin - config.requested_left_margin;
|
||||
ans.struts[s.bottom] = ans.height; ans.struts[s.bottom_end_x] = ans.width;
|
||||
break;
|
||||
case GLFW_EDGE_CENTER_SIZED:
|
||||
ans.needs_strut = false;
|
||||
ans.x = (m.width - ans.width) / 2;
|
||||
ans.y = (m.height - ans.height) / 2;
|
||||
break;
|
||||
default:
|
||||
ans.needs_strut = false;
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.height = m.height - config.requested_bottom_margin - config.requested_top_margin;
|
||||
ans.width = m.width - config.requested_right_margin - config.requested_left_margin;
|
||||
break;
|
||||
}
|
||||
debug_rendering("Calculating layer geometry at scale: %f cell size: (%u, %u) -> %dx%d@%dx%d needs_strut: %d\n",
|
||||
xscale, cell_width, cell_height, ans.width, ans.height, ans.x, ans.y, ans.needs_strut)
|
||||
return ans;
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void) { return _glfw.x11.NET_WM_WINDOW_TYPE != 0 && _glfw.x11.NET_WM_STATE != 0; }
|
||||
|
||||
|
||||
static bool
|
||||
update_wm_hints(_GLFWwindow *window, const WindowGeometry *wg, const _GLFWwndconfig *wndconfig) {
|
||||
XWMHints* hints = XAllocWMHints();
|
||||
bool is_layer_shell = window->x11.layer_shell.is_active;
|
||||
bool ok = false;
|
||||
if (hints) {
|
||||
ok = true;
|
||||
hints->flags = StateHint | InputHint;
|
||||
hints->initial_state = NormalState;
|
||||
hints->input = true;
|
||||
if (is_layer_shell && config.focus_policy == GLFW_FOCUS_NOT_ALLOWED) hints->input = false;
|
||||
XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
|
||||
XFree(hints);
|
||||
} else _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate WM hints");
|
||||
if (_glfw.x11.NET_WM_WINDOW_TYPE) {
|
||||
Atom type = 0;
|
||||
if (is_layer_shell) {
|
||||
const char *name = NULL;
|
||||
#define S(which) type = _glfw.x11.which; name = #which
|
||||
switch (config.type) {
|
||||
case GLFW_LAYER_SHELL_BACKGROUND: S(NET_WM_WINDOW_TYPE_DESKTOP); break;
|
||||
case GLFW_LAYER_SHELL_PANEL: S(NET_WM_WINDOW_TYPE_DOCK); break;
|
||||
default: S(NET_WM_WINDOW_TYPE_NORMAL); break;
|
||||
}
|
||||
#undef S
|
||||
if (!type) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _%s", name);
|
||||
ok = false;
|
||||
}
|
||||
} else if (_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL) type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;
|
||||
if (type) XChangeProperty(
|
||||
_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char*) &type, 1);
|
||||
} else if (is_layer_shell) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _NET_WM_WINDOW_TYPE");
|
||||
ok = false;
|
||||
}
|
||||
if (is_layer_shell) {
|
||||
if (_glfw.x11.NET_WM_STRUT_PARTIAL) {
|
||||
XChangeProperty(
|
||||
_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace,
|
||||
(unsigned char*)(wg->needs_strut ? wg->struts : (strut_type[12]){0}), 12);
|
||||
} else if (wg->needs_strut) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _NET_WM_STRUT_PARTIAL");
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
updateNormalHints(window, wg->width, wg->height);
|
||||
Atom states[8]; unsigned count = 0;
|
||||
if (is_layer_shell) {
|
||||
_glfwPlatformSetWindowDecorated(window, false);
|
||||
if (_glfw.x11.NET_WM_STATE_STICKY) states[count++] = _glfw.x11.NET_WM_STATE_STICKY;
|
||||
if (_glfw.x11.NET_WM_STATE_SKIP_PAGER) states[count++] = _glfw.x11.NET_WM_STATE_SKIP_PAGER;
|
||||
if (_glfw.x11.NET_WM_STATE_SKIP_TASKBAR) states[count++] = _glfw.x11.NET_WM_STATE_SKIP_TASKBAR;
|
||||
#define S(x) if (_glfw.x11.x) { states[count++] = _glfw.x11.x; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _%s", #x); ok = false; }
|
||||
switch (config.type) {
|
||||
case GLFW_LAYER_SHELL_NONE: break;
|
||||
case GLFW_LAYER_SHELL_BACKGROUND: S(NET_WM_STATE_BELOW); break;
|
||||
case GLFW_LAYER_SHELL_PANEL:
|
||||
// i3 does not support NET_WM_STATE_BELOW but panels work without it
|
||||
if (_glfw.x11.NET_WM_STATE_BELOW) { S(NET_WM_STATE_BELOW); }
|
||||
break;
|
||||
case GLFW_LAYER_SHELL_TOP: case GLFW_LAYER_SHELL_OVERLAY: S(NET_WM_STATE_ABOVE); break;
|
||||
}
|
||||
#undef S
|
||||
} else if (wndconfig) {
|
||||
if (!wndconfig->decorated) _glfwPlatformSetWindowDecorated(window, false);
|
||||
if (_glfw.x11.NET_WM_STATE && !window->monitor) {
|
||||
if (wndconfig->floating) {
|
||||
if (_glfw.x11.NET_WM_STATE_ABOVE) states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;
|
||||
}
|
||||
if (wndconfig->maximized) {
|
||||
if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT && _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) {
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
window->x11.maximized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count && _glfw.x11.NET_WM_STATE) XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_STATE,
|
||||
XA_ATOM, 32, PropModeReplace, (unsigned char*) states, count);
|
||||
}
|
||||
if (!wndconfig && ok) {
|
||||
_glfwPlatformSetWindowPos(window, wg->x, wg->y);
|
||||
_glfwPlatformSetWindowSize(window, wg->width, wg->height);
|
||||
}
|
||||
return ok;
|
||||
#undef config
|
||||
}
|
||||
|
||||
// Create the X11 window (and its colormap)
|
||||
//
|
||||
static bool createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
Visual* visual, int depth)
|
||||
{
|
||||
WindowGeometry wg = {.width=wndconfig->width, .height=wndconfig->height};
|
||||
if (window->x11.layer_shell.is_active) {
|
||||
wg = calculate_layer_geometry(window);
|
||||
window->resizable = false;
|
||||
int width = wndconfig->width;
|
||||
int height = wndconfig->height;
|
||||
|
||||
if (wndconfig->scaleToMonitor)
|
||||
{
|
||||
width *= (int)_glfw.x11.contentScaleX;
|
||||
height *= (int)_glfw.x11.contentScaleY;
|
||||
}
|
||||
|
||||
// Create a colormap based on the visual used by the current context
|
||||
@@ -748,11 +563,10 @@ static bool createNativeWindow(_GLFWwindow* window,
|
||||
_glfwGrabErrorHandlerX11();
|
||||
|
||||
window->x11.parent = _glfw.x11.root;
|
||||
debug_rendering("Creating window with geometry: %dx%d@%dx%d\n", wg.width, wg.height, wg.x, wg.y);
|
||||
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
||||
_glfw.x11.root,
|
||||
wg.x, wg.y, // Position
|
||||
wg.width, wg.height,
|
||||
0, 0, // Position
|
||||
width, height,
|
||||
0, // Border width
|
||||
depth, // Color depth
|
||||
InputOutput,
|
||||
@@ -774,6 +588,39 @@ static bool createNativeWindow(_GLFWwindow* window,
|
||||
_glfw.x11.context,
|
||||
(XPointer) window);
|
||||
|
||||
if (!wndconfig->decorated)
|
||||
_glfwPlatformSetWindowDecorated(window, false);
|
||||
|
||||
if (_glfw.x11.NET_WM_STATE && !window->monitor)
|
||||
{
|
||||
Atom states[3];
|
||||
int count = 0;
|
||||
|
||||
if (wndconfig->floating)
|
||||
{
|
||||
if (_glfw.x11.NET_WM_STATE_ABOVE)
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;
|
||||
}
|
||||
|
||||
if (wndconfig->maximized)
|
||||
{
|
||||
if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
{
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
window->x11.maximized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) states, count);
|
||||
}
|
||||
}
|
||||
|
||||
// Declare the WM protocols supported by GLFW
|
||||
{
|
||||
Atom protocols[] =
|
||||
@@ -796,9 +643,32 @@ static bool createNativeWindow(_GLFWwindow* window,
|
||||
(unsigned char*) &pid, 1);
|
||||
}
|
||||
|
||||
if (!update_wm_hints(window, &wg, wndconfig)) return false;
|
||||
// without this floating window position is incorrect on KDE
|
||||
if (window->x11.layer_shell.is_active) _glfwPlatformSetWindowPos(window, wg.x, wg.y);
|
||||
if (_glfw.x11.NET_WM_WINDOW_TYPE && _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL)
|
||||
{
|
||||
Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) &type, 1);
|
||||
}
|
||||
|
||||
// Set ICCCM WM_HINTS property
|
||||
{
|
||||
XWMHints* hints = XAllocWMHints();
|
||||
if (!hints)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY,
|
||||
"X11: Failed to allocate WM hints");
|
||||
return false;
|
||||
}
|
||||
|
||||
hints->flags = StateHint;
|
||||
hints->initial_state = NormalState;
|
||||
|
||||
XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
||||
updateNormalHints(window, width, height);
|
||||
|
||||
// Set ICCCM WM_CLASS property
|
||||
{
|
||||
@@ -1561,7 +1431,6 @@ static void processEvent(XEvent *event)
|
||||
if (event->xconfigure.width != window->x11.width ||
|
||||
event->xconfigure.height != window->x11.height)
|
||||
{
|
||||
debug_rendering("Window resized to: %d %d from: %d %d\n", event->xconfigure.width, event->xconfigure.height, window->x11.width, window->x11.height);
|
||||
_glfwInputFramebufferSize(window,
|
||||
event->xconfigure.width,
|
||||
event->xconfigure.height);
|
||||
@@ -1596,9 +1465,9 @@ static void processEvent(XEvent *event)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (xpos != window->x11.xpos || ypos != window->x11.ypos)
|
||||
{
|
||||
debug_rendering("Window moved to: %d %d from: %d %d\n", xpos, ypos, window->x11.xpos, window->x11.xpos);
|
||||
_glfwInputWindowPos(window, xpos, ypos);
|
||||
window->x11.xpos = xpos;
|
||||
window->x11.ypos = ypos;
|
||||
@@ -2000,12 +1869,9 @@ void _glfwPushSelectionToManagerX11(void)
|
||||
|
||||
int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, const GLFWLayerShellConfig *lsc)
|
||||
{
|
||||
(void)lsc;
|
||||
Visual* visual = NULL;
|
||||
int depth;
|
||||
if (lsc) {
|
||||
window->x11.layer_shell.is_active = true;
|
||||
window->x11.layer_shell.config = *lsc;
|
||||
} else window->x11.layer_shell.is_active = false;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
@@ -2097,16 +1963,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
const GLFWLayerShellConfig*
|
||||
_glfwPlatformGetLayerShellConfig(_GLFWwindow *window) {
|
||||
return &window->x11.layer_shell.config;
|
||||
}
|
||||
|
||||
bool
|
||||
_glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
|
||||
if (value) window->x11.layer_shell.config = *value;
|
||||
WindowGeometry wg = calculate_layer_geometry(window);
|
||||
update_wm_hints(window, &wg, NULL);
|
||||
bool _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
|
||||
(void)window; (void)value;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2463,11 +2321,6 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
return;
|
||||
|
||||
XMapWindow(_glfw.x11.display, window->x11.handle);
|
||||
// without this floating window position is incorrect on KDE
|
||||
if (window->x11.layer_shell.is_active) {
|
||||
WindowGeometry wg = calculate_layer_geometry(window);
|
||||
_glfwPlatformSetWindowPos(window, wg.x, wg.y);
|
||||
}
|
||||
waitForVisibilityNotify(window);
|
||||
}
|
||||
|
||||
@@ -3420,4 +3273,18 @@ GLFWAPI int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
||||
return XSetCommand(_glfw.x11.display, window->x11.handle, argv, argc);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetX11WindowAsDock(int32_t x11_window_id) {
|
||||
_GLFW_REQUIRE_INIT();
|
||||
Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_DOCK;
|
||||
XChangeProperty(_glfw.x11.display, x11_window_id,
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) &type, 1);
|
||||
}
|
||||
|
||||
|
||||
GLFWAPI void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12]) {
|
||||
_GLFW_REQUIRE_INIT();
|
||||
XChangeProperty(_glfw.x11.display, x11_window_id,
|
||||
_glfw.x11.NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char*) dimensions, 12);
|
||||
}
|
||||
|
||||
8
go.mod
8
go.mod
@@ -1,4 +1,4 @@
|
||||
module github.com/kovidgoyal/kitty
|
||||
module kitty
|
||||
|
||||
go 1.23.0
|
||||
|
||||
@@ -6,7 +6,7 @@ toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/ALTree/bigfloat v0.2.0
|
||||
github.com/alecthomas/chroma/v2 v2.17.2
|
||||
github.com/alecthomas/chroma/v2 v2.17.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1
|
||||
github.com/dlclark/regexp2 v1.11.5
|
||||
github.com/edwvee/exiffix v0.0.0-20240229113213-0dbb146775be
|
||||
@@ -17,8 +17,8 @@ require (
|
||||
github.com/shirou/gopsutil/v3 v3.24.5
|
||||
github.com/zeebo/xxh3 v1.0.2
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
|
||||
golang.org/x/image v0.27.0
|
||||
golang.org/x/sys v0.33.0
|
||||
golang.org/x/image v0.26.0
|
||||
golang.org/x/sys v0.32.0
|
||||
howett.net/plist v1.0.1
|
||||
)
|
||||
|
||||
|
||||
12
go.sum
12
go.sum
@@ -2,8 +2,8 @@ github.com/ALTree/bigfloat v0.2.0 h1:AwNzawrpFuw55/YDVlcPw0F0cmmXrmngBHhVrvdXPvM
|
||||
github.com/ALTree/bigfloat v0.2.0/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.17.2 h1:Rm81SCZ2mPoH+Q8ZCc/9YvzPUN/E7HgPiPJD8SLV6GI=
|
||||
github.com/alecthomas/chroma/v2 v2.17.2/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
||||
github.com/alecthomas/chroma/v2 v2.17.0 h1:3r2Cgk+nXNICMBxIFGnTRTbQFUwMiLisW+9uos0TtUI=
|
||||
github.com/alecthomas/chroma/v2 v2.17.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
|
||||
@@ -63,15 +63,15 @@ github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaD
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
|
||||
golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
|
||||
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
|
||||
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
|
||||
@@ -4,13 +4,13 @@ package ask
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/cli/markup"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/style"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"io"
|
||||
"kitty/tools/cli/markup"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/style"
|
||||
"kitty/tools/wcswidth"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/readline"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/readline"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/cli/markup"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/cli/markup"
|
||||
"kitty/tools/tui"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -2,10 +2,10 @@ package choose_fonts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/subseq"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/subseq"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/readline"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/readline"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/readline"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/style"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/readline"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/style"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/loop"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -2,7 +2,7 @@ package choose_fonts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/utils"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/shlex"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,7 +5,7 @@ package clipboard
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"kitty/tools/cli"
|
||||
)
|
||||
|
||||
func run_mime_loop(opts *Options, args []string) (err error) {
|
||||
|
||||
@@ -14,10 +14,10 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
@@ -201,7 +201,7 @@ func unescape_metadata_value(k, x string) (ans string) {
|
||||
return x
|
||||
}
|
||||
|
||||
func Encode_bytes(metadata map[string]string, payload []byte) string {
|
||||
func encode_bytes(metadata map[string]string, payload []byte) string {
|
||||
ans := strings.Builder{}
|
||||
enc_payload := ""
|
||||
if len(payload) > 0 {
|
||||
@@ -228,7 +228,7 @@ func Encode_bytes(metadata map[string]string, payload []byte) string {
|
||||
}
|
||||
|
||||
func encode(metadata map[string]string, payload string) string {
|
||||
return Encode_bytes(metadata, utils.UnsafeStringToBytes(payload))
|
||||
return encode_bytes(metadata, utils.UnsafeStringToBytes(payload))
|
||||
}
|
||||
|
||||
func error_from_status(status string) error {
|
||||
|
||||
@@ -8,11 +8,10 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
@@ -38,7 +37,12 @@ func (self *Input) has_mime_matching(predicate func(string) bool) bool {
|
||||
if predicate(self.mime_type) {
|
||||
return true
|
||||
}
|
||||
return slices.ContainsFunc(self.extra_mime_types, predicate)
|
||||
for _, i := range self.extra_mime_types {
|
||||
if predicate(i) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func write_loop(inputs []*Input, opts *Options) (err error) {
|
||||
@@ -95,7 +99,7 @@ func write_loop(inputs []*Input, opts *Options) (err error) {
|
||||
i := inputs[0]
|
||||
n, err := i.src.Read(buf[:])
|
||||
if n > 0 {
|
||||
waiting_for_write = lp.QueueWriteString(Encode_bytes(make_metadata("wdata", i.mime_type), buf[:n]))
|
||||
waiting_for_write = lp.QueueWriteString(encode_bytes(make_metadata("wdata", i.mime_type), buf[:n]))
|
||||
}
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/utils"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
|
||||
"github.com/alecthomas/chroma/v2"
|
||||
"github.com/alecthomas/chroma/v2/lexers"
|
||||
|
||||
@@ -6,18 +6,17 @@ import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/kittens/ssh"
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/kittens/ssh"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
@@ -37,33 +36,16 @@ var conf *Config
|
||||
var opts *Options
|
||||
var lp *loop.Loop
|
||||
|
||||
var temp_files []string
|
||||
|
||||
func resolve_path(path string) (ans string, is_dir bool, err error) {
|
||||
var s fs.FileInfo
|
||||
if s, err = os.Stat(path); err != nil {
|
||||
return
|
||||
} else {
|
||||
if s.Mode()&fs.ModeNamedPipe != 0 {
|
||||
var src, dest *os.File
|
||||
if src, err = os.Open(path); err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
if dest, err = os.CreateTemp("", fmt.Sprintf("*-pipe-%s", filepath.Base(path))); err != nil {
|
||||
return
|
||||
}
|
||||
defer dest.Close()
|
||||
temp_files = append(temp_files, dest.Name())
|
||||
if _, err = io.Copy(dest, src); err != nil {
|
||||
return
|
||||
}
|
||||
return dest.Name(), false, nil
|
||||
|
||||
} else {
|
||||
return path, s.IsDir(), nil
|
||||
}
|
||||
func isdir(path string) bool {
|
||||
if s, err := os.Stat(path); err == nil {
|
||||
return s.IsDir()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func exists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func get_ssh_file(hostname, rpath string) (string, error) {
|
||||
@@ -151,22 +133,15 @@ func main(_ *cli.Command, opts_ *Options, args []string) (rc int, err error) {
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
defer func() {
|
||||
for _, path := range temp_files {
|
||||
os.Remove(path)
|
||||
}
|
||||
}()
|
||||
var left_is_dir, right_is_dir bool
|
||||
if left, left_is_dir, err = resolve_path(left); err != nil {
|
||||
return 1, err
|
||||
}
|
||||
if right, right_is_dir, err = resolve_path(right); err != nil {
|
||||
return 1, err
|
||||
}
|
||||
if left_is_dir != right_is_dir {
|
||||
if isdir(left) != isdir(right) {
|
||||
return 1, fmt.Errorf("The items to be diffed should both be either directories or files. Comparing a directory to a file is not valid.'")
|
||||
}
|
||||
|
||||
if !exists(left) {
|
||||
return 1, fmt.Errorf("%s does not exist", left)
|
||||
}
|
||||
if !exists(right) {
|
||||
return 1, fmt.Errorf("%s does not exist", right)
|
||||
}
|
||||
lp, err = loop.New()
|
||||
loop.MouseTrackingMode(lp, loop.BUTTONS_AND_DRAG_MOUSE_TRACKING)
|
||||
if err != nil {
|
||||
|
||||
@@ -8,13 +8,13 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/utils/shlex"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/sgr"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/style"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/sgr"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/style"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -8,13 +8,13 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/readline"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/readline"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -11,13 +11,13 @@ import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/style"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/style"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -19,10 +19,10 @@ import (
|
||||
"github.com/dlclark/regexp2"
|
||||
"github.com/seancfoley/ipaddress-go/ipaddr"
|
||||
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,8 +5,8 @@ package hints
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty"
|
||||
"kitty/tools/utils"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/utils"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ package hyperlinked_grep
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
"kitty/tools/utils/shlex"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/utils/shm"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,8 +5,8 @@ package icat
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/utils/images"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -11,13 +11,13 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/style"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/utils/style"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -222,7 +222,7 @@ func main(cmd *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
keep_going.Store(true)
|
||||
if !opts.DetectSupport && num_of_items > 0 {
|
||||
num_workers := utils.Max(1, utils.Min(num_of_items, runtime.NumCPU()))
|
||||
for range num_workers {
|
||||
for i := 0; i < num_workers; i++ {
|
||||
go run_worker()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ package icat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"image"
|
||||
"image/gif"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/utils/shm"
|
||||
|
||||
"github.com/edwvee/exiffix"
|
||||
"github.com/kovidgoyal/imaging"
|
||||
|
||||
@@ -15,11 +15,11 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/utils/shm"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -8,20 +8,20 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"io"
|
||||
"kitty"
|
||||
"math"
|
||||
not_rand "math/rand/v2"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/graphics"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/images"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/images"
|
||||
"kitty/tools/utils/shm"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/simdstring"
|
||||
"kitty/tools/simdstring"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tty"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package panel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
func complete_kitty_listen_on(completions *cli.Completions, word string, arg_num int) {
|
||||
if !strings.Contains(word, ":") {
|
||||
mg := completions.AddMatchGroup("Address family")
|
||||
mg.NoTrailingSpace = true
|
||||
for _, q := range []string{"unix:", "tcp:"} {
|
||||
if strings.HasPrefix(q, word) {
|
||||
mg.AddMatch(q)
|
||||
}
|
||||
}
|
||||
} else if strings.HasPrefix(word, "unix:") && !strings.HasPrefix(word, "unix:@") {
|
||||
cli.FnmatchCompleter("UNIX sockets", cli.CWD, "*")(completions, word[len("unix:"):], arg_num)
|
||||
completions.AddPrefixToAllMatches("unix:")
|
||||
}
|
||||
}
|
||||
|
||||
var CompleteKittyListenOn = complete_kitty_listen_on
|
||||
|
||||
func GetQuickAccessKittyExe() (kitty_exe string, err error) {
|
||||
if kitty_exe, err = filepath.EvalSymlinks(utils.KittyExe()); err != nil {
|
||||
return "", fmt.Errorf("Failed to find path to the kitty executable, this kitten requires the kitty executable to function. The kitty executable or a symlink to it must be placed in the same directory as the kitten executable. Error: %w", err)
|
||||
}
|
||||
if runtime.GOOS == "darwin" {
|
||||
q := filepath.Join(filepath.Dir(filepath.Dir(kitty_exe)), "kitty-quick-access.app", "Contents", "MacOS", "kitty-quick-access")
|
||||
if err := unix.Access(q, unix.X_OK); err == nil {
|
||||
kitty_exe = q
|
||||
}
|
||||
}
|
||||
return kitty_exe, nil
|
||||
|
||||
}
|
||||
|
||||
func main(cmd *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
kitty_exe, err := GetQuickAccessKittyExe()
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
argv := []string{kitty_exe, "+kitten", "panel"}
|
||||
argv = append(argv, o.AsCommandLine()...)
|
||||
err = unix.Exec(kitty_exe, append(argv, args...), os.Environ())
|
||||
rc = 1
|
||||
return
|
||||
}
|
||||
|
||||
func EntryPoint(parent *cli.Command) {
|
||||
create_cmd(parent, main)
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
from contextlib import suppress
|
||||
from functools import partial
|
||||
from typing import Iterable, Mapping, Sequence
|
||||
from typing import Any, Mapping, Sequence
|
||||
|
||||
from kitty.cli import parse_args
|
||||
from kitty.cli_stub import PanelCLIOptions
|
||||
from kitty.constants import is_macos, kitten_exe
|
||||
from kitty.constants import is_macos, is_wayland, kitten_exe
|
||||
from kitty.fast_data_types import (
|
||||
GLFW_EDGE_BOTTOM,
|
||||
GLFW_EDGE_CENTER,
|
||||
GLFW_EDGE_CENTER_SIZED,
|
||||
GLFW_EDGE_LEFT,
|
||||
GLFW_EDGE_NONE,
|
||||
GLFW_EDGE_RIGHT,
|
||||
@@ -25,29 +24,111 @@ from kitty.fast_data_types import (
|
||||
GLFW_LAYER_SHELL_OVERLAY,
|
||||
GLFW_LAYER_SHELL_PANEL,
|
||||
GLFW_LAYER_SHELL_TOP,
|
||||
set_layer_shell_config,
|
||||
glfw_primary_monitor_size,
|
||||
make_x11_window_a_dock_window,
|
||||
toggle_os_window_visibility,
|
||||
)
|
||||
from kitty.simple_cli_definitions import build_panel_cli_spec
|
||||
from kitty.os_window_size import WindowSizeData, edge_spacing
|
||||
from kitty.simple_cli_definitions import panel_kitten_options_spec
|
||||
from kitty.types import LayerShellConfig
|
||||
from kitty.typing_compat import BossType
|
||||
from kitty.typing_compat import BossType, EdgeLiteral
|
||||
from kitty.utils import log_error
|
||||
|
||||
quake = (
|
||||
'kitty +kitten panel --edge=top --layer=overlay --lines=25 --focus-policy=exclusive'
|
||||
' -o background_opacity=0.8 --toggle-visibility --single-instance --instance-group=quake'
|
||||
)
|
||||
default_quake_cmdline = f'{quake} --exclusive-zone=0 --override-exclusive-zone --detach'
|
||||
default_macos_quake_cmdline = f'{quake}'
|
||||
|
||||
|
||||
args = PanelCLIOptions()
|
||||
help_text = 'Use a command line program to draw a GPU accelerated panel on your desktop'
|
||||
usage = '[cmdline-to-run ...]'
|
||||
|
||||
|
||||
def panel_kitten_options_spec() -> str:
|
||||
if not hasattr(panel_kitten_options_spec, 'ans'):
|
||||
setattr(panel_kitten_options_spec, 'ans', build_panel_cli_spec({}))
|
||||
ans: str = getattr(panel_kitten_options_spec, 'ans')
|
||||
return ans
|
||||
|
||||
def parse_panel_args(args: list[str]) -> tuple[PanelCLIOptions, list[str]]:
|
||||
return parse_args(args, panel_kitten_options_spec, usage, help_text, 'kitty +kitten panel', result_class=PanelCLIOptions)
|
||||
|
||||
|
||||
Strut = tuple[int, int, int, int, int, int, int, int, int, int, int, int]
|
||||
|
||||
|
||||
def create_strut(
|
||||
win_id: int,
|
||||
left: int = 0, right: int = 0, top: int = 0, bottom: int = 0, left_start_y: int = 0, left_end_y: int = 0,
|
||||
right_start_y: int = 0, right_end_y: int = 0, top_start_x: int = 0, top_end_x: int = 0,
|
||||
bottom_start_x: int = 0, bottom_end_x: int = 0
|
||||
) -> Strut:
|
||||
return left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x
|
||||
|
||||
|
||||
def create_top_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, top=height, top_end_x=width)
|
||||
|
||||
|
||||
def create_bottom_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, bottom=height, bottom_end_x=width)
|
||||
|
||||
|
||||
def create_left_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, left=width, left_end_y=height)
|
||||
|
||||
|
||||
def create_right_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, right=width, right_end_y=height)
|
||||
|
||||
|
||||
window_width = window_height = 0
|
||||
|
||||
|
||||
def setup_x11_window(win_id: int) -> None:
|
||||
if is_wayland():
|
||||
return
|
||||
try:
|
||||
func = globals()[f'create_{args.edge}_strut']
|
||||
except KeyError:
|
||||
raise SystemExit(f'The value {args.edge} is not support for --edge on X11')
|
||||
strut = func(win_id, window_width, window_height)
|
||||
make_x11_window_a_dock_window(win_id, strut)
|
||||
|
||||
|
||||
def initial_window_size_func(opts: WindowSizeData, cached_values: dict[str, Any]) -> Callable[[int, int, float, float, float, float], tuple[int, int]]:
|
||||
|
||||
def es(which: EdgeLiteral) -> float:
|
||||
return edge_spacing(which, opts)
|
||||
|
||||
def initial_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> tuple[int, int]:
|
||||
if not is_macos and not is_wayland():
|
||||
# Not sure what the deal with scaling on X11 is
|
||||
xscale = yscale = 1
|
||||
global window_width, window_height
|
||||
monitor_width, monitor_height = glfw_primary_monitor_size()
|
||||
x = dual_distance(args.columns, min_cell_value_if_no_pixels=1)
|
||||
rwidth = x[1] if x[1] else (x[0] * cell_width / xscale)
|
||||
x = dual_distance(args.lines, min_cell_value_if_no_pixels=1)
|
||||
rheight = x[1] if x[1] else (x[0] * cell_width / yscale)
|
||||
|
||||
if args.edge in {'left', 'right'}:
|
||||
spacing = es('left') + es('right')
|
||||
window_width = int(rwidth + (dpi_x / 72) * spacing + 1)
|
||||
window_height = monitor_height
|
||||
elif args.edge in {'top', 'bottom'}:
|
||||
spacing = es('top') + es('bottom')
|
||||
window_height = int(rheight + (dpi_y / 72) * spacing + 1)
|
||||
window_width = monitor_width
|
||||
elif args.edge in {'background', 'center'}:
|
||||
window_width, window_height = monitor_width, monitor_height
|
||||
else:
|
||||
x_spacing = es('left') + es('right')
|
||||
window_width = int(rwidth + (dpi_x / 72) * x_spacing + 1)
|
||||
y_spacing = es('top') + es('bottom')
|
||||
window_height = int(rheight + (dpi_y / 72) * y_spacing + 1)
|
||||
return window_width, window_height
|
||||
|
||||
return initial_window_size
|
||||
|
||||
|
||||
def dual_distance(spec: str, min_cell_value_if_no_pixels: int = 0) -> tuple[int, int]:
|
||||
with suppress(Exception):
|
||||
return int(spec), 0
|
||||
@@ -67,14 +148,11 @@ def layer_shell_config(opts: PanelCLIOptions) -> LayerShellConfig:
|
||||
}.get(opts.layer, GLFW_LAYER_SHELL_PANEL)
|
||||
ltype = GLFW_LAYER_SHELL_BACKGROUND if opts.edge == 'background' else ltype
|
||||
edge = {
|
||||
'top': GLFW_EDGE_TOP, 'bottom': GLFW_EDGE_BOTTOM, 'left': GLFW_EDGE_LEFT, 'right': GLFW_EDGE_RIGHT,
|
||||
'center': GLFW_EDGE_CENTER, 'none': GLFW_EDGE_NONE, 'center-sized': GLFW_EDGE_CENTER_SIZED,
|
||||
'top': GLFW_EDGE_TOP, 'bottom': GLFW_EDGE_BOTTOM, 'left': GLFW_EDGE_LEFT, 'right': GLFW_EDGE_RIGHT, 'center': GLFW_EDGE_CENTER, 'none': GLFW_EDGE_NONE
|
||||
}.get(opts.edge, GLFW_EDGE_TOP)
|
||||
focus_policy = {
|
||||
'not-allowed': GLFW_FOCUS_NOT_ALLOWED, 'exclusive': GLFW_FOCUS_EXCLUSIVE, 'on-demand': GLFW_FOCUS_ON_DEMAND
|
||||
}.get(opts.focus_policy, GLFW_FOCUS_NOT_ALLOWED)
|
||||
if opts.hide_on_focus_loss:
|
||||
focus_policy = GLFW_FOCUS_ON_DEMAND
|
||||
x, y = dual_distance(opts.columns, min_cell_value_if_no_pixels=1), dual_distance(opts.lines, min_cell_value_if_no_pixels=1)
|
||||
return LayerShellConfig(type=ltype,
|
||||
edge=edge,
|
||||
@@ -87,49 +165,22 @@ def layer_shell_config(opts: PanelCLIOptions) -> LayerShellConfig:
|
||||
focus_policy=focus_policy,
|
||||
requested_exclusive_zone=opts.exclusive_zone,
|
||||
override_exclusive_zone=opts.override_exclusive_zone,
|
||||
hide_on_focus_loss=opts.hide_on_focus_loss,
|
||||
output_name=opts.output_name or '')
|
||||
|
||||
|
||||
mtime_map: dict[str, float] = {}
|
||||
|
||||
|
||||
def have_config_files_been_updated(config_files: Iterable[str]) -> bool:
|
||||
ans = False
|
||||
for cf in config_files:
|
||||
try:
|
||||
mtime = os.path.getmtime(cf)
|
||||
except OSError:
|
||||
mtime = 0
|
||||
if mtime_map.get(cf, 0) != mtime:
|
||||
ans = True
|
||||
mtime_map[cf] = mtime
|
||||
return ans
|
||||
|
||||
|
||||
def handle_single_instance_command(boss: BossType, sys_args: Sequence[str], environ: Mapping[str, str], notify_on_os_window_death: str | None = '') -> None:
|
||||
global args
|
||||
from kitty.cli import parse_override
|
||||
from kitty.main import run_app
|
||||
from kitty.tabs import SpecialWindow
|
||||
try:
|
||||
new_args, items = parse_panel_args(list(sys_args[1:]))
|
||||
args, items = parse_panel_args(list(sys_args[1:]))
|
||||
except BaseException as e:
|
||||
log_error(f'Invalid arguments received over single instance socket: {sys_args} with error: {e}')
|
||||
return
|
||||
lsc = layer_shell_config(new_args)
|
||||
layer_shell_config_changed = lsc != run_app.layer_shell_config
|
||||
config_changed = have_config_files_been_updated(new_args.config) or args.config != new_args.config or args.override != new_args.override
|
||||
args = new_args
|
||||
if config_changed:
|
||||
boss.load_config_file(*args.config, overrides=tuple(map(parse_override, new_args.override)))
|
||||
if args.toggle_visibility and boss.os_window_map:
|
||||
for os_window_id in boss.os_window_map:
|
||||
toggle_os_window_visibility(os_window_id)
|
||||
if layer_shell_config_changed:
|
||||
set_layer_shell_config(os_window_id, lsc)
|
||||
return
|
||||
items = items or [kitten_exe(), 'run-shell']
|
||||
lsc = layer_shell_config(args)
|
||||
os_window_id = boss.add_os_panel(lsc, args.cls, args.name)
|
||||
if notify_on_os_window_death:
|
||||
boss.os_window_death_actions[os_window_id] = partial(boss.notify_on_os_window_death, notify_on_os_window_death)
|
||||
@@ -138,18 +189,8 @@ def handle_single_instance_command(boss: BossType, sys_args: Sequence[str], envi
|
||||
|
||||
|
||||
def main(sys_args: list[str]) -> None:
|
||||
# run_kitten run using runpy.run_module which does not import into
|
||||
# sys.modules, which means the module will be re-imported later, causing
|
||||
# global variables to be duplicated, so do it now.
|
||||
from kittens.panel.main import actual_main
|
||||
actual_main(sys_args)
|
||||
return
|
||||
|
||||
|
||||
def actual_main(sys_args: list[str]) -> None:
|
||||
global args
|
||||
args, items = parse_panel_args(sys_args[1:])
|
||||
have_config_files_been_updated(args.config)
|
||||
sys.argv = ['kitty']
|
||||
if args.debug_rendering:
|
||||
sys.argv.append('--debug-rendering')
|
||||
@@ -179,6 +220,9 @@ def actual_main(sys_args: list[str]) -> None:
|
||||
from kitty.main import run_app
|
||||
run_app.cached_values_name = 'panel'
|
||||
run_app.layer_shell_config = layer_shell_config(args)
|
||||
if not is_macos:
|
||||
run_app.first_window_callback = setup_x11_window
|
||||
run_app.initial_window_size_func = initial_window_size_func
|
||||
real_main(called_from_panel=True)
|
||||
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@ package query_terminal
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"kitty"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tui/loop"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
package quick_access_terminal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/kovidgoyal/kitty/kittens/panel"
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
var complete_kitty_listen_on = panel.CompleteKittyListenOn
|
||||
|
||||
func load_config(opts *Options) (ans *Config, err error) {
|
||||
ans = NewConfig()
|
||||
p := config.ConfigParser{LineHandler: ans.Parse}
|
||||
err = p.LoadConfig("quick-access-terminal.conf", opts.Config, opts.Override)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ans, nil
|
||||
}
|
||||
|
||||
func main(cmd *cli.Command, opts *Options, args []string) (rc int, err error) {
|
||||
conf, err := load_config(opts)
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
kitty_exe, err := panel.GetQuickAccessKittyExe()
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
argv := []string{kitty_exe, "+kitten", "panel", "--toggle-visibility", "--exclusive-zone=0", "--override-exclusive-zone", "--layer=overlay", "--single-instance"}
|
||||
argv = append(argv, fmt.Sprintf("--lines=%s", conf.Lines))
|
||||
argv = append(argv, fmt.Sprintf("--columns=%s", conf.Columns))
|
||||
argv = append(argv, fmt.Sprintf("--edge=%s", conf.Edge))
|
||||
if conf.Margin_top != 0 {
|
||||
argv = append(argv, fmt.Sprintf("--margin-top=%d", conf.Margin_top))
|
||||
}
|
||||
if conf.Margin_bottom != 0 {
|
||||
argv = append(argv, fmt.Sprintf("--margin-bottom=%d", conf.Margin_bottom))
|
||||
}
|
||||
if conf.Margin_left != 0 {
|
||||
argv = append(argv, fmt.Sprintf("--margin-left=%d", conf.Margin_left))
|
||||
}
|
||||
if conf.Margin_right != 0 {
|
||||
argv = append(argv, fmt.Sprintf("--margin-right=%d", conf.Margin_right))
|
||||
}
|
||||
if len(conf.Kitty_conf) > 0 {
|
||||
for _, c := range conf.Kitty_conf {
|
||||
argv = append(argv, fmt.Sprintf("--config=%s", c))
|
||||
}
|
||||
}
|
||||
if len(conf.Kitty_override) > 0 {
|
||||
for _, c := range conf.Kitty_override {
|
||||
argv = append(argv, fmt.Sprintf("--override=%s", c))
|
||||
}
|
||||
}
|
||||
|
||||
argv = append(argv, fmt.Sprintf("--override=background_opacity=%f", conf.Background_opacity))
|
||||
if runtime.GOOS != "darwin" {
|
||||
argv = append(argv, fmt.Sprintf("--app-id=%s", conf.App_id))
|
||||
}
|
||||
if conf.Output_name != "" {
|
||||
argv = append(argv, fmt.Sprintf("--output-name=%s", conf.Output_name))
|
||||
}
|
||||
argv = append(argv, fmt.Sprintf("--focus-policy=%s", conf.Focus_policy))
|
||||
if conf.Start_as_hidden {
|
||||
argv = append(argv, `--start-as-hidden`)
|
||||
}
|
||||
if conf.Hide_on_focus_loss {
|
||||
argv = append(argv, `--hide-on-focus-loss`)
|
||||
}
|
||||
if opts.DebugRendering {
|
||||
argv = append(argv, `--debug-rendering`)
|
||||
}
|
||||
if opts.Detach {
|
||||
argv = append(argv, `--detach`)
|
||||
}
|
||||
if opts.DetachedLog != "" {
|
||||
if dl, err := filepath.Abs(opts.DetachedLog); err != nil {
|
||||
return 1, err
|
||||
} else {
|
||||
argv = append(argv, dl)
|
||||
}
|
||||
}
|
||||
if opts.InstanceGroup != "" {
|
||||
argv = append(argv, fmt.Sprintf("--instance-group=%s", opts.InstanceGroup))
|
||||
}
|
||||
|
||||
argv = append(argv, args...)
|
||||
err = unix.Exec(kitty_exe, argv, os.Environ())
|
||||
rc = 1
|
||||
return
|
||||
}
|
||||
|
||||
func EntryPoint(parent *cli.Command) {
|
||||
create_cmd(parent, main)
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# License: GPLv3 Copyright: 2025, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import sys
|
||||
|
||||
from kitty.conf.types import Definition
|
||||
from kitty.constants import appname
|
||||
from kitty.simple_cli_definitions import CONFIG_HELP
|
||||
|
||||
help_text = 'A quick access terminal window that you can bring up instantly with a keypress or a command.'
|
||||
|
||||
definition = Definition(
|
||||
'!kittens.quick_access_terminal',
|
||||
)
|
||||
|
||||
agr = definition.add_group
|
||||
egr = definition.end_group
|
||||
opt = definition.add_option
|
||||
|
||||
agr('qat', 'Window appearance')
|
||||
|
||||
opt('lines', '25',
|
||||
long_text='''
|
||||
The number of lines shown in the window, when the window is along the top or bottom edges of the screen.
|
||||
If it has the suffix :code:`px` then it sets the height of the window in pixels instead of lines.
|
||||
''',)
|
||||
|
||||
opt('columns', '80',
|
||||
long_text='''
|
||||
The number of columns shown in the window, when the window is along the left or right edges of the screen.
|
||||
If it has the suffix :code:`px` then it sets the width of the window in pixels instead of columns.
|
||||
''',)
|
||||
|
||||
opt('edge', 'top', choices=('top', 'bottom', 'left', 'right'),
|
||||
long_text='Which edge of the screen to place the window along')
|
||||
|
||||
opt('background_opacity', '0.85', option_type='unit_float', long_text='''
|
||||
The background opacity of the window. This works the same as the kitty
|
||||
option of the same name, it is present here as it has a different
|
||||
default value for the quick access terminal.
|
||||
''')
|
||||
|
||||
opt('hide_on_focus_loss', 'no', option_type='to_bool', long_text='''
|
||||
Hide the window when it loses keyboard focus automatically. Using this option
|
||||
will force :opt:`focus_policy` to :code:`on-demand`.
|
||||
''')
|
||||
|
||||
opt('margin_left', '0', option_type='int',
|
||||
long_text='Set the left margin for the window, in pixels. Has no effect for windows on the right edge of the screen.')
|
||||
|
||||
opt('margin_right', '0', option_type='int',
|
||||
long_text='Set the right margin for the window, in pixels. Has no effect for windows on the left edge of the screen.')
|
||||
|
||||
opt('margin_top', '0', option_type='int',
|
||||
long_text='Set the top margin for the window, in pixels. Has no effect for windows on the bottom edge of the screen.')
|
||||
|
||||
opt('margin_bottom', '0', option_type='int',
|
||||
long_text='Set the bottom margin for the window, in pixels. Has no effect for windows on the top edge of the screen.')
|
||||
|
||||
opt('+kitty_conf', '',
|
||||
long_text='Path to config file to use for kitty when drawing the window. Can be specified multiple times. By default, the'
|
||||
' normal kitty.conf is used. Relative paths are resolved with respect to the kitty config directory.'
|
||||
)
|
||||
|
||||
opt('+kitty_override', '', long_text='Override individual kitty configuration options, can be specified multiple times.'
|
||||
' Syntax: :italic:`name=value`. For example: :code:`font_size=20`.'
|
||||
)
|
||||
|
||||
opt('app_id', f'{appname}-quick-access',
|
||||
long_text='On Wayland set the :italic:`namespace` of the layer shell surface.'
|
||||
' On X11 set the WM_CLASS assigned to the quick access window. (Linux only)')
|
||||
|
||||
|
||||
opt('output_name', '', long_text='''
|
||||
The panel can only be displayed on a single monitor (output) at a time. This allows
|
||||
you to specify which output is used, by name. If not specified the compositor will choose an
|
||||
output automatically, typically the last output the user interacted with or the primary monitor.
|
||||
You can get a list of available outputs by running: :code:`kitten panel --output-name list`.
|
||||
''')
|
||||
|
||||
opt('start_as_hidden', 'no', option_type='to_bool',
|
||||
long_text='Whether to start the quick access terminal hidden. Useful if you are starting it as part of system startup.')
|
||||
|
||||
opt('focus_policy', 'exclusive', choices=('exclusive', 'on-demand'), long_text='''
|
||||
How to manage window focus. A value of :code:`exclusive` means prevent other windows from getting focus.
|
||||
However, whether this works is entirely dependent on the compositor/desktop environment.
|
||||
It does not have any effect on macOS and KDE, for example. Note that on sway using :code:`on-demand` means
|
||||
the compositor will not focus the window when it appears until you click on it, which is why the default is set
|
||||
to :code:`exclusive`.
|
||||
''')
|
||||
|
||||
|
||||
|
||||
def options_spec() -> str:
|
||||
return f'''
|
||||
--config -c
|
||||
type=list
|
||||
completion=type:file ext:conf group:"Config files" kwds:none,NONE
|
||||
{CONFIG_HELP.format(conf_name='quick-access-terminal', appname=appname)}
|
||||
|
||||
|
||||
--override -o
|
||||
type=list
|
||||
Override individual configuration options, can be specified multiple times.
|
||||
Syntax: :italic:`name=value`. For example: :italic:`-o lines=12`
|
||||
|
||||
|
||||
--detach
|
||||
type=bool-set
|
||||
Detach from the controlling terminal, if any, running in an independent child process,
|
||||
the parent process exits immediately.
|
||||
|
||||
|
||||
--detached-log
|
||||
Path to a log file to store STDOUT/STDERR when using :option:`--detach`
|
||||
|
||||
|
||||
--instance-group
|
||||
default=quick-access
|
||||
The unique name of this quick access terminal Use a different name if you want multiple such terminals.
|
||||
|
||||
|
||||
--debug-rendering
|
||||
type=bool-set
|
||||
For debugging interactions with the compositor/window manager.
|
||||
'''
|
||||
|
||||
def main(args: list[str]) -> None:
|
||||
raise SystemExit('This kitten should be run as: kitten quick-access-terminal')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
elif __name__ == '__doc__':
|
||||
cd: dict = sys.cli_docs # type: ignore
|
||||
cd['usage'] = '[cmdline-to-run ...]'
|
||||
cd['options'] = options_spec
|
||||
cd['help_text'] = help_text
|
||||
cd['short_desc'] = help_text
|
||||
elif __name__ == '__conf__':
|
||||
sys.options_definition = definition # type: ignore
|
||||
@@ -87,8 +87,8 @@ class KittenMetadata(NamedTuple):
|
||||
|
||||
def create_kitten_handler(kitten: str, orig_args: list[str]) -> KittenMetadata:
|
||||
from kitty.constants import config_dir
|
||||
m = import_kitten_main_module(config_dir, kitten)
|
||||
kitten = resolved_kitten(kitten)
|
||||
m = import_kitten_main_module(config_dir, kitten)
|
||||
main = m['start']
|
||||
handle_result = m['end']
|
||||
return KittenMetadata(
|
||||
@@ -110,13 +110,12 @@ def set_debug(kitten: str) -> None:
|
||||
|
||||
def launch(args: list[str]) -> None:
|
||||
config_dir, kitten = args[:2]
|
||||
original_kitten_name = kitten
|
||||
kitten = resolved_kitten(kitten)
|
||||
del args[:2]
|
||||
args = [kitten] + args
|
||||
os.environ['KITTY_CONFIG_DIRECTORY'] = config_dir
|
||||
set_debug(kitten)
|
||||
m = import_kitten_main_module(config_dir, original_kitten_name)
|
||||
m = import_kitten_main_module(config_dir, kitten)
|
||||
try:
|
||||
result = m['start'](args)
|
||||
finally:
|
||||
@@ -140,14 +139,11 @@ def run_kitten(kitten: str, run_name: str = '__main__') -> None:
|
||||
if kitten in all_kitten_names():
|
||||
runpy.run_module(f'kittens.{kitten}.main', run_name=run_name)
|
||||
return
|
||||
kitten = original_kitten_name
|
||||
# Look for a custom kitten
|
||||
if not kitten.endswith('.py'):
|
||||
kitten += '.py'
|
||||
from kitty.constants import config_dir
|
||||
path = path_to_custom_kitten(config_dir, kitten)
|
||||
if not os.path.exists(path):
|
||||
path = path_to_custom_kitten(config_dir, resolved_kitten(kitten))
|
||||
if not os.path.exists(path):
|
||||
print('Available builtin kittens:', file=sys.stderr)
|
||||
for kitten in all_kitten_names():
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli/markup"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"kitty/tools/cli/markup"
|
||||
"kitty/tools/tui/loop"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -5,9 +5,9 @@ package show_key
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/cli/markup"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"io"
|
||||
"kitty/tools/cli/markup"
|
||||
"kitty/tools/tty"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
@@ -5,7 +5,7 @@ package show_key
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"kitty/tools/cli"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/utils/shm"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/paths"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/paths"
|
||||
"kitty/tools/utils/shlex"
|
||||
|
||||
"github.com/bmatcuk/doublestar/v4"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
@@ -4,7 +4,7 @@ package ssh
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/utils"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
@@ -112,7 +112,7 @@ func TestSSHConfigParsing(t *testing.T) {
|
||||
hostname = "2"
|
||||
rt()
|
||||
|
||||
ci, err := ParseCopyInstruction("--exclude moose --exclude second --dest=target " + cf)
|
||||
ci, err := ParseCopyInstruction("--exclude moose --dest=target " + cf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func TestSSHConfigParsing(t *testing.T) {
|
||||
if diff != "" {
|
||||
t.Fatalf("Incorrect local_path:\n%s", diff)
|
||||
}
|
||||
diff = cmp.Diff([]string{"moose", "second"}, ci[0].exclude_patterns)
|
||||
diff = cmp.Diff([]string{"moose"}, ci[0].exclude_patterns)
|
||||
if diff != "" {
|
||||
t.Fatalf("Incorrect excludes:\n%s", diff)
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"io"
|
||||
"io/fs"
|
||||
"kitty"
|
||||
"maps"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -28,16 +28,16 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/themes"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/shell_integration"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/secrets"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/themes"
|
||||
"kitty/tools/tty"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/shell_integration"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/secrets"
|
||||
"kitty/tools/utils/shlex"
|
||||
"kitty/tools/utils/shm"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shm"
|
||||
"io/fs"
|
||||
"kitty"
|
||||
"kitty/tools/utils/shm"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
"kitty/tools/utils/shlex"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
@@ -5,9 +5,9 @@ package themes
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/themes"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/themes"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -11,10 +11,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/themes"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"kitty/tools/cli"
|
||||
"kitty/tools/themes"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
@@ -4,20 +4,20 @@ package themes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kovidgoyal/kitty"
|
||||
"io"
|
||||
"kitty"
|
||||
"maps"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/themes"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/readline"
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
"github.com/kovidgoyal/kitty/tools/wcswidth"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/themes"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/tui/readline"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user