Solution to Resolution Fallback in Windows 7 When HDMI Signal Lost
#1
After much tinkering I have come up with a solution which works great for me and will hopefully help others.
using EventGhost I created a python script which creates an eventghost event when the resolution changes, indicating what it has changed to. I then bound the event of it changing back to the HDTV resolution to a macro which closes and reopens XBMC. In my testing this solves the problem of XBMC being either at 1024x768 in the top left corner, or being blown up or frozen.
12/24/2011 Walkthrough:

Download and install the latest EventGhost.
Run EventGhost and create a new configuration. (File > New)
Right click on "Configuration Tree" and choose "Add Plugin"
Scroll through the list until you find "XBMC2" in the "Program Control" folder.
Choose "XBMC2" and press "OK". Adjust the settings as needed, no change is usually needed since we're running this on the XBMC PC.
Now select and copy the following code:

Code:
<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1534">
    <Folder Name="XBMC Resolution Fix" Expanded="True">
        <Macro Name="Check TV">
            <Event Name="Main.OnInit" />
            <Action>
                EventGhost.PythonScript(u'from threading import Thread, Event\nfrom win32api import EnumDisplayMonitors\nfrom win32api import GetSystemMetrics\nprevres = \'1\'\n\nclass MyThread(Thread):\n    def __init__(self):\n        Thread.__init__(self, name = \'CheckTV_Thread\')\n        self.event = Event()\n        self.tv = False\n        \n    def run(self):\n        global prevres\n        while True:\n            width = GetSystemMetrics(0)\n            height = GetSystemMetrics(1)\n            if prevres == \'1\':\n                prevres = str(width) + str(height)\n            if prevres != str(width) + str(height):\n                eg.TriggerEvent(str(width) + \'x\' + str(height), prefix = "ResolutionChanged")\n                prevres = str(width) + str(height)\n            self.event.wait(1)\n            self.event.clear()\n            \n\nmt = MyThread()\nmt.start()\n')
            </Action>
        </Macro>
        <Macro Name="SetDisplay and Toggle XBMC Fullscreen">
            <Event Name="ResolutionChanged.1920x1080" />
            <Event Name="ResolutionChanged.1024x768" />
            <Action>
                System.ChangeDisplaySettings(1, (1920L, 1080L), 60L, 32L, False, False)
            </Action>
            <Action>
                Window.FindWindow(None, u'XBMC', None, None, None, 1, False, 10.0, 0)
            </Action>
            <Action>
                Window.BringToFront()
            </Action>
            <Action>
                XBMC2.ToggleFullScreen()
            </Action>
        </Macro>
    </Folder>
</EventGhost>

Right click on "Configuration Tree" again and choose "Paste"
Now save this configuration somewhere (File > Save)
If you want this to run on startup there is an option to enable that under File > Options...

That should do it! Merry Christmas!



9/11/2011 UPDATE:
I've modified Hitcher's Version which toggles fullscreen instead of restarting XBMC. I've been using it and deem it better than my original Idea. :-)

PHP Code:
<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1534">
    <Folder Name="XBMC Resolution Fix" Expanded="True">
        <Macro Name="Check TV">
            <Event Name="Main.OnInit" />
            <Action>
                EventGhost.PythonScript(u'from threading import Thread, Event\nfrom win32api import EnumDisplayMonitors\nfrom win32api import GetSystemMetrics\nprevres = \'1\'\n\nclass MyThread(Thread):\n    def __init__(self):\n        Thread.__init__(self, name = \'CheckTV_Thread\')\n        self.event = Event()\n        self.tv = False\n        \n    def run(self):\n        global prevres\n        while True:\n            width = GetSystemMetrics(0)\n            height = GetSystemMetrics(1)\n            if prevres == \'1\':\n                prevres = str(width) + str(height)\n            if prevres != str(width) + str(height):\n                eg.TriggerEvent(str(width) + \'x\' + str(height), prefix = "ResolutionChanged")\n                prevres = str(width) + str(height)\n            self.event.wait(1)\n            self.event.clear()\n            \n\nmt = MyThread()\nmt.start()\n')
            </Action>
        </Macro>
        <Macro Name="SetDisplay and Toggle XBMC Fullscreen">
            <Event Name="ResolutionChanged.1920x1080" />
            <Event Name="ResolutionChanged.1024x768" />
            <Action>
                System.ChangeDisplaySettings(1, (1920L, 1080L), 60L, 32L, False, False)
            </Action>
            <Action>
                Window.FindWindow(None, u'XBMC', None, None, None, 1, False, 10.0, 0)
            </Action>
            <Action>
                Window.BringToFront()
            </Action>
            <Action>
                XBMC2.ToggleFullScreen()
            </Action>
        </Macro>
    </Folder>
</EventGhost> 



--Restarting XBMC version--
You may need to change the paths or the timings in the macro to work with your configuration.

Paste the following two boxes of code into the eventghost tree and give it a whirl!

Code:
<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1534">
    <Folder Name="Check TV" Expanded="True">
        <Macro Name="Check TV" Expanded="True">
            <Event Name="Main.OnInit" />
            <Action>
                EventGhost.PythonScript(u'from threading import Thread, Event\nfrom win32api import EnumDisplayMonitors\nfrom win32api import GetSystemMetrics\nprevres = \'1\'\n\nclass MyThread(Thread):\n    def __init__(self):\n        Thread.__init__(self, name = \'CheckTV_Thread\')\n        self.event = Event()\n        self.tv = False\n        \n    def run(self):\n        global prevres\n        while True:\n            width = GetSystemMetrics(0)\n            height = GetSystemMetrics(1)\n            if prevres == \'1\':\n                prevres = str(width) + str(height)\n            if prevres != str(width) + str(height):\n                eg.TriggerEvent(str(width) + \'x\' + str(height), prefix = "ResolutionChanged")\n                prevres = str(width) + str(height)\n            self.event.wait(1)\n            self.event.clear()\n            \n\nmt = MyThread()\nmt.start()\n')
            </Action>
        </Macro>
    </Folder>
</EventGhost>

Code:
<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1534">
    <Macro Name="RestartXBMConResEvent" Expanded="True">
        <Event Name="ResolutionChanged.1920x1080" />
        <Action>
            EventGhost.Wait(15.0)
        </Action>
        <Action>
            Window.FindWindow(None, u'XBMC', None, None, None, None, False, 0.0, 0)
        </Action>
        <Action>
            Window.Close()
        </Action>
        <Action>
            EventGhost.Wait(3.0)
        </Action>
        <Action>
            System.Execute(u'C:\\Program Files (x86)\\XBMC\\XBMC.exe', u'', 0, False, 2, u'C:\\Program Files (x86)\\XBMC', False)
        </Action>
        <Action>
            Window.FindWindow(None, u'XBMC', None, None, None, 1, False, 10.0, 0)
        </Action>
        <Action>
            Window.BringToFront()
        </Action>
    </Macro>
</EventGhost>



Old Solution that did not work for everyone or was not permanent:

So some people have had issues with windows 7 falling back to 1024x768 when changing HDMI sources or turning off their monitor/TV/Receiver. I was one of those people.

There is most likely a more elegant way to fix this, but this is pretty quick and painless.

1. Install tightVNC server on the XBMC PC
2. Turn off the Receiver/TV/Monitor
3. Log into the PC via VNC viewer (Behold your 1024x768 resolution!)
4. Open screen resolution settings and change it to whatever you want it to stay as (1920*1080 in my case)
5. Power your devices on and off as you like! Uninstall tightVNC server also if you're done with it.

Seems like windows 7 falls back to a default resolution when it has "no monitor" to output to, changing it while it is using that monitor saves it to the "no monitor." So now when it has "no monitor" it changes to the resolution you set to that, and so nothing really changes...
Reply
#2
Thanks a lot for posting! I've had this problem many times. Smile
Reply
#3
Excellent, going to try it later post my results.

Thanks.
Reply
#4
Didn't work for unfortunately because as soon as the HDMI signal is lost it reverts to VGA. So when I choose what resolution to run via TightVNC VGA is the only option - there's no HDMI.
Reply
#5
Interesting... I wonder where the difference lies in our setup. Video hardware dependant maybe?
Reply
#6
Maybe try forcing the resolution?

Access Requirements:
You must have Administrator access to the machine to make these changes.

Procedure:1.Click on Start, then Run
2.Type in regedit in the Open box, then hit [Enter]
3.Expand down to HKEY_CURRENT_CONFIG\System\CurrentControlSet\Contr ol\VIDEO\{Hexadecimal number for your primary video card}\00001.Note: Under VIDEO will be one or more registry keys that have a long hexadecimal number; this is the Hexidecimal number assigned to a specific physical or logical video card. There may be more than one if video cards have been changed or a major driver update has been performed. The key that has the current setting should be the one that needs to be modified.

4.Double-click DefautlSettings.XResolution, change the Base from Hexadecimal to Decimal notation, and set the X axis.
5.Double-click DefautlSettings.YResolution, change the Base from Hexadecimal to Decimal notation, and set the Y axis.
6.Reboot
•Note: If settings did not take effect, modify a different video card in the registry
•Note: If monitor ceases to function upon Windows coming up, reboot and go to Safe Mode. Pull up the registry and change the settings that were last modified back to the way it was or change the resolution to a safe resolution such as 640x480.
Reply
#7
Thanks the help but there's nothing in the VIDEO section of HKEY_CURRENT_CONFIG. The only place I can see them is under HKEY_LOCAL_MACHINE and in there it's already set to my HDMI settings.
Reply
#8
I had a suggestion from another forum which seems to have solved this problem for me:


Settings > System > Video Output > Turn off the "Use a fullscreen window rather than true fullscreen"

Try that and let me know if it works for you too.
Reply
#9
We know that fixes the problem but then it causes playback problems.
Reply
#10
After much tinkering I have come up with a solution which works great for me and will hopefully help others.
using EventGhost I created a python script which creates an eventghost event when the resolution changes, indicating what it has changed to. I then bound the event of it changing back to the HDTV resolution to a macro which closes and reopens XBMC. In my testing this solves the problem of XBMC being either at 1024x768 in the top left corner, or being blown up or frozen.

You may need to change the paths or the timings in the macro to work with your configuration.

Paste the following two boxes of code into the eventghost tree and give it a whirl!

Code:
<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1534">
    <Folder Name="Check TV" Expanded="True">
        <Macro Name="Check TV" Expanded="True">
            <Event Name="Main.OnInit" />
            <Action>
                EventGhost.PythonScript(u'from threading import Thread, Event\nfrom win32api import EnumDisplayMonitors\nfrom win32api import GetSystemMetrics\nprevres = \'1\'\n\nclass MyThread(Thread):\n    def __init__(self):\n        Thread.__init__(self, name = \'CheckTV_Thread\')\n        self.event = Event()\n        self.tv = False\n        \n    def run(self):\n        global prevres\n        while True:\n            width = GetSystemMetrics(0)\n            height = GetSystemMetrics(1)\n            if prevres == \'1\':\n                prevres = str(width) + str(height)\n            if prevres != str(width) + str(height):\n                eg.TriggerEvent(str(width) + \'x\' + str(height), prefix = "ResolutionChanged")\n                prevres = str(width) + str(height)\n            self.event.wait(1)\n            self.event.clear()\n            \n\nmt = MyThread()\nmt.start()\n')
            </Action>
        </Macro>
    </Folder>
</EventGhost>

Code:
<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1534">
    <Macro Name="RestartXBMConResEvent" Expanded="True">
        <Event Name="ResolutionChanged.1920x1080" />
        <Action>
            EventGhost.Wait(15.0)
        </Action>
        <Action>
            Window.FindWindow(None, u'XBMC', None, None, None, None, False, 0.0, 0)
        </Action>
        <Action>
            Window.Close()
        </Action>
        <Action>
            EventGhost.Wait(3.0)
        </Action>
        <Action>
            System.Execute(u'C:\\Program Files (x86)\\XBMC\\XBMC.exe', u'', 0, False, 2, u'C:\\Program Files (x86)\\XBMC', False)
        </Action>
        <Action>
            Window.FindWindow(None, u'XBMC', None, None, None, 1, False, 10.0, 0)
        </Action>
        <Action>
            Window.BringToFront()
        </Action>
    </Macro>
</EventGhost>
Reply
#11
I never realised so much can be done with EG.

As I'd rather not have XBMC close down and restart is there a way to window XBMC when the resolution changes, then fullscreen if and when it reverts back to 1980x1080?

Note: This is currently what I manually do when playing music and switching off the TV so the PC/XBMC doesn't crash.
Reply
#12
Hitcher Wrote:I never realised so much can be done with EG.

As I'd rather not have XBMC close down and restart is there a way to window XBMC when the resolution changes, then fullscreen if and when it reverts back to 1980x1080?

Note: This is currently what I manually do when playing music and switching off the TV so the PC/XBMC doesn't crash.

I'm sure it's possible some way or another. Is there a key combination that puts xbmc in windowed mode and fullscreen mode? Or does it have to be done through the menus?
Reply
#13
I'm part way there using the XBMC action ToggleFullScreen but I can't figure out how to make it initially toggle when the resolution changes from 1920x1080 to whatever it is when the TV is switched off.
Reply
#14
You should simply be able to add a second macro with the event trigger for whatever the resolution changes to. If you leave eventghost running when the change happens it should show up in the event list as ResolutionChanged.1024x768 or whatever the resolution is that it is falling back on.
Reply
#15
Ah now I get how it works.

Added ResolutionChanged.1024x768 to toggle once and ResolutionChanged.1920x1080 to toggle back again.

Testing now.

Thanks.
Reply

Logout Mark Read Team Forum Stats Members Help
Solution to Resolution Fallback in Windows 7 When HDMI Signal Lost0