Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Windows (Fixes #28) #1374

Merged
merged 90 commits into from Oct 16, 2018
Merged

Conversation

zacps
Copy link
Contributor

@zacps zacps commented Jun 14, 2018

Primarily this:

  • Adds Windows support to copypasta
  • Adds rusttype as a font rendering backend
  • Creates an interface to abstract over how we interact with a TTY-like thing (EventedRW)
  • Adds safe winpty bindings
  • Adds winpty as a TTY shim
  • Adds appveyor CI support

The windows support is not perfect yet but it's good enough that I think it makes sense to merge it. Any unresolved issues are listed here.

Apologies for the unrelated formatting changes, I can dig through and remove them from the pull but it might take me a little while.

zacps and others added 30 commits November 6, 2017 14:53
Based on japaric/trust
This might not be an appropriate fix, I will admit I don't really
understand mio's model.
Revert to using the title variable, pin all dependancies to a specific
version.
* Added an ICO resource to the Windows EXE
Large merge of changes from jwilm/alacritty master since the start of the windows branch.

* Support integer font size in config (alacritty#886)

Fixes alacritty#882

* Fixed typo in README.md (alacritty#876)

* Correct linefeed handling when scroll region set (alacritty#855)

Linefeeds should only move the cursor down if it's before the end of
the scroll region.

The "out of bounds" panic was triggered by linefeeds going off the
bottom of the screen when the scroll region end was above the cursor.

Note: https://vt100.net/docs/vt102-ug/chapter5.html
"Characters added outside the scrolling region do not cause the screen to scroll."

* Match LF behavior outside scroll region with urxvt

Outside of a scroll region, linefeed will still advances the line until
reaching the bottom row in other terminals. Alacritty now matches that.

* Run all ref tests

There were two ref tests that were not being run. Oops!

* Add ref test for 855

* Don't enforce window dimensions if configured with 0 columns or lines

* Style fixes

* Fix typo and whitespace

* Output more info for `--version` (alacritty#888)

Useful when requesting more info to help investigating issues.

* Support more color escape codes (alacritty#757)

* Support text cursor color escape codes
* Support reset color index escape code
* Support multiple colors in set color index escape code

* Remove outdated TASK.md (alacritty#906)

* Wait to display window until initialization is complete (alacritty#907)

* Revert "Wait to display window until initialization is complete (alacritty#907)"

This reverts commit a931d69.

Please see alacritty#907 (comment)
for rationale w/ GIF.

> now alacritty starts "in stages". First it paints some small
> rectangle, and in a second in "boots" and fills up the available
> space.

* commit some Cargo.lock changes that "cargo build" would do automatically

* clippy: fix if_not_else warning 'breaking' the build. Swap blocks and change to "==".

* Cargo.lock: bump clippy from 0.0.164 to 0.0.174.

* clippy: string constants do not need to have static lifetime (const_static_lifetime).

* clippy: remove unneeded return statement (needless_return).

* clippy: use is_empty() instead of  len() == 0 (warn(len_zero)).

* clippy: do and don't pass some things by reference as suggested (needless_pass_by_value, needless_borrow).

* Add cursor style option (alacritty#928)

The default cursor can now be configured through the cursor_style field
of the config. Valid options include Block, Underline, and Beam.

The default can be restored by sending \e[0q as in VTE terminals.

Live config reloading is supported for this parameter.

* Remove the launcher and set the locale/current directory in alacritty (alacritty#879)

* On macOS when launching multiple times focus win (alacritty#941)

I dug into this and narrowed the issue down to the macOS app bundle
Info.plist file. So, I spun up a native macOS app real quick and tested
it by launching the binary directly and launching it via the app bundle.
When launching from the command line directly, it created multiple
windows & instances of the app. However, when launching via the app
bundle it behaved as I normally expect a macOS app to behave, that is
when launched multiple times to simply focus the already existing window
and instance.

This informed me that it wasn't something in code as much as it was
something in the app bundle configuration. Hence, I reworked the
Info.plist file based on the one that was created by XCode when I made
the native macOS app and it started behaving as expected.

* Fix License link at the bottom of the readme (alacritty#933)

* Add 'borderless' option

Until winit gives us more capabilities in regard to window decorations
this implements a simple switch that renders the window without any
title bar or border

* Add borderless option to config files

See 46a1ee7

* Add new window section to config

Move/rename borderless into window_config as decorations

* Move dimensions and padding into window section

* Update config files

* Deprecate config top-level dimensions and padding

* Use consistent config deprecation message style

* Fix stack-overflow when creating a new atlas

When an atlas is full and the `insert` call fails, a new atlas should be
created. This is the current strategy, however the atlas is put at the
end of the vector, but the `current_atlas` index is set to 0, instead of
the last element. This leads to a recursion where it keeps trying to
insert into the full atlas at position 0 instead of the new at
`atlas.len() - 1`.

With this simple fix a stack-overflow is prevented because the new atlas
is inserted as the first element, which then will be used correctly for
loading new glyphs.

This fixes alacritty/issues/842 and might also solve
alacritty/issues/914 (I wasn't able to reproduce this with the
latest master).

* Change LoadGlyph in LoaderApi to match RenderApi

* Share LoadGlyph implementations

Previously there were two separate but intended-to-be-identical
implementations. Now the two implementations simply delegate to a
single, shared method. This should help correctness issues in the
future.

* Implement faux scrolling

This patch implements faux scrolling inside the alternate screen buffer.

Whenever the user scrolls up or down while the alternate screen buffer
is active, instead of actual scrolling three up/down arrow keys are
inserted.

* Fix faux scrolling for line-based touchpads

Touchpads which use line-based instead of pixel-based updates send
partial scroll requests, so decimal numbers are important. The current
implementation only really used scroll amounts that are either 1 or -1.

This has been fixed and now the line-based touchpads should have very
smooth scrolling, but the pixel-based approach is still WIP and
completely untested.

* Adapt pixel-based scrolling behavior

The pixel-based scrolling behavior has been adapted to be as similar to
the line-based one as possible.

I still have not been able to test this. But this should have a decent
chance to at least kinda work.

* Style nits

* Add Void Linux to distrobutions with packages

Void Linux has the alacritty package in the main repository's, so compilation from source isn't needed.

* Update README.md for current state of macOS

Homebrew Rust will correctly compile `alacritty` now, and the monospace
font is automatically set to `Menlo` at first launch.

* Remove built crate

This became a support burden for me due to various compile and run time
issues.

* Fix macOS fallbacks (alacritty#956)

The cascade list is now generated from Menlo for all fonts. This doesn't
feel correct to me, but it seems to give the expected behavior on macOS.
One of the problems cited was that certain glyphs like ❯ would not be
rendered with default cascade lists for some fonts.

* Remove debug print

* Assure that newlines are in selections (alacritty#777)

When a selection was made, the last line of the selection did not
include a new line character when the line ending was selected. This
would occur if only one line was selected; if multiple lines were
selected, only the final line did not include a newline.

This commit updates the `string_from_selection` function to attempt to
append a newline character in all places where they are suitable.
Because of the simplification of newline insertion, several trait
implementations were removed.

* Update dependencies

Also fixes warning from gl generator

* Update deps

* Update glutin to v0.10

* Update bitflags to v1

* Update euclid to v16

* Update glutin to v0.11

* Add custom underline cursor

As mentioned in alacritty#931, it can be troublesome if a font has
an underline symbol outside of the glyph's bounding box. This can lead
to the underline disappearing at the bottom of the terminal.

As a solution a symbol from the private use area was used as the
character code for the underline symbol. Whenever this symbol is
encountered, instead of rendering it, a custom block is rendered.

In this implementation the block has the full character as width and
sits flush with the bottom of the glyph's bounding box. The height is
half the distance between the baseline and the bottom of the bounding
box.

* Revert to old system for macos

Because rendering with macos works differently, the old underline cursor
is used for that. The cursor symbol has also been setup as a constant in
the font project.

* Update comment to reference proper character

The unicode character comment has been updated to correctly reference
the character instead of commenting on the variable that might be that
character.

* Specify unicode code point explicitly

* Add custom beam cursor

In issue jwilm/asacritty#31 a few people complained about Beam cursor
being weird with their fonts, so to make all cursors uniform in
alacritty, a custom cursor has been added for the Beam too.

The beam cursor's height is always the full height of the monospace font
glyph bounding box. The width depends on the font size. It is calculated
using the width of the cell and dividing it by two. The block is always
aligned at the far-left of the cell.

The implementation is identical to the one of the underline cursor, but
it has been refactored so the glyphs are created in `lib.rs`, which can
be used by darwin/macos to implement these features too.

A small bug in the underline cursor has also been fixed, until now the
width was just using the width of the unicode character. Now it should
be using the full width of the monospace glyph bounding box with every
font.

Here are some screenshots for the Beam cursor:
![Small](https://u.teknik.io/v1QH3.png)
![Normal](https://u.teknik.io/RTlp2.png)
![Big](https://u.teknik.io/DLu2M.png)
![Huge](https://u.teknik.io/pSAFX.png)

* Add custom cursors for macos

The macos target now also supports the custom beam and underline
cursors. The only thing left for this is now is testing and making sure
it works with tiny fonts.

* Format cursor code and add documentation

As requested a few comments have been added to the darwin code. There
also was an off by one error in the ascent calculation which has been
corrected.

The beam cursor width has also been tweaked to be slightly slimmer in
general.

All code added in this PR has also been run through the default rustfmt
to make sure the formatting is okay.

* Add custom box cursor for unfocused window

* Refactor darwin code

The ascent calculation on darwin was more complicated than it needed to
be. By running a `.ceil()` instead of adding one, checking if it's 0,
substracting if it is, and then flooring it, a few instructions could be
shaved off.

* Add box cursor to unfocused underline and beam

Because some people have requested this change, the beam and underline
cursors now also transform into an empty box when the terminal loses
focus. Like this there is one unique symbol to indicate that a terminal
is not currently focused.

* Remove the launcher and set the locale/current directory in alacritty (alacritty#879)

* Fix linux symbol size

With linux every box, line or underline should now have the
pixel-perfect size with any font at any size.

This uses the default font to get the size of the monospace box. It
assumes that the face 0 is always the primary font, if this is not the
case, this will probably break.

* Use font_key provided with cursor glyphs

Previously it was assumed that the font_key for the normal font is
always 0, because this assumption was a bit of a stretch, now the
font_key provided with the glyph is used. This is always the bold,
italics or normal font associated with the cell.

* Move custom cursor block on ft

Moved the custom cursor block on ft to the top, so no unnecessary
operations are executed when trying to draw a custom cursor glyph.

* Fix stack overflow with too large glyphs

This resolves the remaining issue of alacritty#842.

* Adding dynamic_title property to configuration (alacritty#819)

This logic is applied in Term's ansi::Handler implementation
to avoid unnecessary allocations.

* Change mouse cursor on terminal mode change (alacritty#865)

Some terminals have functionality around changing the type of mouse
cursor dynamically (arrow and text) based on which mode(s) the VTE is
in. For example, gnome-terminal changes the cursor from text (default)
to an arrow when opening programs that track mouse events (e.g. vim,
emacs, tmux, htop, etc.). The programs all allow using the mouse
interactively under some circumstances (like executing `set mouse=a` in
vim).

The programs that use an interactive mouse set the terminal mode to
different values. Though they're not entirely the same terminal mode
across programs, an emulator like vte (the library gnome-terminal
implements), changes the mouse cursor if the mouse mode is one of the
following:

- 1000: Mouse Click Tracking
- 1001: Mouse Highlight Tracking
- 1002: Mouse Cell Motion Tracking
- 1003: Mouse All Motion Tracking
- 1004: Mouse Focus Tracking

See https://github.com/GNOME/vte/blob/6acfa59dfcceef65c1f7e3570db37ab245f049c4/src/vteseq.cc#L708
for more information.

This commit adds functionality that changes the winit/glutin
`MouseCursor` when a mouse-listening mode of 1000-1004 is set. It
behaves similarly to when the window title changes.

* Refactor populate cursor, fix-wide-cursor (alacritty#762)

Cleanup cursor handling code and support wide cursors

* Fix zombie children (alacritty#976)

Resolves alacritty#973

* Add config option for faux scrollback

Some people have complained about the behavior of faux scrollback inside
of vim/tmux, however from what I can tell, alacritty behaves the same
way as other terminal emulators that support faux scrollback.

However there are a lot of terminal emulators that do not support faux
scrollback at all, which leads to people complaining about unusual
scroll behavior.

This is my proposal on how to solve this issue, by giving people that do
not like the VTE-Style faux scrolling the option to opt-out.

* Allow faux scroll amount configuration

It is now possible to configure the amount of lines
scrolled with faux scrollback.

* Address feedback

The config documentation has been changed to make it clear which part of
the documentation is related to which setting.

The faux scrollback part of the `scroll_terminal` method has been
cleaned up by making use of the fact that the `codepoint + 1` can be
used in the escape sequence which is used for scrolling.

* Add support for set-clipboard. (alacritty#970)

This allows e.g. tmux to set the clipboard via the OSC 52 escape code.

* Enable shift+select in mouse mode

When an application takes control over the mouse, it usually disables
selection completely. However the common way to still make selection
possible is by allowing selection while the shift key is held down.

This feature is implemented here by making use of the new `modifiers`
field on mouse events with glutin/winit.

This fixes alacritty#146.

* Update mouse modifiers to only pass shift

The only mouse modifier required right now is the shift key, to prevent
passing around unnecessary state, only the shift state is passed to the
mouse processors now.

* Fix failed tests

Three was still a test which passed the whole modifiers struct instead
of just the shift bool, this has been fixed.

* Use default modifier state

The tests were using a manually setup `ModifiersState`, to clean things
up a bit the `ModifiersState::default` method has been used to replace
this.

* Always clear selection

It seems like the common consensus is that even in mouse mode, the
selection should be cleared with a normal click.

If there is any reason why this should not be the case, please let me
know.

* Pass ModifiersState to mouse input as whole

ModifiersState is now passed to the mouse methods in `input.rs` as a
whole instead of just passing the `shift` state. This should make it a
bit easier to do changes in the future.

* Pass ModifiersState to mouse_moved method too

* Prevent font_size_modifier from sinking too low (alacritty#994)

This replaces the `font_size_modifier` stored on the `Term` struct with a `font_size` field.

With this change it is not necessary anymore to calculate the new font size from a delta but the current font size is always stored directly on the `Term` struct.

As a result of this it is now possible to increase the font size by more than 127 steps at runtime. It also limits the minimum font size to 1, so issues with the `font_size_modifier` dropping far below font size 1 are resolved with this change.

This fixes alacritty#955.

* Improve ability of alacritty to deal with broken config

Until now alacritty completely refuses to start when the config is broken
in any way. This behavior has been changed so the worst-case is always
that alacritty launches with the default configuration.

When part of the config is broken, alacritty shouldn't instantly try to
recover to the default config, but instead try to use defaults only for
the parts of the config which are broken. This has also been implemented
for most of the fields in the configuration. So it should be possible that
parts are broken, but the rest is still used for the configuration.

This fixes alacritty#954.

* Add clippy check to travis

This commit adds clippy as a required step of the build process. To make
this possible, all existing clippy issues have been resolved.

* Fix SGR mouse reporting

There were two bugs fixed in this commit:

1. `sgr_mouse_report` was not always called when `SGR_MOUSE` bit was set
   due to calling `normal_mouse_report` instead of `mouse_report` in the
   scrolling method.
2. SGR reporting was always going off the left mouse button state rather
   than what was appropriate. This affected SGR scroll reporting since
   it only behaves correctly for pressed events (final character 'M').

Resolves alacritty#698.

* Honour working dir on linux (alacritty#987)

* Resolves alacritty#733.

When pasting in non-bracketed mode, LFs are replaced with CRs.

* Non-bracketed paste support for DOS CRLFs.

When pasting in non-bracketed more, all line endings (including
DOS-style CRLFs) get normalized to a single CR to simulate a keypress of
the <return> key.

* Revert alacritty#987 behavior on macos (alacritty#1007)

* Fix indexed color setting regression

Commit 2920cbe introduced a regression because of a typo in the chunk slice index for the `parse_rgb_color` call.

This fixes this issue by resetting it to the state it was before the faulty commit.

* Fix `ioctl` call failing on 32 bit architecture (alacritty#1011)

* Make Mac app installation steps idempotent (alacritty#1015)

Repeated uses of `cp -r target/release/osx/Alacritty.app
  /Applications/Alacritty.app` will result in copying Alacritty.app to
  `/Applications/Alacritty.app/Alacritty.app`.

* Expand key binding config documentation

A link to all variants available as `key` has been added to the key
bindings documentation, to help users with finding the right place
for mapping key codes.

* Update lockfile

Clippy failed to build with the latest nightly, so the lockfile has been
updated to allow the nightly builds to work again.

* Spawn alacritty window as invisible

This change initially spawns alacritty as in invisible window, this
makes it possible for the pty to already access data like `window_id`
without having to wait for the window manager to actually open the
window.

Even though `GlWindow::new` is blocking when `with_visibility(true)` is
used, the `window.show` call is not blocking. So calling `GlWindow::new`
and `with_visibility(false)`, then immediately calling `window.show`
will create a window and make it visible instantly.

* Update lockfile (alacritty#1031)

The lockfile has been updated to make clippy work with nightly again.

* Implement `reset_state` of Term struct (alacritty#1035)

Up to this point the `reset_state` method of the `Term` struct has been
just a placeholder. This has been changed and all important state has
been reset.

The only state that has not been reset is stuff which is retrieved from
the config and isn't stored as default on the `Term` struct either. From
what I can tell these are all never changed though.

This fixes alacritty#1033.

After doing some more testing trying to figure out how to fix that all
glyphs are messed up after doing `cat /dev/urandom`, I was able to
confirm that resetting `Term::cursor` fixes the glyphs and restores
everything to normal.

So this also fixes alacritty#804.

* Better character cell width with FreeType (alacritty#1029)

This should fix alacritty#1020, alacritty#710, and alacritty#902

* Update dependencies

Updated the version of some dependencies.

This also changes to a new clippy version so clippy can work with the latest nightly compiler again. Some issues created by new lints have been fixed.

* Update lockfile

Updated the lockfile to make sure clippy is building properly with the
latest nightly toolchain.

* Update core-text (alacritty#1061)

This cleans up a bunch of code.

* fix fallbacks in macos (alacritty#1099)

fixes alacritty#1086

* `starting` not `staring` (alacritty#1074)

* Add info about default configuration for macOS

* Add install instructions via cargo --git

* Fix heading for NixOS/Nixpkgs

The level of heading were one to high.

* Upgrade dependencies

Upgrading glutin to the latest version allows building alacritty even
with old XRandr versions.

This is relevant for Debian machines (and other ancient systems).

* Update arraydeque dependency

* Ignore emacs temp files

* Fixed lockup on start
Issue was fixed in the glutin 0.9-0.13 update but the function was not
re-enabled.
Remove use of `const fn` which is not yet stabilised.
@zacps
Copy link
Contributor Author

zacps commented Oct 11, 2018

@jwilm I think I've addressed all the issues you pointed out.

@jwilm
Copy link
Contributor

jwilm commented Oct 11, 2018

@zacps thanks! I'll run with a build off this branch until I get an opportunity to bench/final review.

@chrisduerr let's try and avoid landing any major changes until we get this in-tree.

@zacps zacps force-pushed the windows-linux branch 2 times, most recently from 1ec4065 to 5ff5efe Compare October 11, 2018 22:08
@chrisduerr
Copy link
Member

I'm fine with not landing any major changes, however the performance issue is still present.

I'd like to make sure the remaining performance gaps are closed, since there isn't really any good reason why this should impact performance on linux/macos (those users aren't getting any benefit from losing that performance).

In my benchmarks, I've been able to see around 5% performance degradation in the scrolling-in-region benchmark. I wasn't able to see anything in the other benchmarks, however I've just compared single data points instead of a range of results.

@zacps
Copy link
Contributor Author

zacps commented Oct 11, 2018

@chrisduerr Could you post some information about your system?

My system:

OS: Arch linux
CPU: i5 4690k @4.5GHz
GPU: GTX970 (Proprietary drivers)

Also please try running multiple benchmarks, using the command I ran above with hyperfind makes this a lot easier. Even across 20 runs of ~70sec long tests my branch had a smaller minimum (lower confidence interval bound) time than master. One run will not give enough information to draw a conclusion.

@chrisduerr
Copy link
Member

I'm running a i7 6700k system with the mesa driver (R9 390). Note that I did not run just a single benchmark. The performance degradation is significant and reproducible. And based on what jwilm has said, it doesn't seem like it's something specifically with my system either.

Note that for reproducing this, I would recommend setting a relatively big distance from bottom for the scroll in region benchmark. With my tests that was able to showcase the regression best.

@zacps
Copy link
Contributor Author

zacps commented Oct 12, 2018

I still can't reproduce, I bumped it up to 5 and 15 lines from bottom and if anything the windows branch performed slightly better (though not a significant difference).

@zacps zacps force-pushed the windows-linux branch 2 times, most recently from 253193b to 44b01cb Compare October 13, 2018 03:39
@chrisduerr
Copy link
Member

Note that I'm using 50 lines from the bottom to produce a significant performance difference.

I'll try to compare the two versions with perf and share my results.

@chrisduerr
Copy link
Member

Okay, so I've gone over this and tested things again and again. And I think I'd recommend to go forward with this PR without further investigations of the performance issues.

I've tested running standalone benchmarks, hyperfine, running it through perf and using the benchmarks created in #1653 and I was not able to reliably reproduce any performance degradations.

When running standalone benchmarks there were some interesting fluctuations, like a slowdown of .2s when running the scrolling-in-region benchmark with an offset of 50 after running the asrw benchmark. However I wasn't able to reproduce this consistently and I think that can be mostly blamed on CPU frequency adjustments.

Unless @jwilm is able to reliably reproduce a performance regression, I don't think it's worth to put any more effort into this. Especially because the offset in a scrolling region usually isn't bigger than 1 or 2, so performance regressions with an offset of >10 shouldn't be incredibly critical anyways.

@jwilm jwilm merged commit 15e0dea into alacritty:master Oct 16, 2018
@jwilm
Copy link
Contributor

jwilm commented Oct 16, 2018

@zacps thanks for all the effort here. I invited you as a collaborator to the project so that you're empowered to improve Windows support and manage issues/PRs pertaining to it.

@jwilm
Copy link
Contributor

jwilm commented Oct 16, 2018

@zacps Feel free to move the issues over from your tracker and label them with H - windows

@zacps zacps deleted the windows-linux branch October 17, 2018 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet