Skip to content

Fix: Resolved ViewMode race condition and added Global View override (by Gemini AI) #1167

@60secondsassassin

Description

@60secondsassassin

Expected Behavior

When a specific View ID (e.g., 51 for Posters in Estuary) is defined in the addon settings for a category (Movies, TV Shows, etc.), Elementum should consistently apply that view mode when the directory is opened.

Current Behavior

Even when correct View IDs are set, Kodi often ignores the command and defaults to IconWall or List view. This happens because the Container.SetViewMode command is being triggered before the directory is finalized or rendered, creating a race condition where the UI isn't ready to receive the view change.

Possible Solution

1/ Lifecycle Reordering: Move the xbmcplugin.endOfDirectory call before the Container.SetViewMode logic in navigation.py.

2/ Synchronization Delay: Introduce a small xbmc.sleep() (approx. 400ms) after the directory is closed to allow the skin to render the container before the view mode is forced.

3/ Global Override: Add a "Global View Mode" toggle in settings.xml to allow users to force a single Skin ID across all Elementum lists, simplifying setup for users who want a uniform look.

The reason your SetViewMode isn't working as expected is that it's being called before the directory is finalized. In Kodi, you cannot successfully tell the UI to change its view until the list is actually finished and rendered.

Here is the exact modification you need to make to the end of your navigation.py file to fix the timing and implement the Global Mode.


1. The Modified Code Block

Replace the last ~12 lines of your navigation.py (the ones starting from # Set ViewMode) with this:

    # 1. Finalize the directory FIRST. 
    # Kodi needs the list to be "closed" before it can apply a view style.
    xbmcplugin.endOfDirectory(HANDLE, succeeded=True, updateListing=False, cacheToDisc=True)

    # 2. Apply ViewMode with Global Logic and Timing Fix
    if data["content_type"]:
        # Check if Global Mode is enabled (assumes you added this to settings.xml)
        if ADDON.getSetting("viewmode_global_enabled") == "true":
            viewMode = ADDON.getSetting("viewmode_global_id")
            log.debug("Elementum: Using Global View Mode: %s" % viewMode)
        else:
            # Fallback to granular settings
            viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"])
            log.debug("Elementum: Using Granular View Mode: %s for %s" % (viewMode, data["content_type"]))

        if viewMode and viewMode != "0":
            try:
                # The Timing Fix: 
                # Wait 400ms to let the skin "catch up" and render the items.
                xbmc.sleep(400) 
                xbmc.executebuiltin('Container.SetViewMode(%s)' % viewMode)
            except Exception as e:
                log.warning("Unable to SetViewMode(%s): %s" % (viewMode, repr(e)))

2. Why this fixes it

  1. The Order: In your original code, xbmcplugin.endOfDirectory was the very last line. By moving it above the SetViewMode call, we ensure Kodi has received all the data before we try to change the layout.
  2. The Sleep: Even with the order fixed, Kodi is often still "drawing" the list items when the command arrives. The xbmc.sleep(400) ensures the UI is ready to listen to the SetViewMode command.
  3. The Logic: I’ve added the check for viewmode_global_enabled. This allows you to toggle between "One ID for everything" and the category-specific IDs you already have.

3. Update your resources/settings.xml

For the "Global" logic above to work, you must make sure these two lines exist in your settings.xml file (within the same category as your other view settings):

<setting id="viewmode_global_enabled" type="bool" label="Enable Global View Mode" default="false" />
<setting id="viewmode_global_id" type="number" label="Global View ID (e.g. 51)" default="50" enable="eq(-1,true)" />

4. How to Test

  1. Save the changes to navigation.py.
  2. Restart Kodi.
  3. Go to Elementum settings and enable Global View Mode.
  4. Set the Global View ID to 51.
  5. Open a movie list. It should now consistently land on the Poster view.

Note

If it still shows IconWall, try increasing xbmc.sleep(400) to xbmc.sleep(800). Some hardware (like older Android boxes or Raspberries) needs more time to render the UI.

Steps to Reproduce (for bugs)

1/ Use the default Estuary skin.
2/ In Elementum settings, ensure viewmode_movies is set to 51.
3/ Navigate to Movies > Most Popular.
4/ Observe that the view often defaults to IconWall instead of the expected Poster view.
Manually changing the view works, but it does not "stick" or apply automatically on the next visit.

Context

I am trying to achieve a consistent visual experience across the addon. Currently, the "Set default view" feature in Elementum is unreliable on many systems (especially lower-end hardware) because the Python script finishes its execution before the Kodi UI has finished preparing the view container.

Your Environment

  • Version used: Elementum 0.1.112
  • Environment name and version: Kodi 21.3
  • Operating System and version: Opensuse Leap 15.6 / tvOS 26
  • Link to Kodi debug log: N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions