Skip to content

Improve getcellpixels().#16047

Closed
mikoto2000 wants to merge 14 commits intovim:masterfrom
mikoto2000:improve-getcellpixels
Closed

Improve getcellpixels().#16047
mikoto2000 wants to merge 14 commits intovim:masterfrom
mikoto2000:improve-getcellpixels

Conversation

@mikoto2000
Copy link
Copy Markdown
Contributor

followup PR of #16004.

  • Fixed return type
    • Returns [] on failure and when using gVim.
  • Fixed doc
    • Clarified that it returns [] on failure and when using gVim.
    • Fix return type to list<any>
  • I created new test file test_getcellpixels.vim and move test implementation.


// failed get pixel size.
if (cs.cs_xpixel == -1)
return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps move this above the allocation of the list. So we do not try to allocate when it is not neccessary

test_functions \
test_function_lists \
test_ga \
test_getcellpixels \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this deserves it's own test. Let's just move the test into test_functions.vim

CheckNotMSWindows
let cellpixels = getcellpixels()
call assert_equal(2, len(cellpixels))
endfunc
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a second test like this:

func Test_getcellpixels_gui()
  if has("gui_running")
    call assert_equal([], getcellpixels())
  endif
endfunc

@mikoto2000
Copy link
Copy Markdown
Contributor Author

Hmm, the test is failing now.

Maybe it wasn't running before.

https://github.com/vim/vim/actions/runs/11827146010/job/32954690492?pr=16047#step:18:3418

Failing with ioctl?

Consider how to identify the problem.

@mikoto2000
Copy link
Copy Markdown
Contributor Author

I added call ch_logfile('Test_getcellpixels.log', 'w') to the test code to check if ioctl was failing.

" Test for getcellwidth()
" Pixel size of a cell is terminal-dependent, so in the test, only the list and size 2 are checked.
func Test_getcellpixels()
" Not yet Windows-compatible
CheckNotMSWindows
call ch_logfile('Test_getcellpixels.log', 'w')
let cellpixels = getcellpixels()
call assert_equal(2, len(cellpixels))
endfunc

As a result, it was found that ioctl failed.

$ head -n 2 testdir/Test_getcellpixels.log
==== start log session Wed Nov 13 23:47:25 2024 ====
0.000002764 : ioctl(TIOCGWINSZ) failed

In Vim's test, ioctl doesn't work?

How do we test this?

@zeertzjq
Copy link
Copy Markdown
Member

RunVimInTerminal?

@mikoto2000
Copy link
Copy Markdown
Contributor Author

Oh, out of habit I was running it inside the Vim terminal.
I'll try running it again outside Vim.

@mikoto2000
Copy link
Copy Markdown
Contributor Author

Sorry, What mean RunVimInTerminal?

@zeertzjq
Copy link
Copy Markdown
Member

You can see Test_state() for a reference :)

@mikoto2000
Copy link
Copy Markdown
Contributor Author

Thank you. I maybe understand.

Comment on lines +4162 to +4163

" Test for getcellwidth()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
" Test for getcellwidth()
" Test for getcellpixels()

@ychin
Copy link
Copy Markdown
Contributor

ychin commented Nov 14, 2024

RunVimInTerminal?

RunVimInTerminal is an interesting situation because you are testing two things here. In addition to getcellpixels() in the Vim you are testing, you are also testing that the parent Vim is correctly passing the size info to the child Vim process to be tested.

In particular, the code here is doing the work of passing that info in to the Vim embedded terminal (and is what would end up being tested):

    int
mch_report_winsize(int fd, int rows, int cols)
{
    //...
    // calcurate and set tty pixel size
    struct cellsize cs;
    mch_calc_cell_size(&cs);
    ws.ws_xpixel = cols * cs.cs_xpixel;
    ws.ws_ypixel = rows * cs.cs_ypixel;

    retval = ioctl(tty_fd, TIOCSWINSZ, &ws);
    //...
}

It gets called to report the window size info to the embedded terminal in Vim's terminal.c (fd here is the fd for the embedded tty). Before the last PR, it used to be hard-coded to report a 5x10 pixel size which was not accurate. Now it's doing the right thing and passing the correct values along.

However, in this situation when the ioctl call in the parent Vim fails, it is going to set cs_xpixel to -1, which actually leads to kind of funky results in the above code as you get cols * -1 and rows * -1 which leads to some weird negative numbers. One way to fix it is to use a pre-canned 5x10 in this situation, or just use 0.

You can see this behavior just running Vim within Vim and then calling echo getcellsize() inside the child Vim.

@mikoto2000
Copy link
Copy Markdown
Contributor Author

@ychin Thank you for your comment.

One way to fix it is to use a pre-canned 5x10 in this situation, or just use 0.

Using a value of 5x10 when returning the value could lead the user to mistakenly believe that the result was correct, so we thought it would be better to change it to 0x0 (returning [0, 0]).

I will fix it.

diff --git a/src/os_unix.c b/src/os_unix.c
index 56bbc868d..80ca0ce26 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4434,8 +4434,18 @@ mch_report_winsize(int fd, int rows, int cols)
     // calcurate and set tty pixel size
     struct cellsize cs;
     mch_calc_cell_size(&cs);
-    ws.ws_xpixel = cols * cs.cs_xpixel;
-    ws.ws_ypixel = rows * cs.cs_ypixel;
+
+    if (cs.cs_xpixel == -1)
+    {
+        // failed get pixel size.
+        ws.ws_xpixel = 0;
+        ws.ws_ypixel = 0;
+    }
+    else
+    {
+        ws.ws_xpixel = cols * cs.cs_xpixel;
+        ws.ws_ypixel = rows * cs.cs_ypixel;
+    }
-
     retval = ioctl(tty_fd, TIOCSWINSZ, &ws);
     ch_log(NULL, "ioctl(TIOCSWINSZ) %s", retval == 0 ? "success" : "failed");

Fixed to return zero when failing to get pixel size.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants