greghendershott / racket-mode

Emacs major and minor modes for Racket: edit, REPL, check-syntax, debug, profile, packages, and more.
https://www.racket-mode.com/
GNU General Public License v3.0
683 stars 92 forks source link

cannot run programs requiring racket/gui/base on windows #301

Closed zlee-personal closed 3 years ago

zlee-personal commented 6 years ago

Upon pressing f5, the repl opens, prints "on-demand one-time instantiation of racket/gui/base", and doesn't ever run the program. This only happens with programs which require gui.

greghendershott commented 6 years ago

I'm not seeing this. For example a foo.rkt buffer with this:

#lang racket/base

(require racket/gui)

"hi, world"

When I M-x racket-run, in the *Racket-REPL* buffer I see:

; on-demand one-time instantiation of racket/gui/base
"hi, world"
foo.rkt>

So can you help me out with more information?

  1. Please paste output of M-x racket-bug-report here, so I can see versions of Emacs, Racket, racket-mode, etc. you're using.

  2. If my foo.rkt program shows the problem for you, great, please let me know that. Otherwise, please give me the simplest example .rkt file you can, that does show the problem.

zlee-personal commented 6 years ago

racket bug report gives:

``` ((emacs-version "25.3.1") (emacs-uptime "3 minutes, 9 seconds") (system-type windows-nt) (major-mode racket-mode) (racket--source-dir "c:/Users/me/.emacs.d/elpa/racket-mode-20180401.1803/") (racket-program "Racket.exe") (racket-memory-limit 2048) (racket-error-context medium) (racket-history-filter-regexp "\\`\\s *\\S ?\\S ?\\s *\\'") (racket-images-inline t) (racket-images-keep-last 100) (racket-images-system-viewer "display") (racket-pretty-print t) (racket-indent-curly-as-sequence t) (racket-indent-sequence-depth 0) (racket-pretty-lambda nil) (racket-smart-open-bracket-enable nil)) (enabled-minor-modes (Info-breadcrumbs-in-mode-line-mode) (anzu-mode) (async-bytecomp-package-mode) (auto-composition-mode) (auto-compression-mode) (auto-encryption-mode) (auto-fill-mode) (auto-highlight-symbol-mode) (auto-save-mode) (bug-reference-prog-mode) (clean-aindent-mode) (column-number-mode) (company-mode) (diff-auto-refine-mode) (electric-indent-mode) (eval-sexp-fu-flash-mode) (evil-escape-mode) (evil-local-mode) (evil-mode) (evil-search-highlight-persist) (evil-surround-mode) (eyebrowse-mode) (fci-mode) (file-name-shadow-mode) (flx-ido-mode) (flycheck-pos-tip-mode) (font-lock-mode) (global-anzu-mode) (global-auto-revert-mode) (global-eldoc-mode) (global-evil-search-highlight-persist) (global-evil-surround-mode) (global-flycheck-mode) (global-font-lock-mode) (global-git-commit-mode) (global-hl-line-mode) (global-linum-mode) (global-magit-file-mode) (global-page-break-lines-mode) (global-spacemacs-leader-override-mode) (global-undo-tree-mode) (global-vi-tilde-fringe-mode) (goto-address-prog-mode) (helm-descbinds-mode) (helm-flx-mode) (helm-mode) (highlight-numbers-mode) (highlight-parentheses-mode) (hl-todo-mode) (hs-minor-mode) (ido-vertical-mode) (line-number-mode) (linum-mode) (mouse-wheel-mode) (override-global-mode) (persp-mode) (popwin-mode) (projectile-mode) (rainbow-delimiters-mode) (recentf-mode) (save-place-mode) (savehist-mode) (shell-dirtrack-mode) (show-smartparens-global-mode) (show-smartparens-mode) (smartparens-mode) (spaceline-helm-mode) (spaceline-info-mode) (spacemacs-leader-override-mode) (transient-mark-mode) (undo-tree-mode) (vi-tilde-fringe-mode) (volatile-highlights-mode) (which-key-mode) (winner-mode) (winum-mode) (xterm-mouse-mode) (yas-global-mode) (yas-minor-mode)) (disabled-minor-modes (Info-persist-history-mode) (abbrev-mode) (adaptive-wrap-prefix-mode) (auto-fill-function) (auto-image-file-mode) (auto-revert-mode) (auto-revert-tail-mode) (blink-cursor-mode) (buffer-read-only) (bug-reference-mode) (company-search-mode) (compilation-in-progress) (compilation-minor-mode) (compilation-shell-minor-mode) (completion-in-region-mode) (defining-kbd-macro) (diff-minor-mode) (dired-hide-details-mode) (display-time-mode) (edebug-mode) (eldoc-mode) (electric-layout-mode) (electric-quote-mode) (evil-magit-toggle-text-minor-mode) (flycheck-mode) (flyspell-mode) (git-commit-mode) (global-auto-highlight-symbol-mode) (global-company-mode) (global-highlight-parentheses-mode) (global-hl-todo-mode) (global-prettify-symbols-mode) (global-reveal-mode) (global-visual-line-mode) (goto-address-mode) (helm--minor-mode) (helm--remap-mouse-mode) (helm-autoresize-mode) (helm-migemo-mode) (helm-popup-tip-mode) (hidden-mode-line-mode) (hl-line-mode) (horizontal-scroll-bar-mode) (hybrid-mode) (ibuffer-auto-mode) (ido-everywhere) (image-minor-mode) (isearch-mode) (ispell-minor-mode) (jit-lock-debug-mode) (magit-auto-revert-mode) (magit-blame-mode) (magit-blame-read-only-mode) (magit-blob-mode) (magit-file-mode) (magit-popup-help-mode) (magit-wip-after-apply-mode) (magit-wip-after-save-local-mode) (magit-wip-after-save-mode) (magit-wip-before-change-mode) (mail-abbrevs-mode) (menu-bar-mode) (mml-mode) (next-error-follow-minor-mode) (org-capture-mode) (org-cdlatex-mode) (org-src-mode) (orgstruct-mode) (outline-minor-mode) (overwrite-mode) (package-build-minor-mode) (page-break-lines-mode) (paragraph-indent-minor-mode) (prettify-symbols-mode) (racket-check-syntax-mode) (rectangle-mark-mode) (reveal-mode) (server-buffer-clients) (server-mode) (sh-electric-here-document-mode) (shell-command-with-editor-mode) (size-indication-mode) (smartparens-global-mode) (smartparens-global-strict-mode) (smartparens-strict-mode) (smerge-mode) (temp-buffer-resize-mode) (tool-bar-mode) (tooltip-mode) (undo-tree-visualizer-selection-mode) (unify-8859-on-decoding-mode) (unify-8859-on-encoding-mode) (use-hard-newlines) (view-mode) (visible-mode) (visual-line-mode) (window-divider-mode) (with-editor-mode) (ws-butler-global-mode) (ws-butler-mode) (xref-etags-mode)) ```

Your foo.rkt works. I have somewhat isolated the issue: the repl works fine until I try to run the (main) function that uses the big-bang function from 2htdp/universe. After messing around, I also noticed that if I run the program, then press C-c C-c to interrupt the process when it is frozen, it will exit into a racket repl not inside the file. If I run the file again, it will work fine, run the program, and go to a repl inside the file. If I close the repl and try to run it again, I have to repeat the C-c C-c thing for it to work. This only happens on windows also.

greghendershott commented 6 years ago

Thanks for the additional information!

This may take me awhile to figure out what's going on. Also, I don't have a Windows laptop with me now; I will toward the end of next week.

Maybe I should make a VirtualBox VM for situations like this, and buy a Windows license.

greghendershott commented 6 years ago

OK I installed VirtualBox, downloaded and installed this free Windows VM from Microsoft, installed Emacs for Windows and Racket for Windows.

I've never used 2htdp/universe and big-bang. Can you give me an example program that shows the problem?

zlee-personal commented 6 years ago

Here is a simple program that uses big-bang:

#lang racket

(require 2htdp/image)
(require 2htdp/universe)

(big-bang 1 ; initial state
  [to-draw (lambda (x) ; draws a square of x length over a white background
                               (underlay/xy (rectangle 100 100 "solid" "white")
                                                    50 
                                                    50
                                                    (square x 'solid "red")))]
  [on-tick add1] ; adds 1 to the state every tick
  [stop-when (lambda (x) (> x 50))]) ; stops when state is over 50

It pretty much passes state between functions and draws something using the to-draw function every tick. This big-bang displays a square that gets larger by 1 every tick. When it is finished, (when the stop-when function returns true), the big-bang function returns the final state, in this case 51. What I noticed happening, is that the execution of the program will finish, and the function will return 51. However, no graphics will be displayed. Then, when you run it again, the graphics work. When I was running the program which first caused the issue, it seemed to freeze, because my big-bang needs input from the user in order to end, so racket-mode thought that my big-bang was running and it just waited for it to stop.

alex-hhh commented 6 years ago

I can confirm that this is a problem with racket-mode on Windows when racket is first started up. @vityou , your example will work if you start the program again (i.e hit F5) without stopping racket.exe.

The problem is that the program runs fine but any windows don't get displayed, even though they are created. Consider this example, which creates a frame, than shows it:

#lang racket
(require racket/gui)
(define f (new frame% [label "hello"] [width 100] [height 100]))
(send f show #t)

If I hit F5 to start a new racket program, the frame is created, but it will not show up. If I than type (send f show #t) in the REPL, the frame will show up. If I evaluate the program again (i.e hit F5), the frame will show without the extra REPL step.

This is a problem that existed for a while, but it has never bothered me. Even for complex programs, if racket.exe is started for the first time, I just enter a (send toplevel show #t) at the REPL to show the window and everything works fine.

greghendershott commented 6 years ago

@alex-hhh Thanks for joining in.

When racket-mode prints:

; on-demand one-time instantiation of racket/gui/base"

Do you suppose it should also print something like:

; TIP: If your frame% window doesn't appear, try entering (send frame show #t).

@alex-hhh: What do you think? @vityou: Would that have helped you?


p.s I'm at a conference and haven't had time to sit down with Windows, yet, and see if there's anything else I could do.

zlee-personal commented 6 years ago

I think it should print something like "if your window doesn't show up, try running the program again without deleting this buffer". Sending something to the frame wouldn't be possible in some cases if the program is still running as the repl wouldn't accept input.

alex-hhh commented 6 years ago

Any message would be misleading:

I can spend some time trying to see what the problem is. It might also be worth asking about this on racket-users, as the racket developers will know more about how the GUI is initialized.

alex-hhh commented 6 years ago

Experimenting with this a bit more, I found out that having two show invocations makes it work with racket-mode:

#lang racket
(require racket/gui)
(define f (new frame% [label "hello"] [width 100] [height 100]))
(send f show #t)
(send f show #t)

The original program, with only one "show" invocation, works when racket is started from the command line. That is, saving the code to "example.rkt" and running "racket example.rkt".

@greghendershott , can you confirm that you cannot reproduce this on Linux or OSX? -- this would make it Windows specific.

greghendershott commented 6 years ago

With no *Racket REPL* yet created, on macOS 10.11.6 with Racket 6.10 and Emacs 25.1.1 -- the window appears with a single (send f show #t).

(In fact it appears in the foreground on top of Emacs' window -- even when Emacs is in full screen mode).

greghendershott commented 6 years ago

I did finally get a chance to try Windows 10 in Virtual Box.

@alex-hhh I see the same behavior as you (on Windows) regarding the need to show the frame twice.

@vityou when I try your big bang example I see the same behavior as you (on Windows).

As I mentioned before, I don't see this same behavior on macOS.


I'm not sure what to do about this in racket-mode, other than document this?

alex-hhh commented 6 years ago

This seems to be a windows specific issue, indeed. I think it would be worth asking for help on the racket mailing lists.

greghendershott commented 3 years ago

I have a commit for this; it shows then immediately hides an initial frame on Windows. Although that's a work-around, it seems to fix this satisfactorily in my testing today.


p.s. I'm sorry to be so slow to follow through on this. In recent days I took some time to revisit racket/gui/base handling on all platforms, as well as to fix some failing tests on Windows. Windows is now part of CI (easier on GitHub Actions than previously on Travis CI) so that should help going forward.