• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
1

app.Displaying considered unreliable

Community Expert ,
Jan 27, 2018 Jan 27, 2018

Copy link to clipboard

Copied

Der friends,

The white document hits again... ( see https://forums.adobe.com/thread/2276988) and I tracked it down to failing app.Displaying. The script requests function SetDisplay (bWanted) 17 times successful, but the 18. call does not switch the display any more. The routine is that simple:

function SetDisplay (bWanted) { //=== Set display to on or off ====================================
// Arguments bWanted: true => set display ON; false => display OFF
// Commment  This function does not work reliably. See https://forums.adobe.com/thread/2276988
// Reference Rick Quattro
    Console ("    current:" + app.Displaying + " => wanted: " + bWanted);
  if (app.Displaying != bWanted) {
    app.Displaying = bWanted;
    Console ("    set ? " + app.Displaying);
  }
} //--- end SetDisplay

Just after the following log the document gets white:

....SetDisplay(true)
    current:0 => wanted: true
    set ? 0

That is, app.Displaying was not performed and hence the document is not visible.

The white document appears within a routine which collects variables from the document. Since this function switches between pages and even page types I want to avoid flicker - which is really annoying here.

Do you spot something dubious in this routine?

function CollectVarsInDoc (oDoc, aDocVars) { //=== Collect variables in the 'natural' order =======
// Arguments oDoc:        current document
//           aDocVars:    array to be filled with var objects
// Called by xxx
// Calling   GetFindParameters, SetDisplay, SaveCurrentLocation, RestoreLocation
// Comment   Variables are found on all page types (Body, Master, Reference).
//           Starting points must be oDoc.FirstBodyPageInDoc, .FirstMasterPageInDoc, .FirstRefPageInDoc
var aVarsRange = [], bIsSystem, findParams, jFound = 0, jPageType, iVrLen, oFirst, oPage, oPara,
    oSavedLoc, oTextItem,  oTR = new TextRange(), oVar, sVarName, sValue,
    aPages = [oDoc.FirstBodyPageInDoc, oDoc.FirstMasterPageInDoc, oDoc.FirstRefPageInDoc];

  SetDisplay (false);
  oSavedLoc = SaveCurrentLocation (oDoc);
  aDocVars.length = 0;                            // clear array for refill
  if (oDoc == null) {                             // emergency bailing out   
    SetDisplay (true);
    return;
  }              
  for (jPageType = 0; jPageType < 3; jPageType++) { // for all page types
    oFirst = aPages[jPageType];
    if (oFirst.id == 0 && jPageType != 1) {continue}; // only master page(s) exist
    oDoc.CurrentPage = oFirst;
    oPage = oDoc.CurrentPage;
    oPara = oPage.PageFrame.FirstGraphicInFrame.FirstPgf;
    while (oPara == undefined) {                  // can happen on ref pages
      oPage = oPage.PageNext;
      if (oPage.id == 0) {
        goFMv.nDocVars = aDocVars.length;
        RestoreLocation (oDoc, oSavedLoc);
        SetDisplay (true);
        return;}                                  // no next page available
      oPara = oPage.PageFrame.FirstGraphicInFrame.FirstPgf;
    }
    oTR   = oDoc.TextSelection;
    oTR.beg.obj =  oTR.end.obj = oPara;
    oDoc.TextSelection = oTR;
    oTR.beg.offset = oTR.end.offset = 0;

    findParams = GetFindParameters (2, null);     // finding any variable, no wrap
    InitFA_errno ();                              // reset - it is write protected
    oTR = oDoc.Find(oTR.beg, findParams);         // and do an initial find to get started.

    while(FA_errno === Constants.FE_Success) {
      jFound += 1;
      oDoc.TextSelection = oTR;                   // set up the text range
      aVarsRange = oDoc.GetTextForRange (oTR, Constants.FTI_VarBegin);  // this is an array
      iVrLen = aVarsRange.length;                 // have not found anything other than 1 to be correct
      if (iVrLen === 0) {                         // Hickup ?
        InitFA_errno ();                          // track the progress
        oTR = oDoc.Find(oTR.beg, findParams);     // prepare for next find
        continue;                                 // while
      }
      oTextItem = aVarsRange[0];                  // have not found anything other than 1 to be correct
      oVar = oTextItem.obj;
      sVarName = oVar.VarFmt.Name;                // name of the variable
      sValue   = oVar.VarFmt.Fmt;                 // contents of variable
      oTR      = oVar.TextRange;                  // the text range of the variable
      bIsSystem= (oVar.VarFmt.SystemVar !== Constants.FV_VAR_USER_VARIABLE);
      aDocVars.push (new oVariable (sVarName, sValue, oVar, bIsSystem, oTR));
      InitFA_errno ();                            // track the progress
      oTR = oDoc.Find(oTR.beg, findParams);       // prepare for next find
    }
  }
  goFMv.nDocVars = goFMv.aoDocVars.length;
  RestoreLocation (oDoc, oSavedLoc);
  SetDisplay (true);
} //--- end CollectVarsInDoc

From a more detailed trace I know that the statement on line 66 is in charge.

TOPICS
Scripting

Views

897

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 27, 2018 Jan 27, 2018

Somewhere along the line, Adobe changed the Displaying property from a toggle (on or off) to a stack-based property. So the problem comes when Displaying is set to the same value more than once. I don't remember the details, but the solution is simple:

// Make sure Displaying is on before you turn it off.

if (app.Displaying === 1) {

    app.Displaying = 0;

}

...

// Make sure Displaying is off before you turn it on.

if (app.Displaying === 0) {

    app.Displaying = 1;

}

Votes

Translate

Translate
Community Expert ,
Jan 27, 2018 Jan 27, 2018

Copy link to clipboard

Copied

Somewhere along the line, Adobe changed the Displaying property from a toggle (on or off) to a stack-based property. So the problem comes when Displaying is set to the same value more than once. I don't remember the details, but the solution is simple:

// Make sure Displaying is on before you turn it off.

if (app.Displaying === 1) {

    app.Displaying = 0;

}

...

// Make sure Displaying is off before you turn it on.

if (app.Displaying === 0) {

    app.Displaying = 1;

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 28, 2018 Jan 28, 2018

Copy link to clipboard

Copied

Thanks Rick, but isn't my code observing the basic rule: avoid to set the current setting again?

function SetDisplay (bWanted) { //=== Set display to on or off ====================================
// Arguments bWanted: true => set display ON; false => display OFF
var bCurrent = app.Displaying;
  if (bCurrent != bWanted) {                      // if current setting not the wanted one
    app.Displaying = bWanted;                     // set to the wanted one
  }
} //--- end SetDisplay

bCurrentbWantedActiom
truetrueif is bypassed
truefalseapp.Displaying = false
falsetrueapp.Displaying = true
falsefalseif is bypassed

IMHO my code is correct - but my logic might be wrong!

Klaus

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 28, 2018 Jan 28, 2018

Copy link to clipboard

Copied

Hi Klaus. After looking at your SetDisplay function, it looks like your logic is correct. I am sorry for not reading more carefully and following the thread you mentioned.

I would not worry about setting Displaying inside of a function like this. I always do it in my main function, usually "processDoc". I am not sure, but maybe there is a problem when calling it too many times.

main ();

function main () {

    // Test for active doc or book, etc.

    // and call processDoc or processBook.

    processDoc (app.ActiveDoc);

}

function processDoc (doc) {

    // Do any required tests here. Return if necessary.

    // Now worry about the display.

    if (app.Displaying === 1) {

        app.Displaying = 0;

    }

    // Call my various functions, etc.

    abc (doc);

    xyz (doc);

    // Restore the display.

    if (app.Displaying === 0) {

        app.Displaying = 1;

    }

}

function processBook (book) {

    // For each book component, open it and call processDoc.

    processDoc (doc);

}

function xyz (doc) {

}

function abc (doc) {

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 31, 2018 Jan 31, 2018

Copy link to clipboard

Copied

Dear all,

I can not follow Rick's advice to place the SetDisplay function high up in the function hierarchy. The function creating the flicker (CollectVarsInDoc traverses all types of pages in a document) initially  is called at level 2. Later it is called on level 3 below Notify. The crux in my situation is the need of Notify: Documents can be opened, closed or switched while the palette is open.

Extensive traces and tests have again shown that SetDisplay creates a white screen if it was ‘entered’ via Notify. Hence I decided to leave out the ‘antiflicker’ function. It turns out that flicker is acceptable even in a 55 pages document, because obviously not all pages are to be displayed or the displays are superseded by the next one and hence appear like skipped.

My script is about "avoid the proliferation of distinct dialogues" for common tasks on variables ...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 03, 2018 Feb 03, 2018

Copy link to clipboard

Copied

After further tests, experiments, frustration and coffees I state:

  • SetDisplay works well as long as it called in the normal flow of script execution.
  • As soon as it is entered via the Notify route the "white document" effect may/does occur.

Hence I have removed the call to SetDisplay within function CollectVarsInDoc and instead wrapped it around the calls of this function - except in the calling route from Notify.

This avoids the "white document" behavior and restricts the flicker caused by CollectVarsInDoc to few cases.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 14, 2023 Jan 14, 2023

Copy link to clipboard

Copied

LATEST

Thank you, Klaus, the SetDisplay function you coded is extremely helpful. Real game-changer for all the issues I had with the "white page".

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines