Skip to content
Snippets Groups Projects

Add Windows support.

Open Jezza requested to merge Jezza/termion:windows-support into master
1 unresolved thread

Edit: It's all done and ready now.


I had some spare time and I love termion, so I thought I'd add support for windows. I'm by no means a windows programmer, so if I've botched something or there's a better way to do something, feel free to say something. The implementation itself is pretty much done. It's complete enough that I could run most of the examples. The tests are another matter... I'll need to look into it, but basically, the tests themselves just don't work.

I've marked this as a WIP as there's still some things to do.

First:

As I said, some of the examples don't work or have odd behaviour. Those in question:

  • async (At a quick glance, it's not doing the thing it's supposed to... Or at least, it looks very weird. An error is printed out, so that's probably something I should look into.)

  • detect_color (An internal error, haven't looked into it yet because it's getting late...)

  • is_tty (Kind of a weird question, because I have no idea if it even makes sense. It's not possible to construct a fd to stdout without explicitly doing so in windows... It's an open topic.)

  • mouse (The mouse itself does generate events. For example, the click example does work.)

  • truecolor (This just looks weird. I think it might have something to do with the refresh rate of the console...)

Second:

Code review! I have no idea if what I did was the correct thing to do in that scenario. For example, I use std's handle when fetching the stdout handle, but in the attr module, I just use the win api directly. Now, I know they're both functionally equivalent, but I should probably standardise it. There's also the "problem" of returning a fs::File as the tty. A good idea might be to switch winapi's HANDLE to std's, and then just use winapi's stdout handle, and only use rust for the fs::File conversion.

Third:

Some of the flags I pass to the console api. I know that we need all except one flag: ENABLE_VIRTUAL_TERMINAL_PROCESSING. I only added it because the documentation says it's typically used in conjunction with ENABLE_VIRTUAL_TERMINAL_INPUT. I'm about 99% we don't need it, or arguably, even want it...

Fourth:

Is is_tty necessary for windows? I alluded to the main reason why I think this right now. To construct a HANDLE to something that could be a tty requires some pretty explicit pipework in windows. At least, from what I can tell. I'm not opposed to implementing it, I'm basically just trying to confirm that "yeah, it's technically needed." All that needs to be done in this case is basically just pull out the fd that the incoming stream uses, and check it against the stdout. That's probably going to be a bit messy though. Rust does have a IntoRawHandle for things that can be turned into raw handles. Files, stdout, etc, already implement it. I don't know if I can decompose a RawHandle... I'll need to look into it.


After all of that is done, I would consider this done. In the meantime, as it stands, it does work, so people are free to poke around on this branch, and see what breaks.

Edited by Jezza

Merge request reports

Pipeline #7236 failed

Pipeline failed for 9e35f915 on Jezza:windows-support

Approval is optional
The target branch master does not exist. Please restore it or use a different target branch.

Merge details

  • The source branch is 62 commits behind the target branch.
  • 1 commit and 1 merge commit will be added to master.
  • Source branch will be deleted.

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Jezza added 1 commit

    added 1 commit

    • 4b873d60 - Correctly set the console modes.

    Compare with previous version

  • Jezza marked the checklist item detect_color (An internal error, haven't looked into it yet because it's getting late...) as completed

    marked the checklist item detect_color (An internal error, haven't looked into it yet because it's getting late...) as completed

  • Jezza marked the checklist item truecolor (This just looks weird. I think it might have something to do with the refresh rate of the console...) as completed

    marked the checklist item truecolor (This just looks weird. I think it might have something to do with the refresh rate of the console...) as completed

  • Jezza marked the checklist item async (At a quick glance, it's not doing the thing it's supposed to... Or at least, it looks very weird. An error is printed out, so that's probably something I should look into.) as completed

    marked the checklist item async (At a quick glance, it's not doing the thing it's supposed to... Or at least, it looks very weird. An error is printed out, so that's probably something I should look into.) as completed

  • Jezza added 1 commit

    added 1 commit

    • ba8a17e2 - Correctly set the console modes.

    Compare with previous version

  • Jezza added 1 commit

    added 1 commit

    • 226a38e9 - Correctly set the console modes.

    Compare with previous version

  • Jezza marked the checklist item mouse (The mouse itself does generate events. For example, the click example does work.) as completed

    marked the checklist item mouse (The mouse itself does generate events. For example, the click example does work.) as completed

  • Jezza marked the checklist item is_tty (Kind of a weird question, because I have no idea if it even makes sense. It's not possible to construct a fd to stdout without explicitly doing so in windows... It's an open topic.) as completed

    marked the checklist item is_tty (Kind of a weird question, because I have no idea if it even makes sense. It's not possible to construct a fd to stdout without explicitly doing so in windows... It's an open topic.) as completed

  • Jezza added 1 commit

    added 1 commit

    • ae3b8c8c - Construct the window's tty handle and set the necessary console modes.

    Compare with previous version

  • Jezza added 1 commit

    added 1 commit

    Compare with previous version

  • Jezza unmarked as a Work In Progress

    unmarked as a Work In Progress

  • Jezza changed the description

    changed the description

  • Alrighty, it's done.
    I couldn't find anything else to pick at .
    All of the examples work well.

    Edited by Jezza
  • closed

  • Jezza reopened

    reopened

  • Jezza changed title from Add basic windows support. to Add Windows support.

    changed title from Add basic windows support. to Add Windows support.

  • This resolves both #103 and #156.

  • Jezza added 1 commit

    added 1 commit

    Compare with previous version

  • Bump?

  • Jezza changed the description

    changed the description

  • It seems to me that windows 10 default terminal emulator app doesn't have ENABLE_VIRTUAL_TERMINAL_PROCESSING (enables escape sequence processing) set by default which causes most examples to fail. Adding a quick hack calling set_terminal_attr with ENABLE_VIRTUAL_TERMINAL_PROCESSING and ENABLE_PROCESSED_OUTPUT set mostly fixed it. I don't see a way of solving this without changing API - either adding extra init method or attribute setter/restorer structure like RawTerminal.

    Using third party terminal emulator which enables escape code processing by default doesn't have this problem. Tried Alacritty and ConEmu.

    Edited by karliss
  • @karliss Uh, it already sets that flag on the stdout inside sys/win/attr.rs.

    Edited by Jezza
  • I'm just a user of termion, but one issue with this change is that it changes get_tty to return impl Read instead of File. That's a problem because normally (on *nix, at least) you can read from and write to a TTY. It also makes it so you can't call into_raw_mode on the returned TTY.

  • @mjbshaw, I agree. That should not change. There must be a better way to implement get_tty on Windows, or it should be left unimplemented on Windows. Simply returning one of the stdio handles is not enough, as it may be piped from or into a file. The same is the case for is_tty.

    Edited by Jeremy Soller
  • Coleman McFarland mentioned in issue #167

    mentioned in issue #167

  • Jezza added 34 commits

    added 34 commits

    Compare with previous version

  • Finally got time to revisit this.

    impl Read: Yeah, in hindsight, that's actually pretty silly.
    I don't think I can turn it back to fs::File, because of issues with Windows.
    One option would be to turn it into impl Read + Write.
    fs::File implements them both, and I can implement a passthrough struct for Windows.

    Edited by Jezza
  • Jezza added 1 commit

    added 1 commit

    • 51628636 - Change standard TTY type to `impl Read + Write`

    Compare with previous version

  • Jezza added 1 commit

    added 1 commit

    • f87d4170 - Fix the Invalid Handle error by fetching the true redirected STDIN.

    Compare with previous version

  • Jezza added 1 commit

    added 1 commit

    • 453879d3 - Fix the Invalid Handle error by fetching the true redirected STDIN.

    Compare with previous version

  • Jezza added 1 commit

    added 1 commit

    Compare with previous version

  • The disk usage analyzer will be solving a long-standing issue with compilation on windows once this MR lands in master.

    Thanks for the initiative, @Jezza !

  • Nagy Tibor mentioned in issue calc#30

    mentioned in issue calc#30

  • kankri mentioned in merge request !174

    mentioned in merge request !174

  • Also checking back in; any timeline for merging and Windows support?

    Thanks for the attention!

  • Merge conflicts must be resolved.

Please register or sign in to reply
Loading