sumatrapdf icon indicating copy to clipboard operation
sumatrapdf copied to clipboard

DDE SetView jumps to next page when setting scroll above certain value but it shouldn't

Open Universal-Invariant opened this issue 4 months ago • 5 comments

I'm using SetView(pdfname, "continuous",-1, 0,y)

To set the y scroll value to scroll the pdf in some reasonable way. Everything works unless y is a large value and then sumatra seems to round over the value to the next page and clamp it. So there is no way to get a continuous scrolls value.

It's hard to explain but it is obvious. Wrap the command above in V(y)

then doing V(100) scrolls the page a predicatble amount. V(200) V(300) V(400) jumps to next page which has zero scroll.

So I can't do V(500) or V(600). This means that I can only scroll about 60% of the page rather to 90% like I need.

In fact, it doesn't seem to make any sense what so after when large values are used. It seems that SumatraPDF has a bug in how it interprets the values and does not correctly handle them in a continuous view. One can't negative scroll either so there is no way to compensate if it jumps and go back a little.

It seems that SumatraPDF is interpreting the page as if it is in a single page view mode without interpolating between pages correctly in continuous mode. This effectively makes the command useless even though it is the only way to get a consistent and predictable scroll amount regardless of zoom.

This maybe because I'm using -1 which fits the page so it does some calculation afterwards but this value has to be specified.

It seems to work with setting the zoom to 0 but I'm not sure if this is universal. In some sense I want to fit the page and scroll. It clearly changes the zoom type so I'm worried there may be a consistency issue in some cases.

Universal-Invariant avatar Aug 20 '25 05:08 Universal-Invariant

Sorry hit the close accidentally

Hmmm PDF has a co-ordinate system like charts do when you scroll to 0 0 it would be lower left corner and viewers would find all scroll to's need to be negative such that scroll to 0 842 would be start of an A4 page.

MuPDF and thus SumatraPDF would find that hard to manage so each page viewport is based on a reversed Y calculation so 0 0 becomes top left same as rendered images would.

In continuous mode there is a tipping point at the page breaks (PDF does not have real concept of breaks or pages overflow from one to another only viewport does that due to relative placement). So when two pages are in view the top half would be say 400-800 and bottom half 0-400 in an oddly downward direction.

In theory using XY 0,700 should work to move that location to top left corner? Thus 140 points be showing in top part and the rest of the screen be showing next page object. but depending on zoom it does not "corner" the goto location.

Image

NOTE using -1 will not work on last page due to boundary conditions but should on all others from [0]=1 to [n-2] = last-1 Image

NOTE the page indicator DRIVEN says 1 but a manual user scrolling will see 2 in the indicator as it is the majority of viewport!

THUS as observed any other command like scroll to 500 will apply to SECOND PAGE NOT FIRST and if sent again show 3rd page

Image Image

There are many other odd limitations in Driving a PDF and as for Fullscreen the f is a toggle on off and for audio renders no way to know if on or off (apart from where the window boundary is) MuPDF does not even offer go to by co-ordinate so that has been added by SumatraPDF.

Part of MuPDF controls Image

GitHubRulesOK avatar Aug 20 '25 11:08 GitHubRulesOK

SumatraPDF is command streams so to go forwards 200 try

execute -s SUMATRA -t control -c "[GotoPage(\"c:\test\file.pdf\", 2)][SetView(\"C:\test\file.pdf\", \"continuous\",-1,0,200)]"
timeout 1
execute -s SUMATRA -t control -c "[GotoPage(\"c:\test\file.pdf\", 2)][SetView(\"C:\test\file.pdf\", \"continuous\",-1,0,400)]"
timeout 1
execute -s SUMATRA -t control -c "[GotoPage(\"c:\test\file.pdf\", 2)][SetView(\"C:\test\file.pdf\", \"continuous\",-1,0,600)]"
timeout 1
execute -s SUMATRA -t control -c "[GotoPage(\"c:\test\file.pdf\", 2)][SetView(\"C:\test\file.pdf\", \"continuous\",-1,0,800)]"

GitHubRulesOK avatar Aug 20 '25 16:08 GitHubRulesOK

Yes, the issue is when setting the zoom to something like -1, -2, likely -3 as it will execute those actions then scroll. This means if one scrolls essentially more than half a page when it zooms to fit page it will fit the next page. Luckily setting the zoom to 0 seems to fix this in the sense that it won't change the zoom and allows scrolling past 50%.

I just don't know how setting to zoom to 0 will generally work in different configurations. I guess I'll just have to find out the hard way. So far it is working.

As far as getting full screen info. I don't know how you can say the things you said. 100% Sumatra has to know it is either in full screen or not. If it doesn't then it is a flaw in the design. Every togglable setting always has an initial state. If sumatrapdf is not tracking those then it should. It's not as if sumatrapdf is started in a random state. If it were then every time you started sumatrapdf you would have to toggle some states to get the thing back to the way you wanted. Either sumatrapdf persists certain states when shutdown by saving them and then loading them on the next run(which we know it does for some) or it initalizes them to a deterministic default state.

Every toggle of a binary state is then going to be easily tracked deterministically since it is an involution. In fact:

https://github.com/sumatrapdfreader/sumatrapdf/blob/cdadfde74471e9b06898e5c1e87edd98b4204597/src/SumatraPDF.h#L192

https://github.com/sumatrapdfreader/sumatrapdf/blob/cdadfde74471e9b06898e5c1e87edd98b4204597/src/SumatraPDF.h#L125

https://github.com/sumatrapdfreader/sumatrapdf/blob/cdadfde74471e9b06898e5c1e87edd98b4204597/src/SumatraPDF.cpp#L4057

void ToggleFullScreen(MainWindow* win, bool presentation) {
    bool enterFullScreen = presentation ? !win->presentation : !win->isFullScreen;

    if (win->presentation || win->isFullScreen) {
        ExitFullScreen(win);
    } else {
        RememberDefaultWindowPosition(win);
    }

    if (enterFullScreen && (!presentation || win->IsDocLoaded())) {
        EnterFullScreen(win, presentation);
    }
}

https://github.com/sumatrapdfreader/sumatrapdf/blob/cdadfde74471e9b06898e5c1e87edd98b4204597/mupdf/platform/java/example/Viewer.java#L1107


	protected void toggleFullscreen() {
		isFullscreen = !isFullscreen; // <----- HERE

		if (isFullscreen)
			setExtendedState(Frame.MAXIMIZED_BOTH);
		else
			setExtendedState(Frame.NORMAL);
	}

So the state is clearly saved in isFullscreen and it could be no other way(toggles are not magic).

So I have no idea why you say the things you say. I have noticed it as a pattern where you say that something can't be done because of xyz but it never makes sense. It makes it seem like you don't understand programming much or just assume that it can't be done because sumatrapdf already doesn't do it.

So could you explain why you say those things? Is there something I'm missing? Maybe what you are saying is that muPDF does not export the functionality to do so and SumatraPDF is based on muPDF? (I didn't know it was until I just looked) This doesn't mean it is impossible but that without modifying muPDF then sumatraPDF can't use that functionality. And then for some reason SumatraPDF is restricted from modifying muPDF? (doesn't maintain it's own fork and does't put in changes)

in any case there is:

protected boolean isFullscreen = false;

All muPDF would need to export is something like getFullScreenState() { return isFullscreen; } or it could also create a isFullscreen that is toggled in the same way(so it attempts to follow isFullscreen in muPDF) but this could result in an inconsistent state if fullscreen can be set in ways outside of sumatraPDF or the tracking isn't handled in every possible setting of fullscreen.

I don't know enough about sumatraPDF's design but if it's based on muPDF(which I also no nothing about) then maybe the solution would to be to maintain a fork of muPDF and modify that to export what is needed so that sumatraPDF can become more robust?

These are not difficult programming problems(very basic in fact) but if sumatraPDF is basically a wrapper around muPDF and muPDF encapsulates all these useful features then maybe it would be better to deal with the muPDF side of things?

Universal-Invariant avatar Aug 20 '25 17:08 Universal-Invariant

You need to ask developer I am just front of house bartender. I had to write my own DDE controler in Windows native Console.net code., for above demo. The maximised/full screen flipping is based on WINDOWS reactions. So YES SumatraPDF holds an initial state in settings and monitors user keys as to isFullScreen current (https://github.com/sumatrapdfreader/sumatrapdf/blob/cdadfde74471e9b06898e5c1e87edd98b4204597/mupdf/platform/gl/gl-main.c#L225) for escape but does not expose the current state to out of memory until end of session.

And YES it probably could be exported but that is not a function anybody wrote, you could read settings file for last state intermittent change.

SumatraPDF does not use the java code stream it uses the core c components and does c++ modify as few as practical, it inherits MuPDF losses and gains!

GitHubRulesOK avatar Aug 20 '25 22:08 GitHubRulesOK

Ok, I had no idea that SumatraPDF sat on top of muPDF and I don't know enough about either to know how difficult it is to do these relatively basic things. If several internal states of muPDF can stay consistent with sumatraPDF because all their changes first go through sumatraPDF then it might, almost always, stay consistent without any need to modify muPDF. Basically what you said about isFullScreen. in this case a Cmd version should easily be doable. There is no real need for it outside of DDE which is likely why it wasn't added but it is useful for DDE as is setters for the other togglables.

Universal-Invariant avatar Aug 21 '25 04:08 Universal-Invariant