diff -pruN 0.6.7.1-1/bin/MangoHud.conf 0.6.8-1/bin/MangoHud.conf
--- 0.6.7.1-1/bin/MangoHud.conf	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/bin/MangoHud.conf	1970-01-01 00:00:00.000000000 +0000
@@ -1,223 +0,0 @@
-### MangoHud configuration file
-### Uncomment any options you wish to enable. Default options are left uncommented
-### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
-### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead
-
-################ PERFORMANCE #################
-
-### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced)
-# fps_limit=
-
-### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
-# vsync=
-
-### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N)
-# gl_vsync=
-
-################### VISUAL ###################
-
-### Legacy layout
-# legacy_layout=false
-
-### Display custom centered text, useful for a header
-# custom_text_center=
-
-### Display the current system time
-# time
-
-### Time formatting examples
-# time_format=%H:%M
-# time_format=[ %T %F ]
-# time_format=%X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese)
-
-### Display MangoHud version
-# version
-
-### Display the current GPU information
-gpu_stats
-# gpu_temp
-# gpu_core_clock
-# gpu_mem_clock
-# gpu_power
-# gpu_text=GPU
-# gpu_load_change
-# gpu_load_value=60,90
-# gpu_load_color=39F900,FDFD09,B22222
-
-### Display the current CPU information
-cpu_stats
-# cpu_temp
-# cpu_power
-# cpu_text=CPU
-# cpu_mhz
-# cpu_load_change
-# cpu_load_value=60,90
-# cpu_load_color=39F900,FDFD09,B22222
-
-### Display the current CPU load & frequency for each core
-# core_load
-# core_load_change
-
-### Display IO read and write for the app (not system)
-# io_stats
-# io_read
-# io_write
-
-### Display system vram / ram / swap space usage
-# vram
-# ram
-# swap
-
-### Display per process memory usage
-## Show resident memory and other types, if enabled
-# procmem
-# procmem_shared
-# procmem_virt
-
-### Display battery information
-# battery
-# battery_icon
-# gamepad_battery
-# gamepad_battery_icon
-
-### Display FPS and frametime
-fps
-# fps_sampling_period=500
-# fps_color_change
-# fps_value=30,60
-# fps_color=B22222,FDFD09,39F900
-frametime
-# frame_count
-
-### Display miscellaneous information
-# engine_version
-# gpu_name
-# vulkan_driver
-# wine
-
-### Display loaded MangoHud architecture
-# arch
-
-### Display the frametime line graph
-frame_timing
-# histogram
-
-### Display GameMode / vkBasalt running status
-# gamemode
-# vkbasalt
-
-### Display current FPS limit
-# show_fps_limit
-
-### Display the current resolution
-# resolution
-
-### Display custom text
-# custom_text=
-### Display output of Bash command in next column
-# exec=
-
-### Display media player metadata
-# media_player
-# media_player_name=spotify
-## Format metadata, lines are delimited by ; (wip)
-# media_player_format={title};{artist};{album}
-# media_player_format=Track:;{title};By:;{artist};From:;{album}
-
-### Change the hud font size
-# font_size=24
-# font_scale=1.0
-# font_size_text=24
-# font_scale_media_player=0.55
-# no_small_font
-
-### Change default font (set location to TTF/OTF file)
-## Set font for the whole hud
-# font_file=
-
-## Set font only for text like media player metadata
-# font_file_text=
-
-## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these
-## Probably don't enable all at once because of memory usage and hardware limits concerns
-## If you experience crashes or text is just squares, reduce glyph range or reduce font size
-# font_glyph_ranges=korean,chinese,chinese_simplified,japanese,cyrillic,thai,vietnamese,latin_ext_a,latin_ext_b
-
-### Change the hud position
-# position=top-left
-
-### Change the corner roundness
-# round_corners=
-
-### Disable / hide the hud by default
-# no_display
-
-### Hud position offset
-# offset_x=
-# offset_y=
-
-### Hud dimensions
-# width=
-# height=
-# table_columns=
-# cellpadding_y=
-
-### Hud transparency / alpha
-# background_alpha=0.5
-# alpha=
-
-### Color customization
-# text_color=FFFFFF
-# gpu_color=2E9762
-# cpu_color=2E97CB
-# vram_color=AD64C1
-# ram_color=C26693
-# engine_color=EB5B5B
-# io_color=A491D3
-# frametime_color=00FF00
-# background_color=020202
-# media_player_color=FFFFFF
-# wine_color=EB5B5B
-# battery_color=FF9078
-
-### Specify GPU with PCI bus ID for AMDGPU and NVML stats
-### Set to 'domain:bus:slot.function'
-# pci_dev=0:0a:0.0
-
-### Blacklist
-# blacklist=
-
-################ WORKAROUNDS #################
-### Options starting with "gl_*" are for OpenGL
-### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable
-# gl_size_query=viewport
-
-### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III
-# gl_bind_framebuffer=0
-
-### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx
-# gl_dont_flip=1
-
-################ INTERACTION #################
-
-### Change toggle keybinds for the hud & logging
-# toggle_hud=Shift_R+F12
-# toggle_fps_limit=Shift_L+F1
-# toggle_logging=Shift_L+F2
-# reload_cfg=Shift_L+F4
-# upload_log=Shift_L+F3
-
-#################### LOG #####################
-### Automatically start the log after X seconds
-# autostart_log=1
-### Set amount of time in seconds that the logging will run for
-# log_duration=
-### Change the default log interval, 100 is default
-# log_interval=100
-### Set location of the output files (required for logging)
-# output_folder=/home/<USERNAME>/mangologs
-### Permit uploading logs directly to FlightlessMango.com
-# permit_upload=1
-### Define a '+'-separated list of percentiles shown in the benchmark results
-### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1
-# benchmark_percentiles=97,AVG,1,0.1
diff -pruN 0.6.7.1-1/bin/mangohud.in 0.6.8-1/bin/mangohud.in
--- 0.6.7.1-1/bin/mangohud.in	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/bin/mangohud.in	2022-08-01 01:27:11.000000000 +0000
@@ -22,7 +22,7 @@ fi
 # Preload using the plain filenames of the libs, the dynamic linker will
 # figure out whether the 32 or 64 bit version should be used, and will search
 # for it in the correct directory
-LD_PRELOAD="${LD_PRELOAD}:${MANGOHUD_LIB_NAME}"
-LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:@ld_libdir_mangohud@"
+LD_PRELOAD="${LD_PRELOAD}${LD_PRELOAD:+:}${MANGOHUD_LIB_NAME}"
+LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${LD_LIBRARY_PATH:+:}@ld_libdir_mangohud@"
 
 exec env MANGOHUD=1 LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" LD_PRELOAD="${LD_PRELOAD}" "$@"
diff -pruN 0.6.7.1-1/control/src/control/__init__.py 0.6.8-1/control/src/control/__init__.py
--- 0.6.7.1-1/control/src/control/__init__.py	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/control/src/control/__init__.py	2022-08-01 01:27:11.000000000 +0000
@@ -10,9 +10,9 @@ import argparse
 
 TIMEOUT = 1.0 # seconds
 
-VERSION_HEADER = bytearray('MesaOverlayControlVersion', 'utf-8')
+VERSION_HEADER = bytearray('MangoHudControlVersion', 'utf-8')
 DEVICE_NAME_HEADER = bytearray('DeviceName', 'utf-8')
-MESA_VERSION_HEADER = bytearray('MesaVersion', 'utf-8')
+MANGOHUD_VERSION_HEADER = bytearray('MangoHudVersion', 'utf-8')
 
 DEFAULT_SERVER_ADDRESS = "\0mangohud"
 
@@ -160,21 +160,48 @@ def control(args):
 
     version = None
     name = None
-    mesa_version = None
+    mangohud_version = None
 
     msgs = msgparser.readCmd(3)
 
+    for m in msgs:
+        cmd, param = m
+        if cmd == VERSION_HEADER:
+            version = int(param)
+        elif cmd == DEVICE_NAME_HEADER:
+            name = param.decode('utf-8')
+        elif cmd == MANGOHUD_VERSION_HEADER:
+            mangohud_version = param.decode('utf-8')
+
     if args.info:
         info = "Protocol Version: {}\n"
         info += "Device Name: {}\n"
-        info += "Mesa Version: {}"
-        print(info.format(version, name, mesa_version))
+        info += "MangoHud Version: {}"
+        print(info.format(version, name, mangohud_version))
 
 
     if args.cmd == 'toggle-logging':
         conn.send(bytearray(':logging;', 'utf-8'))
+    elif args.cmd == 'start-logging':
+        conn.send(bytearray(':logging=1;', 'utf-8'))
+
+    elif args.cmd == 'stop-logging':
+        conn.send(bytearray(':logging=0;', 'utf-8'))
+        now = time.monotonic()
+        while True:
+            msg = str(conn.recv(3))
+            if "LoggingFinished" in msg:
+                print("Logging has stopped")
+                exit(0)
+            elapsed = time.monotonic() - now
+            if elapsed > 3:
+                print("Stop logging timed out")
+                exit(1)
+
     elif args.cmd == 'toggle-hud':
         conn.send(bytearray(':hud;', 'utf-8'))
+    elif args.cmd == 'toggle-fcat':
+        conn.send(bytearray(':fcat;', 'utf-8'))
 
 def main():
     parser = argparse.ArgumentParser(description='MangoHud control client')
@@ -184,10 +211,13 @@ def main():
     commands = parser.add_subparsers(help='commands to run', dest='cmd')
     commands.add_parser('toggle-hud')
     commands.add_parser('toggle-logging')
+    commands.add_parser('start-logging')
+    commands.add_parser('stop-logging')
+    commands.add_parser('toggle-fcat')
 
     args = parser.parse_args()
 
     control(args)
 
 if __name__ == '__main__':
-    main()
\ No newline at end of file
+    main()
diff -pruN 0.6.7.1-1/data/io.github.flightlessmango.mangohud.metainfo.xml 0.6.8-1/data/io.github.flightlessmango.mangohud.metainfo.xml
--- 0.6.7.1-1/data/io.github.flightlessmango.mangohud.metainfo.xml	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/data/io.github.flightlessmango.mangohud.metainfo.xml	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="generic">
+  <id>io.github.flightlessmango.mangohud</id>
+
+  <name>MangoHud</name>
+  <summary>Vulkan/OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more</summary>
+  <developer_name>FlightlessMango</developer_name>
+  <icon type="stock">io.github.flightlessmango.mangohud</icon>
+
+  <metadata_license>CC0-1.0</metadata_license>
+  <project_license>MIT</project_license>
+
+  <description>
+    <p>A modification of the Mesa Vulkan overlay, including GUI improvements with HUD configuration, temperature reporting, and logging capabilities. Includes a script (mangohud) to start it on any OpenGL or Vulkan application.</p>
+  </description>
+
+  <screenshots>
+    <screenshot type="default">
+      <caption>Example</caption>
+      <image>https://raw.githubusercontent.com/flightlessmango/MangoHud/master/assets/overlay_example.gif</image>
+    </screenshot>
+    <screenshot>
+      <caption>Log uploading walkthrough</caption>
+      <image>https://raw.githubusercontent.com/flightlessmango/MangoHud/master/assets/log_upload_example.gif</image>
+    </screenshot>
+  </screenshots>
+
+  <url type="homepage">https://github.com/flightlessmango/MangoHud</url>
+  <url type="bugtracker">https://github.com/flightlessmango/MangoHud/issues</url>
+  <url type="donation">https://www.paypal.me/flightlessmango</url>
+
+  <provides>
+    <binary>mangohud</binary>
+  </provides>
+
+  <categories>
+    <category>Utility</category>
+    <category>Game</category>
+  </categories>
+
+  <content_rating type="oars-1.1" />
+</component>
diff -pruN 0.6.7.1-1/data/io.github.flightlessmango.mangohud.svg 0.6.8-1/data/io.github.flightlessmango.mangohud.svg
--- 0.6.7.1-1/data/io.github.flightlessmango.mangohud.svg	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/data/io.github.flightlessmango.mangohud.svg	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,373 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="73.101814mm"
+   height="86.038353mm"
+   viewBox="0 0 73.101814 86.038353"
+   version="1.1"
+   id="svg3290"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
+   sodipodi:docname="io.github.flightlessmango.mangohud.svg">
+  <title
+     id="title5515">FlightlessMango Icon</title>
+  <defs
+     id="defs3284">
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2486">
+      <rect
+         style="opacity:1;stroke-width:0.75"
+         id="rect2488"
+         width="207.21774"
+         height="243.88824"
+         x="893.77185"
+         y="-713.32947"
+         transform="scale(1,-1)" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2344">
+      <path
+         d="M 0,2000 H 2000 V 0 H 0 Z"
+         id="path2342" />
+    </clipPath>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="-313.85759"
+     inkscape:cy="470.82412"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     inkscape:document-rotation="0"
+     showgrid="false"
+     units="mm"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1274"
+     inkscape:window-height="1056"
+     inkscape:window-x="1280"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata3287">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>FlightlessMango Icon</dc:title>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by/4.0/" />
+        <dc:date>2020-11-14</dc:date>
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>FlightlessMango</dc:title>
+          </cc:Agent>
+        </dc:creator>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by/4.0/">
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction" />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution" />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-0.06554034,-0.07012108)">
+    <g
+       id="g2338"
+       clip-path="url(#clipPath2486)"
+       transform="matrix(0.35277777,0,0,-0.35277777,-315.2373,251.7169)">
+      <g
+         id="g2340"
+         clip-path="url(#clipPath2344)">
+        <g
+           id="g2346"
+           transform="translate(683.6049,1312.4586)">
+          <path
+             d="M 0,0 V -4.41 H -11.995 V -14.829 H 0 v -4.41 H -11.995 V -34.09 h -4.411 V 0 Z"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2348" />
+        </g>
+        <path
+           d="m 715.713,1278.369 h -4.432 v 34.111 h 4.432 z"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           id="path2350" />
+        <path
+           d="m 748.695,1278.369 h -4.41 v 21.924 h 4.41 z m -0.022,30.042 c 0.611,-0.597 0.916,-1.328 0.916,-2.195 0,-0.867 -0.305,-1.598 -0.916,-2.195 -0.611,-0.596 -1.342,-0.894 -2.194,-0.894 -0.839,0 -1.563,0.298 -2.173,0.894 -0.611,0.597 -0.916,1.328 -0.916,2.195 0,0.867 0.305,1.598 0.916,2.195 0.61,0.596 1.334,0.895 2.173,0.895 0.852,0 1.583,-0.299 2.194,-0.895"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           id="path2352" />
+        <g
+           id="g2354"
+           transform="translate(796.2708,1291.6427)">
+          <path
+             d="m 0,0 c -0.27,1.349 -0.951,2.571 -2.045,3.665 -1.478,1.491 -3.267,2.237 -5.369,2.237 -2.103,0 -3.896,-0.746 -5.38,-2.237 -1.485,-1.492 -2.227,-3.281 -2.227,-5.37 0,-2.102 0.742,-3.895 2.227,-5.379 1.484,-1.485 3.277,-2.227 5.38,-2.227 2.102,0 3.891,0.739 5.369,2.216 1.094,1.094 1.775,2.301 2.045,3.622 z M 0.022,7.137 V 8.65 H 4.453 V -7.649 c 0,-4.261 -1.158,-7.549 -3.473,-9.864 -2.372,-2.089 -5.234,-3.133 -8.586,-3.133 -3.352,0 -6.215,1.044 -8.587,3.133 -0.483,0.483 -1.256,1.463 -2.322,2.94 l 4.389,1.576 c 0.568,-0.681 0.952,-1.121 1.15,-1.321 1.492,-1.477 3.282,-2.215 5.37,-2.215 3.508,0 5.937,2.301 7.287,6.903 -1.378,-2.671 -3.743,-4.006 -7.095,-4.006 -3.353,0 -6.211,1.151 -8.576,3.452 -2.365,2.301 -3.547,5.127 -3.547,8.479 0,3.353 1.182,6.211 3.547,8.576 2.365,2.365 5.223,3.548 8.576,3.548 2.826,0 5.305,-1.094 7.436,-3.282"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2356" />
+        </g>
+        <g
+           id="g2358"
+           transform="translate(829.0182,1312.4586)">
+          <path
+             d="m 0,0 h 4.432 v -14.531 c 1.235,2.372 3.025,3.558 5.369,3.558 2.344,0 4.215,-0.841 5.614,-2.524 1.399,-1.683 2.12,-3.796 2.163,-6.339 V -34.09 h -4.411 v 14.084 c 0,1.264 -0.358,2.347 -1.076,3.249 -0.717,0.902 -1.85,1.353 -3.398,1.353 -1.832,0 -3.253,-0.98 -4.261,-2.94 V -34.09 H 0 Z"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2360" />
+        </g>
+        <g
+           id="g2362"
+           transform="translate(877.4686,1300.2928)">
+          <path
+             d="M 0,0 V 8.224 H 4.41 V 0 H 8.352 V -4.41 H 4.41 V -21.924 H 0 V -4.41 H -3.942 V 0 Z"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2364" />
+        </g>
+        <path
+           d="m 917.204,1278.369 h -4.432 v 34.111 h 4.432 z"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           id="path2366" />
+        <g
+           id="g2368"
+           transform="translate(959.6033,1296.9692)">
+          <path
+             d="m 0,0 c -0.497,0.384 -1.613,0.575 -3.345,0.575 -2.088,0 -3.875,-0.742 -5.359,-2.226 -1.484,-1.485 -2.226,-3.278 -2.226,-5.38 0,-1.719 0.191,-2.834 0.575,-3.345 z m -7.372,-13.636 c 0.738,-0.654 2.08,-0.98 4.027,-0.98 2.102,0 3.899,0.739 5.39,2.216 0.185,0.199 0.561,0.639 1.129,1.321 l 4.411,-1.577 c -1.08,-1.491 -1.861,-2.479 -2.344,-2.961 -2.372,-2.373 -5.234,-3.558 -8.586,-3.558 -3.338,0 -6.193,1.185 -8.565,3.558 -2.373,2.372 -3.558,5.234 -3.558,8.586 0,3.352 1.185,6.214 3.558,8.587 2.372,2.371 5.227,3.557 8.565,3.557 2.869,0 5.383,-0.866 7.542,-2.599 C 4.552,2.216 4.9,1.896 5.241,1.556 5.383,1.413 5.787,0.966 6.456,0.213 L 4.24,-2.024 Z"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2370" />
+        </g>
+        <g
+           id="g2372"
+           transform="translate(998.5509,1283.0776)">
+          <path
+             d="M 0,0 C 0.525,-0.511 1.151,-0.767 1.875,-0.767 2.6,-0.767 3.221,-0.511 3.74,0 4.258,0.512 4.517,1.143 4.517,1.896 4.517,2.621 4.261,3.239 3.75,3.75 3.395,4.105 2.635,4.652 1.47,5.39 c -1.591,0.867 -2.72,1.634 -3.388,2.301 -1.165,1.165 -1.746,2.564 -1.746,4.198 0,1.647 0.581,3.057 1.746,4.229 1.165,1.172 2.571,1.758 4.219,1.758 1.647,0 3.019,-0.554 4.113,-1.662 0.78,-0.781 1.278,-1.655 1.49,-2.621 L 3.622,12.358 c -0.1,0.354 -0.199,0.589 -0.298,0.703 -0.256,0.255 -0.597,0.383 -1.023,0.383 -0.426,0 -0.792,-0.152 -1.097,-0.458 -0.306,-0.305 -0.458,-0.671 -0.458,-1.097 0,-0.426 0.149,-0.788 0.447,-1.087 C 1.463,10.547 2.074,10.113 3.026,9.503 4.787,8.536 6.065,7.656 6.861,6.86 8.238,5.468 8.928,3.814 8.928,1.896 c 0,-1.96 -0.686,-3.632 -2.057,-5.017 -1.37,-1.385 -3.036,-2.078 -4.996,-2.078 -1.946,0 -3.608,0.696 -4.985,2.088 -0.953,0.952 -1.577,2.138 -1.876,3.559 l 4.39,0.937 C -0.468,0.732 -0.27,0.27 0,0"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2374" />
+        </g>
+        <g
+           id="g2376"
+           transform="translate(1039.1595,1283.0776)">
+          <path
+             d="m 0,0 c 0.525,-0.511 1.151,-0.767 1.875,-0.767 0.724,0 1.346,0.256 1.865,0.767 0.518,0.512 0.777,1.143 0.777,1.896 0,0.725 -0.256,1.343 -0.767,1.854 -0.355,0.355 -1.116,0.902 -2.28,1.64 -1.591,0.867 -2.72,1.634 -3.388,2.301 -1.165,1.165 -1.746,2.564 -1.746,4.198 0,1.647 0.581,3.057 1.746,4.229 1.165,1.172 2.571,1.758 4.219,1.758 1.647,0 3.019,-0.554 4.113,-1.662 0.78,-0.781 1.278,-1.655 1.49,-2.621 L 3.622,12.358 c -0.1,0.354 -0.199,0.589 -0.298,0.703 -0.256,0.255 -0.597,0.383 -1.023,0.383 -0.426,0 -0.792,-0.152 -1.097,-0.458 -0.306,-0.305 -0.458,-0.671 -0.458,-1.097 0,-0.426 0.149,-0.788 0.447,-1.087 C 1.463,10.547 2.074,10.113 3.026,9.503 4.787,8.536 6.065,7.656 6.861,6.86 8.238,5.468 8.928,3.814 8.928,1.896 c 0,-1.96 -0.686,-3.632 -2.057,-5.017 -1.37,-1.385 -3.036,-2.078 -4.996,-2.078 -1.946,0 -3.608,0.696 -4.985,2.088 -0.953,0.952 -1.577,2.138 -1.876,3.559 l 4.39,0.937 C -0.468,0.732 -0.27,0.27 0,0"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2378" />
+        </g>
+        <g
+           id="g2380"
+           transform="translate(1080.4086,1312.4586)">
+          <path
+             d="M 0,0 11.058,-19.111 22.072,0 H 26.1 V -34.09 H 21.69 V -9.46 L 11.058,-27.868 0.384,-9.46 V -34.09 H -4.027 V 0 Z"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2382" />
+        </g>
+        <g
+           id="g2384"
+           transform="translate(1154.7667,1288.2979)">
+          <path
+             d="m 0,0 v 3.239 c -0.256,1.377 -0.938,2.627 -2.046,3.749 -1.491,1.477 -3.281,2.216 -5.369,2.216 -2.102,0 -3.896,-0.739 -5.379,-2.216 -1.485,-1.477 -2.227,-3.267 -2.227,-5.369 0,-2.088 0.742,-3.874 2.227,-5.358 1.483,-1.485 3.277,-2.227 5.379,-2.227 2.088,0 3.878,0.738 5.369,2.216 1.108,1.122 1.79,2.372 2.046,3.75 m 0,10.461 v 1.534 H 4.432 V -9.95 H 0 v 2.748 c -2.131,-2.201 -4.603,-3.302 -7.415,-3.302 -3.352,0 -6.21,1.183 -8.576,3.547 -2.365,2.365 -3.547,5.224 -3.547,8.576 0,3.352 1.182,6.211 3.547,8.576 2.366,2.365 5.224,3.547 8.576,3.547 2.812,0 5.284,-1.094 7.415,-3.281"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2386" />
+        </g>
+        <g
+           id="g2388"
+           transform="translate(1191.8602,1294.4125)">
+          <path
+             d="M 0,0 V -16.043 H -4.432 V 5.88 H 0 V 3.324 c 0.923,2.499 2.777,3.749 5.561,3.749 2.372,0 4.257,-0.841 5.657,-2.524 1.399,-1.683 2.12,-3.796 2.162,-6.339 V -16.043 H 8.97 V -1.96 C 8.97,-0.696 8.508,0.387 7.585,1.289 6.661,2.191 5.561,2.642 4.282,2.642 3.018,2.642 1.925,2.202 1.001,1.321 0.49,0.796 0.156,0.355 0,0"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2390" />
+        </g>
+        <g
+           id="g2392"
+           transform="translate(1252.5187,1291.6427)">
+          <path
+             d="m 0,0 c -0.271,1.349 -0.952,2.571 -2.046,3.665 -1.477,1.491 -3.267,2.237 -5.369,2.237 -2.102,0 -3.896,-0.746 -5.379,-2.237 -1.485,-1.492 -2.227,-3.281 -2.227,-5.37 0,-2.102 0.742,-3.895 2.227,-5.379 1.483,-1.485 3.277,-2.227 5.379,-2.227 2.102,0 3.892,0.739 5.369,2.216 1.094,1.094 1.775,2.301 2.046,3.622 z M 0.021,7.137 V 8.65 H 4.453 V -7.649 c 0,-4.261 -1.158,-7.549 -3.473,-9.864 -2.372,-2.089 -5.235,-3.133 -8.586,-3.133 -3.353,0 -6.215,1.044 -8.587,3.133 -0.483,0.483 -1.257,1.463 -2.322,2.94 l 4.388,1.576 c 0.569,-0.681 0.952,-1.121 1.152,-1.321 1.491,-1.477 3.28,-2.215 5.369,-2.215 3.507,0 5.937,2.301 7.286,6.903 -1.378,-2.671 -3.743,-4.006 -7.095,-4.006 -3.352,0 -6.21,1.151 -8.576,3.452 -2.365,2.301 -3.547,5.127 -3.547,8.479 0,3.353 1.182,6.211 3.547,8.576 2.366,2.365 5.224,3.548 8.576,3.548 2.827,0 5.305,-1.094 7.436,-3.282"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2394" />
+        </g>
+        <g
+           id="g2396"
+           transform="translate(1290.7312,1295.3074)">
+          <path
+             d="m 0,0 c -1.484,-1.492 -2.226,-3.281 -2.226,-5.369 0,-2.102 0.742,-3.892 2.226,-5.369 1.484,-1.477 3.278,-2.216 5.38,-2.216 2.102,0 3.895,0.739 5.38,2.216 1.484,1.477 2.226,3.267 2.226,5.369 0,2.088 -0.742,3.877 -2.226,5.369 C 9.275,1.492 7.482,2.237 5.38,2.237 3.278,2.237 1.484,1.492 0,0 m 5.38,6.775 c 3.352,0 6.211,-1.186 8.575,-3.558 2.365,-2.372 3.548,-5.234 3.548,-8.586 0,-3.353 -1.183,-6.214 -3.548,-8.587 -2.364,-2.372 -5.223,-3.557 -8.575,-3.557 -3.338,0 -6.193,1.185 -8.565,3.557 -2.372,2.373 -3.558,5.234 -3.558,8.587 0,3.352 1.186,6.214 3.558,8.586 2.372,2.372 5.227,3.558 8.565,3.558"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2398" />
+        </g>
+        <path
+           d="M 2000,0 H 5 v 983 h 1995 z"
+           style="fill:#fffae3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           id="path2400" />
+        <g
+           id="g2402"
+           transform="translate(757.9102,452.8965)">
+          <path
+             d="m 0,0 v -7.977 h 6.042 v -3.947 H 0 V -24.251 H -4.271 V 3.947 H 7.533 V 0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2404" />
+        </g>
+        <g
+           id="g2406"
+           transform="translate(797.7944,432.6738)">
+          <path
+             d="M 0,0 V -4.028 H -11.4 V 24.17 h 4.27 L -7.13,0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2408" />
+        </g>
+        <path
+           d="m 818.666,456.844 h 4.27 v -28.198 h -4.27 z"
+           style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           id="path2410" />
+        <g
+           id="g2412"
+           transform="translate(858.5898,450.4785)">
+          <path
+             d="m 0,0 v -1.934 l -4.109,-0.201 v 1.693 c 0,2.255 -0.846,3.262 -2.497,3.262 -1.652,0 -2.498,-1.007 -2.498,-2.86 v -15.388 c 0,-1.853 0.806,-2.86 2.458,-2.86 1.651,0 2.457,1.007 2.457,3.263 v 4.834 h -2.417 v 3.948 H 0 v -9.226 c 0,-4.269 -2.457,-6.767 -6.728,-6.767 -4.229,0 -6.646,2.498 -6.646,6.767 V 0 c 0,4.271 2.417,6.768 6.646,6.768 C -2.457,6.768 0,4.271 0,0"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2414" />
+        </g>
+        <g
+           id="g2416"
+           transform="translate(890.0957,428.6455)">
+          <path
+             d="M 0,0 V 12.286 H -5.075 V 0 h -4.271 v 28.198 h 4.271 V 16.314 H 0 V 28.198 H 4.271 V 0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2418" />
+        </g>
+        <g
+           id="g2420"
+           transform="translate(924.0195,452.8154)">
+          <path
+             d="M 0,0 V -24.17 H -4.271 V 0 H -8.822 V 4.028 H 4.552 V 0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2422" />
+        </g>
+        <g
+           id="g2424"
+           transform="translate(960.8022,432.6738)">
+          <path
+             d="M 0,0 V -4.028 H -11.4 V 24.17 h 4.27 L -7.13,0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2426" />
+        </g>
+        <g
+           id="g2428"
+           transform="translate(985.9434,452.8965)">
+          <path
+             d="m 0,0 v -7.977 h 6.244 v -3.947 H 0 v -8.379 h 7.734 v -3.948 H -4.27 V 3.947 H 7.734 V 0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2430" />
+        </g>
+        <g
+           id="g2432"
+           transform="translate(1026.7549,450.9219)">
+          <path
+             d="m 0,0 v -0.725 l -4.109,-0.403 v 1.048 c 0,1.611 -0.766,2.457 -2.175,2.457 -1.41,0 -2.176,-0.846 -2.176,-2.457 v -0.363 c 0,-1.652 0.726,-3.061 3.585,-5.479 3.908,-3.303 5.358,-5.639 5.358,-9.023 v -1.409 c 0,-4.029 -2.377,-6.326 -6.606,-6.326 -4.231,0 -6.606,2.297 -6.606,6.326 v 1.893 l 4.108,0.402 v -2.013 c 0,-1.774 0.806,-2.659 2.417,-2.659 1.611,0 2.417,0.885 2.417,2.659 v 0.926 c 0,1.772 -0.846,3.182 -3.706,5.599 -3.907,3.303 -5.236,5.64 -5.236,8.943 V 0 c 0,4.028 2.295,6.324 6.364,6.324 C -2.297,6.324 0,4.028 0,0"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2434" />
+        </g>
+        <g
+           id="g2436"
+           transform="translate(1059.3076,450.9219)">
+          <path
+             d="m 0,0 v -0.725 l -4.109,-0.403 v 1.048 c 0,1.611 -0.766,2.457 -2.175,2.457 -1.41,0 -2.176,-0.846 -2.176,-2.457 v -0.363 c 0,-1.652 0.726,-3.061 3.585,-5.479 3.908,-3.303 5.358,-5.639 5.358,-9.023 v -1.409 c 0,-4.029 -2.377,-6.326 -6.606,-6.326 -4.231,0 -6.606,2.297 -6.606,6.326 v 1.893 l 4.108,0.402 v -2.013 c 0,-1.774 0.806,-2.659 2.417,-2.659 1.611,0 2.417,0.885 2.417,2.659 v 0.926 c 0,1.772 -0.846,3.182 -3.706,5.599 -3.907,3.303 -5.236,5.64 -5.236,8.943 V 0 c 0,4.028 2.295,6.324 6.364,6.324 C -2.297,6.324 0,4.028 0,0"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2438" />
+        </g>
+        <g
+           id="g2440"
+           transform="translate(1094.3184,428.6455)">
+          <path
+             d="M 0,0 V 19.577 H -0.081 L -3.626,4.028 H -6.163 L -9.708,19.577 H -9.789 V 0 h -4.028 v 28.198 h 5.599 l 3.344,-15.146 h 0.08 L -1.49,28.198 H 4.271 V 0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2442" />
+        </g>
+        <g
+           id="g2444"
+           transform="translate(1125.542,438.918)">
+          <path
+             d="M 0,0 H 3.586 L 1.854,11.883 H 1.732 Z m 5.076,-10.272 -0.927,6.405 h -4.712 l -0.927,-6.405 h -4.27 l 4.874,28.198 h 5.439 l 4.874,-28.198 z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2446" />
+        </g>
+        <g
+           id="g2448"
+           transform="translate(1165.8701,428.6455)">
+          <path
+             d="M 0,0 -5.599,18.691 H -5.68 V 0 h -4.028 v 28.198 h 4.754 L 0.081,11.4 H 0.162 V 28.198 H 4.189 V 0 Z"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2450" />
+        </g>
+        <g
+           id="g2452"
+           transform="translate(1205.7158,450.4785)">
+          <path
+             d="m 0,0 v -1.934 l -4.108,-0.201 v 1.693 c 0,2.255 -0.846,3.262 -2.497,3.262 -1.653,0 -2.499,-1.007 -2.499,-2.86 v -15.388 c 0,-1.853 0.806,-2.86 2.458,-2.86 1.652,0 2.457,1.007 2.457,3.263 v 4.834 h -2.416 v 3.948 H 0 v -9.226 c 0,-4.269 -2.457,-6.767 -6.727,-6.767 -4.23,0 -6.646,2.498 -6.646,6.767 V 0 c 0,4.271 2.416,6.768 6.646,6.768 C -2.457,6.768 0,4.271 0,0"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2454" />
+        </g>
+        <g
+           id="g2456"
+           transform="translate(1231.7031,450.0762)">
+          <path
+             d="m 0,0 v -14.663 c 0,-2.095 0.927,-3.223 2.618,-3.223 1.693,0 2.619,1.128 2.619,3.223 V 0 C 5.237,2.095 4.311,3.223 2.618,3.223 0.927,3.223 0,2.095 0,0 m 9.507,0.04 v -14.743 c 0,-4.432 -2.618,-7.131 -6.889,-7.131 -4.269,0 -6.889,2.699 -6.889,7.131 V 0.04 c 0,4.432 2.62,7.13 6.889,7.13 4.271,0 6.889,-2.698 6.889,-7.13"
+             style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2458" />
+        </g>
+        <g
+           id="g2460"
+           transform="translate(1100.9401,661.5807)">
+          <path
+             d="m 0,0 c 0,0 -31.4,46.786 -77.244,51.496 0,0 -86.911,9.978 -106.761,-96.712 -3.373,-18.131 -3.024,-34.734 0.124,-49.549 9.467,-10.111 23.255,-20.105 40.687,-27.366 19.155,-7.978 26.834,-21.155 29.838,-31.678 18.644,26.846 1.258,68.715 1.258,68.715 19.468,-6.28 27.318,-35.796 27.318,-35.796 10.362,11.304 19.154,43.332 -0.314,67.196 -14.232,17.446 -13.816,42.076 -11.618,51.496 3.172,13.595 15.085,25.277 29.045,25.277 13.96,0 25.277,-11.317 25.277,-25.277 0,-8.236 -7.629,-15.162 -12.234,-21.266 -21.443,-28.425 6.896,-39.65 8.78,-69.48 4.359,-69.014 -50.868,-64.057 -50.868,-64.057 -1.587,-5.818 -8.659,-12.973 -10.85,-15.085 0.003,0 0.007,-10e-4 0.011,-0.002 0.065,0.043 0.103,0.066 0.103,0.066 l 5.242,-0.849 c 26.536,-3 53.043,7.333 68.922,34.083 C 7.536,-70.022 -91.06,-52.124 0,0"
+             style="fill:#f7941e;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2462" />
+        </g>
+        <g
+           id="g2464"
+           transform="translate(1038.7678,651.5327)">
+          <path
+             d="m 0,0 c 5.116,0 9.263,4.147 9.263,9.263 0,1.321 -0.281,2.575 -0.779,3.712 C 7.875,12.379 7.042,12.01 6.123,12.01 c -1.864,0 -3.375,1.512 -3.375,3.376 0,0.919 0.368,1.752 0.964,2.361 C 2.575,18.245 1.321,18.526 0,18.526 -5.116,18.526 -9.263,14.379 -9.263,9.263 -9.263,4.147 -5.116,0 0,0"
+             style="fill:#f7941e;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2466" />
+        </g>
+        <g
+           id="g2468"
+           transform="translate(993.389,489.493)">
+          <path
+             d="m 0,0 c -0.013,-0.008 -0.028,-0.019 -0.043,-0.029 -0.151,-0.1 -0.411,-0.281 -0.75,-0.549 -1.987,-1.572 -6.576,-6.075 -6.361,-14.016 0.273,-10.12 8.456,-4.177 7.895,1.106 -0.561,5.282 5.368,12.581 5.368,12.581 L 5.346,-0.783 0.103,0.066 C 0.103,0.066 0.065,0.043 0,0"
+             style="fill:#74a643;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2470" />
+        </g>
+        <g
+           id="g2472"
+           transform="translate(987.5845,507.7722)">
+          <path
+             d="m 0,0 c -3.004,10.522 -10.684,23.7 -29.839,31.678 -17.432,7.26 -31.219,17.254 -40.686,27.365 -9.959,10.637 -15.137,21.403 -14.738,29.25 0,0 -26.008,-65.675 13.438,-101.405 34.576,-31.319 71.326,-7.651 71.326,-7.651 0,0 -45.521,6.117 -65.664,49.919 0,0 24.448,-30.526 52.688,-41.624 4.976,-1.956 10.07,-3.313 15.169,-3.789 0,0 0.912,7.13 -1.694,16.257"
+             style="fill:#74a643;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path2474" />
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff -pruN 0.6.7.1-1/data/mangoapp.1 0.6.8-1/data/mangoapp.1
--- 0.6.7.1-1/data/mangoapp.1	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/data/mangoapp.1	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,39 @@
+.\" Manpage for mangoapp.
+.TH mangoapp 1 "" "" "mangoapp"
+
+.SH NAME
+mangoapp \- transparent background application with a built in mangohud
+
+.SH SYNOPSIS
+\fBmangoapp\fR
+
+.SH DESCRIPTION
+MangoHud is a Vulkan/OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more.
+.PP
+Mangoapp is a transparent background opengl application with a built in MangoHud. It's designed to be run inside a
+gamescope instance which will display mangoapp ontop of gamescopes output. It also takes frame information from
+gamescope. The purpose of this is to "easily" make MangoHud compatible with any application, or at least any
+application that gamescope can run. This solves issues with some OpenGL games and certain ports that have stdc++ issues
+as it's no longer directly injected into the game.
+
+.SH USAGE
+Create a script (e.g. \fBrun.sh\fR) containing the app you want to run (e.g. \fBvkcube\fR) and \fBmangoapp\fR like so:
+.PP
+.RS 4
+.EX
+#!/bin/sh
+
+vkcube&
+mangoapp
+.EE
+.RE
+.PP
+And then run it with \fBgamescope ./run.sh\fR.
+
+.SH SEE ALSO
+mangohud(1)
+
+.SH ABOUT
+MangoHud development takes place at \fIhttps://github.com/flightlessmango/MangoHud\fR.
+.br
+Benchmarks created with MangoHud can be uploaded to \fIhttps://flightlessmango.com\fR.
diff -pruN 0.6.7.1-1/data/MangoHud.conf 0.6.8-1/data/MangoHud.conf
--- 0.6.7.1-1/data/MangoHud.conf	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/data/MangoHud.conf	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,239 @@
+### MangoHud configuration file
+### Uncomment any options you wish to enable. Default options are left uncommented
+### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
+### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead
+
+################ PERFORMANCE #################
+
+### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced)
+# fps_limit=
+
+### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
+# vsync=
+
+### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N)
+# gl_vsync=
+
+################### VISUAL ###################
+
+### Legacy layout
+# legacy_layout=false
+
+### Display custom centered text, useful for a header
+# custom_text_center=
+
+### Display the current system time
+# time
+
+### Time formatting examples
+# time_format=%H:%M
+# time_format=[ %T %F ]
+# time_format=%X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese)
+
+### Display MangoHud version
+# version
+
+### Display the current GPU information
+gpu_stats
+# gpu_temp
+# gpu_core_clock
+# gpu_mem_clock
+# gpu_power
+# gpu_text=GPU
+# gpu_load_change
+# gpu_load_value=60,90
+# gpu_load_color=39F900,FDFD09,B22222
+
+### Display the current CPU information
+cpu_stats
+# cpu_temp
+# cpu_power
+# cpu_text=CPU
+# cpu_mhz
+# cpu_load_change
+# cpu_load_value=60,90
+# cpu_load_color=39F900,FDFD09,B22222
+
+### Display the current CPU load & frequency for each core
+# core_load
+# core_load_change
+
+### Display IO read and write for the app (not system)
+# io_stats
+# io_read
+# io_write
+
+### Display system vram / ram / swap space usage
+# vram
+# ram
+# swap
+
+### Display per process memory usage
+## Show resident memory and other types, if enabled
+# procmem
+# procmem_shared
+# procmem_virt
+
+### Display battery information
+# battery
+# battery_icon
+# gamepad_battery
+# gamepad_battery_icon
+
+### Display FPS and frametime
+fps
+# fps_sampling_period=500
+# fps_color_change
+# fps_value=30,60
+# fps_color=B22222,FDFD09,39F900
+frametime
+# frame_count
+
+### Display miscellaneous information
+# engine_version
+# gpu_name
+# vulkan_driver
+# wine
+
+### Display loaded MangoHud architecture
+# arch
+
+### Display the frametime line graph
+frame_timing
+# histogram
+
+### Display GameMode / vkBasalt running status
+# gamemode
+# vkbasalt
+
+### Display current FPS limit
+# show_fps_limit
+
+### Display the current resolution
+# resolution
+
+### Display custom text
+# custom_text=
+### Display output of Bash command in next column
+# exec=
+
+### Display media player metadata
+# media_player
+# media_player_name=spotify
+## Format metadata, lines are delimited by ; (wip)
+# media_player_format={title};{artist};{album}
+# media_player_format=Track:;{title};By:;{artist};From:;{album}
+
+### Change the hud font size
+# font_size=24
+# font_scale=1.0
+# font_size_text=24
+# font_scale_media_player=0.55
+# no_small_font
+
+### Change default font (set location to TTF/OTF file)
+## Set font for the whole hud
+# font_file=
+
+## Set font only for text like media player metadata
+# font_file_text=
+
+## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these
+## Probably don't enable all at once because of memory usage and hardware limits concerns
+## If you experience crashes or text is just squares, reduce glyph range or reduce font size
+# font_glyph_ranges=korean,chinese,chinese_simplified,japanese,cyrillic,thai,vietnamese,latin_ext_a,latin_ext_b
+
+### Change the hud position
+# position=top-left
+
+### Change the corner roundness
+# round_corners=
+
+### Disable / hide the hud by default
+# no_display
+
+### Hud position offset
+# offset_x=
+# offset_y=
+
+### Hud dimensions
+# width=
+# height=
+# table_columns=
+# cellpadding_y=
+
+### Hud transparency / alpha
+# background_alpha=0.5
+# alpha=
+
+### FCAT overlay
+### This enables an FCAT overlay to perform frametime analysis on the final image stream.
+### Enable the overlay
+# fcat
+### Set the width of the FCAT overlay.
+### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs.
+### A minimum of 20 pixels is recommended by nVidia.
+# fcat_overlay_width=24
+### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise.
+# fcat_screen_edge=0
+
+### Color customization
+# text_color=FFFFFF
+# gpu_color=2E9762
+# cpu_color=2E97CB
+# vram_color=AD64C1
+# ram_color=C26693
+# engine_color=EB5B5B
+# io_color=A491D3
+# frametime_color=00FF00
+# background_color=020202
+# media_player_color=FFFFFF
+# wine_color=EB5B5B
+# battery_color=FF9078
+
+### Specify GPU with PCI bus ID for AMDGPU and NVML stats
+### Set to 'domain:bus:slot.function'
+# pci_dev=0:0a:0.0
+
+### Blacklist
+# blacklist=
+
+### Control over socket
+### Enable and set socket name, '%p' is replaced with process id
+# control = mangohud
+# control = mangohud-%p
+
+################ WORKAROUNDS #################
+### Options starting with "gl_*" are for OpenGL
+### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable
+# gl_size_query=viewport
+
+### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III
+# gl_bind_framebuffer=0
+
+### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx
+# gl_dont_flip=1
+
+################ INTERACTION #################
+
+### Change toggle keybinds for the hud & logging
+# toggle_hud=Shift_R+F12
+# toggle_fps_limit=Shift_L+F1
+# toggle_logging=Shift_L+F2
+# reload_cfg=Shift_L+F4
+# upload_log=Shift_L+F3
+
+#################### LOG #####################
+### Automatically start the log after X seconds
+# autostart_log=1
+### Set amount of time in seconds that the logging will run for
+# log_duration=
+### Change the default log interval, 100 is default
+# log_interval=100
+### Set location of the output files (required for logging)
+# output_folder=/home/<USERNAME>/mangologs
+### Permit uploading logs directly to FlightlessMango.com
+# permit_upload=1
+### Define a '+'-separated list of percentiles shown in the benchmark results
+### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1
+# benchmark_percentiles=97,AVG,1,0.1
diff -pruN 0.6.7.1-1/data/meson.build 0.6.8-1/data/meson.build
--- 0.6.7.1-1/data/meson.build	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/data/meson.build	2022-08-01 01:27:11.000000000 +0000
@@ -1,4 +1,49 @@
+man1dir = join_paths(get_option('mandir'), 'man1')
+datadir = get_option('datadir')
+metainfo_file = files('io.github.flightlessmango.mangohud.metainfo.xml')
+icon_file = files('io.github.flightlessmango.mangohud.svg')
+
+# Validate metainfo file
+ascli_exe = find_program('appstreamcli', required: get_option('tests'))
+if ascli_exe.found()
+  test('validate metainfo file',
+       ascli_exe,
+       args: ['validate',
+              '--no-net',
+              '--pedantic',
+              metainfo_file]
+  )
+endif
+
+# Install metainfo file
+install_data(
+  metainfo_file,
+  install_dir: join_paths(datadir, 'metainfo'),
+  install_tag : 'doc',
+)
+
+# Install icon for metainfo
+install_data(
+  icon_file,
+  install_dir: join_paths(datadir, 'icons', 'hicolor', 'scalable', 'apps'),
+  install_tag : 'doc',
+)
+
+# Install man pages
 install_man(
   files('mangohud.1'),
-  install_dir: join_paths(get_option('mandir'), 'man1'),
+  install_dir: man1dir,
+)
+if get_option('mangoapp')
+  install_man(
+    files('mangoapp.1'),
+    install_dir: man1dir,
+  )
+endif
+
+install_data(
+  files('MangoHud.conf'),
+  install_dir : join_paths(get_option('datadir'), 'doc', 'mangohud'),
+  rename : ['MangoHud.conf.example'],
+  install_tag : 'doc',
 )
diff -pruN 0.6.7.1-1/debian/changelog 0.6.8-1/debian/changelog
--- 0.6.7.1-1/debian/changelog	2022-07-05 09:50:00.000000000 +0000
+++ 0.6.8-1/debian/changelog	2022-08-01 08:25:18.000000000 +0000
@@ -1,3 +1,9 @@
+mangohud (0.6.8-1) unstable; urgency=medium
+
+  * New upstream version 0.6.8 (Closes: #1016209)
+
+ -- Stephan Lachnit <stephanlachnit@debian.org>  Mon, 01 Aug 2022 10:25:18 +0200
+
 mangohud (0.6.7.1-1) unstable; urgency=medium
 
   * New upstream version 0.6.7.1
diff -pruN 0.6.7.1-1/debian/copyright 0.6.8-1/debian/copyright
--- 0.6.7.1-1/debian/copyright	2022-07-05 09:47:54.000000000 +0000
+++ 0.6.8-1/debian/copyright	2022-08-01 08:25:18.000000000 +0000
@@ -7,6 +7,14 @@ Files: *
 Copyright: 2020-2022 flightlessmango <https://github.com/flightlessmango>
 License: MIT
 
+Files: data/io.github.flightlessmango.mangohud.metainfo.xml
+Copyright: 2020-2022 flightlessmango <https://github.com/flightlessmango>
+License: CC0-1.0
+
+Files: data/io.github.flightlessmango.mangohud.svg
+Copyright: 2020-2022 flightlessmango <https://github.com/flightlessmango>
+License: CC-BY-4.0
+
 Files: bin/gen_enum_to_str.py
        include/vulkan/vk_util.h
        src/vulkan.cpp
@@ -44,8 +52,8 @@ Copyright: 2007-2014 VMware, Inc.
 License: MIT
 
 Files: subprojects/imgui-*/*
-       src/gl/imgui_impl_opengl3.cpp
-       src/gl/imgui_impl_opengl3.h
+       src/gl/gl_renderer.cpp
+       src/gl/gl_renderer.h
 Copyright: 2014-2021 Omar Cornut <omar@miracleworld.net>
 License: MIT
 
@@ -202,3 +210,120 @@ License: OFL-1.1
  DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
  OTHER DEALINGS IN THE FONT SOFTWARE.
+
+License: CC0-1.0
+ To the extent possible under law, the author(s) have dedicated all
+ copyright and related and neighboring rights to this software to the public
+ domain worldwide. This software is distributed without any warranty.
+Comment:
+ On Debian systems, the complete text of the CC0 license, version 1.0,
+ can be found in "/usr/share/common-licenses/CC0-1.0".
+
+License: CC-BY-4.0
+ Creative Commons Attribution 4.0 International
+ .
+ Creative Commons Corporation ("Creative Commons") is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an "as-is" basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
+ .
+ Using Creative Commons Public Licenses
+ .
+ Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
+ .
+ Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors
+ .
+ Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor's permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public : wiki.creativecommons.org/Considerations_for_licensees
+ .
+ Creative Commons Attribution 4.0 International Public License
+ .
+ By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+ .
+ Section 1 – Definitions.
+ .
+    a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+    b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+    c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+    d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
+    e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
+    f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+    g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+    h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
+    i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
+    j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
+    k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
+ .
+ Section 2 – Scope.
+ .
+    a. License grant.
+        1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+            A. reproduce and Share the Licensed Material, in whole or in part; and
+            B. produce, reproduce, and Share Adapted Material.
+        2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+        3. Term. The term of this Public License is specified in Section 6(a).
+        4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+        5. Downstream recipients.
+            A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
+            B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
+        6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+    b. Other rights.
+        1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+        2. Patent and trademark rights are not licensed under this Public License.
+        3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
+ .
+ Section 3 – License Conditions.
+ .
+ Your exercise of the Licensed Rights is expressly made subject to the following conditions.
+ .
+    a. Attribution.
+        1. If You Share the Licensed Material (including in modified form), You must:
+            A. retain the following if it is supplied by the Licensor with the Licensed Material:
+                i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+                ii. a copyright notice;
+                iii. a notice that refers to this Public License;
+                iv. a notice that refers to the disclaimer of warranties;
+                v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+            B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
+            C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
+        2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
+        3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
+        4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
+ .
+ Section 4 – Sui Generis Database Rights.
+ .
+ Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
+ .
+    a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
+    b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
+    c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+ .
+ For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+ .
+ Section 5 – Disclaimer of Warranties and Limitation of Liability.
+ .
+    a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
+    b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
+    c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+ .
+ Section 6 – Term and Termination.
+ .
+    a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+    b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
+        1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
+        2. upon express reinstatement by the Licensor.
+    c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+    d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+    e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+ .
+ Section 7 – Other Terms and Conditions.
+ .
+    a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
+    b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
+ .
+ Section 8 – Interpretation.
+ .
+    a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+    b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+    c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+    d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+ .
+ Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the "Licensor." The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
+ .
+ Creative Commons may be contacted at creativecommons.org.
diff -pruN 0.6.7.1-1/debian/mangoapp.install 0.6.8-1/debian/mangoapp.install
--- 0.6.7.1-1/debian/mangoapp.install	2022-07-05 09:47:54.000000000 +0000
+++ 0.6.8-1/debian/mangoapp.install	2022-08-01 08:22:22.000000000 +0000
@@ -1,3 +1,4 @@
 usr/bin/mangoapp
 usr/lib/*/mangohud/libMangoApp.so
 usr/share/vulkan/implicit_layer.d/libMangoApp.json
+usr/share/man/man1/mangoapp.1
diff -pruN 0.6.7.1-1/debian/mangohud.install 0.6.8-1/debian/mangohud.install
--- 0.6.7.1-1/debian/mangohud.install	2022-07-05 09:47:54.000000000 +0000
+++ 0.6.8-1/debian/mangohud.install	2022-08-01 08:25:18.000000000 +0000
@@ -4,3 +4,5 @@ usr/share/vulkan/implicit_layer.d/MangoH
 usr/share/doc/mangohud/MangoHud.conf.example
 usr/bin/mangohud
 usr/share/man/man1/mangohud.1
+usr/share/metainfo/io.github.flightlessmango.mangohud.metainfo.xml
+usr/share/icons/hicolor/scalable/apps/io.github.flightlessmango.mangohud.svg
diff -pruN 0.6.7.1-1/debian/patches/0001_fix-json-dep.patch 0.6.8-1/debian/patches/0001_fix-json-dep.patch
--- 0.6.7.1-1/debian/patches/0001_fix-json-dep.patch	2022-07-05 09:50:00.000000000 +0000
+++ 0.6.8-1/debian/patches/0001_fix-json-dep.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,16 +0,0 @@
-Description: fix wrong meson dependency usge
-Author: Stephan Lachnit <stephanlachnit@debian.org>
-Forwarded: https://github.com/flightlessmango/MangoHud/pull/797
-
---- a/meson.build
-+++ b/meson.build
-@@ -273,8 +273,7 @@
-
- if get_option('mangoapp') or get_option('mangoapp_layer')
-   glfw3_dep = dependency('glfw3')
--  json_sp = subproject('nlohmann_json')
--  json_dep = json_sp.get_variable('nlohmann_json_dep')
-+  json_dep = dependency('nlohmann_json')
- endif
-
- subdir('src')
diff -pruN 0.6.7.1-1/debian/patches/0002_fix-libmangoapp-path.patch 0.6.8-1/debian/patches/0002_fix-libmangoapp-path.patch
--- 0.6.7.1-1/debian/patches/0002_fix-libmangoapp-path.patch	2022-07-05 09:50:00.000000000 +0000
+++ 0.6.8-1/debian/patches/0002_fix-libmangoapp-path.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-Description: fix missing install dir
-Author: Stephan Lachnit <stephanlachnit@debian.org>
-Forwarded: https://github.com/flightlessmango/MangoHud/pull/796
-
---- a/src/meson.build
-+++ b/src/meson.build
-@@ -282,6 +282,7 @@
-     gnu_symbol_visibility : 'hidden',
-     include_directories : [inc_common],
-     link_args : link_args,
-+    install_dir : libdir_mangohud,
-     install : true
-   )
- endif
diff -pruN 0.6.7.1-1/debian/patches/series 0.6.8-1/debian/patches/series
--- 0.6.7.1-1/debian/patches/series	2022-07-05 09:47:54.000000000 +0000
+++ 0.6.8-1/debian/patches/series	2022-08-01 08:21:07.000000000 +0000
@@ -1,3 +1 @@
-0001_fix-json-dep.patch
-0002_fix-libmangoapp-path.patch
 Build-mangoapp-and-mangohudctl-for-any-CPU-architecture.patch
diff -pruN 0.6.7.1-1/debian/salsa-ci.yml 0.6.8-1/debian/salsa-ci.yml
--- 0.6.7.1-1/debian/salsa-ci.yml	2022-07-05 09:47:54.000000000 +0000
+++ 0.6.8-1/debian/salsa-ci.yml	2022-08-01 08:22:57.000000000 +0000
@@ -1,4 +1,3 @@
 ---
 include:
-  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
-  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
+  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
diff -pruN 0.6.7.1-1/meson.build 0.6.8-1/meson.build
--- 0.6.7.1-1/meson.build	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/meson.build	2022-08-01 01:27:11.000000000 +0000
@@ -1,8 +1,8 @@
 project('MangoHud',
   ['c', 'cpp'],
-  version : 'v0.6.7',
+  version : 'v0.6.8',
   license : 'MIT',
-  meson_version: '>=0.54.0',
+  meson_version: '>=0.60.0',
   default_options : ['buildtype=release', 'c_std=c99', 'cpp_std=c++14', 'warning_level=2']
 )
 
@@ -276,9 +276,11 @@ endif
 
 if get_option('mangoapp') or get_option('mangoapp_layer')
   glfw3_dep = dependency('glfw3')
-  json_sp = subproject('nlohmann_json')
-  json_dep = json_sp.get_variable('nlohmann_json_dep')
+  json_dep = dependency('nlohmann_json')
 endif
 
 subdir('src')
-subdir('data')
+
+if get_option('include_doc')
+  subdir('data')
+endif
diff -pruN 0.6.7.1-1/meson_options.txt 0.6.8-1/meson_options.txt
--- 0.6.7.1-1/meson_options.txt	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/meson_options.txt	2022-08-01 01:27:11.000000000 +0000
@@ -6,7 +6,7 @@ option('append_libdir_mangohud', type :
 option('ld_libdir_prefix', type : 'boolean', value : false, description: 'Set ld libdir to "$prefix/lib/mangohud/\$LIB"')
 option('ld_libdir_abs', type : 'boolean', value : false, description: 'Use absolute path in LD_PRELOAD')
 option('prepend_libdir_vk', type : 'boolean', value : true, description: 'Prepend libdir to library path in vulkan manifest')
-option('include_doc', type : 'boolean', value : true, description: 'Include the example config')
+option('include_doc', type : 'boolean', value : true, description: 'Include the example config, man pages, appstream files etc.')
 option('with_nvml', type : 'combo', value : 'enabled', choices: ['enabled', 'system', 'disabled'], description: 'Enable NVML support')
 option('with_xnvctrl', type : 'feature', value : 'enabled', description: 'Enable XNVCtrl support')
 option('with_x11', type : 'feature', value : 'enabled')
@@ -16,4 +16,5 @@ option('with_dlsym', type : 'feature', v
 option('loglevel', type: 'combo', choices : ['trace', 'debug', 'info', 'warn', 'err', 'critical', 'off'], value : 'info', description: 'Max log level in non-debug build')
 option('mangoapp', type: 'boolean', value : 'false')
 option('mangohudctl', type: 'boolean', value : 'false')
-option('mangoapp_layer', type: 'boolean', value : 'false')
\ No newline at end of file
+option('mangoapp_layer', type: 'boolean', value : 'false')
+option('tests', type: 'feature', value: 'auto', description: 'Run tests')
diff -pruN 0.6.7.1-1/README.md 0.6.8-1/README.md
--- 0.6.7.1-1/README.md	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/README.md	2022-08-01 01:27:11.000000000 +0000
@@ -353,7 +353,7 @@ Parameters that are enabled by default h
 | `battery`                          | Display current battery percent and energy consumption                                |
 | `battery_icon`                     | Display battery icon instead of percent                                               |
 | `battery_color`                    | Change the BATT text color                                                            |
-| `fps_only`                         | Show FPS without the engine name e.g. DXVK/VULAKAN etc.                               |
+| `fps_only`                         | Show FPS only. ***Not meant to be used with other display params***                   |
 | `gamepad_battery`                  | Display battey of wireless gamepads (xone,xpadneo,ds4)                                |
 | `gamepad_battery_icon`             | Display gamepad battery percent with icon. *enabled by default                        |
 Example: `MANGOHUD_CONFIG=cpu_temp,gpu_temp,position=top-right,height=500,font_size=32`
diff -pruN 0.6.7.1-1/src/amdgpu.cpp 0.6.8-1/src/amdgpu.cpp
--- 0.6.7.1-1/src/amdgpu.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/amdgpu.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -44,10 +44,14 @@ std::mutex amdgpu_common_metrics_m;
 bool amdgpu_check_metrics(const std::string& path)
 {
     metrics_table_header header {};
-    std::ifstream in(path, std::ios_base::binary);
-    if (!in.read((char*)&header, sizeof(header)))
+	FILE *f;
+	f = fopen(path.c_str(), "rb");
+	if (!f)
+		return false;
+
+    if (fread(&header, sizeof(header), 1, f) == 0)
     {
-        SPDLOG_DEBUG("Failed to read '{}': {}", path, in.eof() ? "End of file" : strerror(errno));
+        SPDLOG_DEBUG("Failed to read the metrics header of '{}'", path);
         return false;
     }
 
@@ -71,67 +75,69 @@ bool amdgpu_check_metrics(const std::str
 
 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
 void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) {
-	// Set all the fields to 0 by default
-	memset(metrics, 0, sizeof(struct amdgpu_common_metrics));
-
-	if (!metrics_path.empty()){
-		struct metrics_table_header header;
-		std::ifstream in(metrics_path, std::ios_base::in | std::ios_base::binary);
-		in.read((char*)&header, sizeof(header));
-		int64_t indep_throttle_status = 0;
-		if (header.format_revision == 1) {
-			// Desktop GPUs
-			cpuStats.cpu_type = "GPU";
-			struct gpu_metrics_v1_3 amdgpu_metrics;
-			in.clear();
-			in.seekg(0);
-			in.read((char*)&amdgpu_metrics, sizeof(amdgpu_metrics));
-
-			metrics->gpu_load_percent = amdgpu_metrics.average_gfx_activity;
-
-			metrics->average_gfx_power_w = amdgpu_metrics.average_socket_power;
-
-			metrics->current_gfxclk_mhz = amdgpu_metrics.average_gfxclk_frequency;
-			metrics->current_uclk_mhz = amdgpu_metrics.current_uclk;
-
-			metrics->gpu_temp_c = amdgpu_metrics.temperature_edge;
-			indep_throttle_status = amdgpu_metrics.indep_throttle_status;
-		} else if (header.format_revision == 2) {
-			// APUs
-			cpuStats.cpu_type = "APU";
-			struct gpu_metrics_v2_2 amdgpu_metrics;
-			in.clear();
-			in.seekg(0);
-			in.read((char*)&amdgpu_metrics, sizeof(amdgpu_metrics));
-
-			metrics->gpu_load_percent = amdgpu_metrics.average_gfx_activity;
-
-			metrics->average_gfx_power_w = amdgpu_metrics.average_gfx_power / 1000.f;
-			metrics->average_cpu_power_w = amdgpu_metrics.average_cpu_power / 1000.f;
-
-			metrics->current_gfxclk_mhz = amdgpu_metrics.current_gfxclk;
-			metrics->current_uclk_mhz = amdgpu_metrics.current_uclk;
-
-			metrics->soc_temp_c = amdgpu_metrics.temperature_soc / 100;
-			metrics->gpu_temp_c = amdgpu_metrics.temperature_gfx / 100;
-			int cpu_temp = 0;
-			for (unsigned i = 0; i < cpuStats.GetCPUData().size() / 2; i++)
-				cpu_temp = MAX(cpu_temp, amdgpu_metrics.temperature_core[i]);
-			metrics->apu_cpu_temp_c = cpu_temp / 100;
-			indep_throttle_status = amdgpu_metrics.indep_throttle_status;
-		}
+	FILE *f;
+	void *buf[MAX(sizeof(struct gpu_metrics_v1_3), sizeof(struct gpu_metrics_v2_2))];
+	struct metrics_table_header* header = (metrics_table_header*)buf;
+
+	f = fopen(metrics_path.c_str(), "rb");
+	if (!f)
+		return;
+
+	// Read the whole file
+	if (!fread(buf, sizeof(buf), 1, f) == 0) {
+		SPDLOG_DEBUG("Failed to read amdgpu metrics file '{}'", metrics_path.c_str());
+		fclose(f);
+		return;
+	}
+	fclose(f);
 
-		/* Throttling: See 
-		https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
-		for the offsets */ 
-		metrics->is_power_throttled = ((indep_throttle_status >> 0) & 0xFF) != 0;
-		metrics->is_current_throttled = ((indep_throttle_status >> 16) & 0xFF) != 0;
-		metrics->is_temp_throttled = ((indep_throttle_status >> 32) & 0xFFFF) != 0;
-		metrics->is_other_throttled = ((indep_throttle_status >> 56) & 0xFF) != 0;
+	int64_t indep_throttle_status = 0;
+	if (header->format_revision == 1) {
+		// Desktop GPUs
+		cpuStats.cpu_type = "GPU";
+		struct gpu_metrics_v1_3 *amdgpu_metrics = (struct gpu_metrics_v1_3 *) buf;
+		metrics->gpu_load_percent = amdgpu_metrics->average_gfx_activity;
+
+		metrics->average_gfx_power_w = amdgpu_metrics->average_socket_power;
+
+		metrics->current_gfxclk_mhz = amdgpu_metrics->average_gfxclk_frequency;
+		metrics->current_uclk_mhz = amdgpu_metrics->current_uclk;
+
+		metrics->gpu_temp_c = amdgpu_metrics->temperature_edge;
+		indep_throttle_status = amdgpu_metrics->indep_throttle_status;
+	} else if (header->format_revision == 2) {
+		// APUs
+		cpuStats.cpu_type = "APU";
+		struct gpu_metrics_v2_2 *amdgpu_metrics = (struct gpu_metrics_v2_2 *) buf;
+
+		metrics->gpu_load_percent = amdgpu_metrics->average_gfx_activity;
+
+		metrics->average_gfx_power_w = amdgpu_metrics->average_gfx_power / 1000.f;
+		metrics->average_cpu_power_w = amdgpu_metrics->average_cpu_power / 1000.f;
+
+		metrics->current_gfxclk_mhz = amdgpu_metrics->current_gfxclk;
+		metrics->current_uclk_mhz = amdgpu_metrics->current_uclk;
+
+		metrics->soc_temp_c = amdgpu_metrics->temperature_soc / 100;
+		metrics->gpu_temp_c = amdgpu_metrics->temperature_gfx / 100;
+		int cpu_temp = 0;
+		for (unsigned i = 0; i < cpuStats.GetCPUData().size() / 2; i++)
+			cpu_temp = MAX(cpu_temp, amdgpu_metrics->temperature_core[i]);
+		metrics->apu_cpu_temp_c = cpu_temp / 100;
+		indep_throttle_status = amdgpu_metrics->indep_throttle_status;
 	}
+
+	/* Throttling: See
+	https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
+	for the offsets */
+	metrics->is_power_throttled = ((indep_throttle_status >> 0) & 0xFF) != 0;
+	metrics->is_current_throttled = ((indep_throttle_status >> 16) & 0xFF) != 0;
+	metrics->is_temp_throttled = ((indep_throttle_status >> 32) & 0xFFFF) != 0;
+	metrics->is_other_throttled = ((indep_throttle_status >> 56) & 0xFF) != 0;
 }
 
 #define UPDATE_METRIC_AVERAGE(FIELD) do { int value_sum = 0; for (size_t s=0; s < METRICS_SAMPLE_COUNT; s++) { value_sum += metrics_buffer[s].FIELD; } amdgpu_common_metrics.FIELD = value_sum / METRICS_SAMPLE_COUNT; } while(0)
+#define UPDATE_METRIC_AVERAGE_FLOAT(FIELD) do { float value_sum = 0; for (size_t s=0; s < METRICS_SAMPLE_COUNT; s++) { value_sum += metrics_buffer[s].FIELD; } amdgpu_common_metrics.FIELD = value_sum / METRICS_SAMPLE_COUNT; } while(0)
 #define UPDATE_METRIC_MAX(FIELD) do { int cur_max = metrics_buffer[0].FIELD; for (size_t s=1; s < METRICS_SAMPLE_COUNT; s++) { cur_max = MAX(cur_max, metrics_buffer[s].FIELD); }; amdgpu_common_metrics.FIELD = cur_max; } while(0)
 #define UPDATE_METRIC_LAST(FIELD) do { amdgpu_common_metrics.FIELD = metrics_buffer[METRICS_SAMPLE_COUNT - 1].FIELD; } while(0)
 
@@ -145,6 +151,9 @@ void amdgpu_metrics_polling_thread() {
 		gpu_load_needs_dividing = true;
 		amdgpu_common_metrics.gpu_load_percent /= 100;
 	}
+	
+	// Set all the fields to 0 by default. Only done once as we're just replacing previous values after
+	memset(metrics_buffer, 0, sizeof(metrics_buffer));
 
 	while (1) {
 		// Get all the samples
@@ -163,8 +172,8 @@ void amdgpu_metrics_polling_thread() {
 		// Copy the results from the different metrics to amdgpu_common_metrics
 		amdgpu_common_metrics_m.lock();
 		UPDATE_METRIC_AVERAGE(gpu_load_percent);
-		UPDATE_METRIC_AVERAGE(average_gfx_power_w);
-		UPDATE_METRIC_AVERAGE(average_cpu_power_w);
+		UPDATE_METRIC_AVERAGE_FLOAT(average_gfx_power_w);
+		UPDATE_METRIC_AVERAGE_FLOAT(average_cpu_power_w);
 
 		UPDATE_METRIC_AVERAGE(current_gfxclk_mhz);
 		UPDATE_METRIC_AVERAGE(current_uclk_mhz);
@@ -191,7 +200,6 @@ void amdgpu_get_metrics(){
 	gpu_info.load = amdgpu_common_metrics.gpu_load_percent;
 
 	gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w;
-
 	gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz;
 	gpu_info.MemClock = amdgpu_common_metrics.current_uclk_mhz;
 
diff -pruN 0.6.7.1-1/src/app/layer.cpp 0.6.8-1/src/app/layer.cpp
--- 0.6.7.1-1/src/app/layer.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/app/layer.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -1,14 +1,18 @@
 #include <mutex>
 #include <list>
+#include <fstream>
 #include <unordered_map>
 #include <sys/stat.h>
 #include <unistd.h>
-#include "overlay.h"
 #include <inttypes.h>
 #include "mesa/util/macros.h"
+#include "vk_enum_to_str.h"
+#include <vulkan/vk_layer.h>
 #include <vulkan/vk_util.h>
 #include "nlohmann/json.hpp"
+#include "engine_types.h"
 
+using namespace std;
 using json = nlohmann::json;
 
 // single global lock, for simplicity
@@ -16,6 +20,14 @@ std::mutex global_lock;
 typedef std::lock_guard<std::mutex> scoped_lock;
 std::unordered_map<uint64_t, void *> vk_object_to_data;
 
+/* Mapped from VkInstace/VkPhysicalDevice */
+struct instance_data {
+   struct vk_instance_dispatch_table vtable;
+   VkInstance instance;
+   string engineName, engineVersion;
+   enum EngineTypes engine;
+};
+
 #define HKEY(obj) ((uint64_t)(obj))
 #define FIND(type, obj) (reinterpret_cast<type *>(find_object_data(HKEY(obj))))
 
@@ -53,8 +65,6 @@ static struct instance_data *new_instanc
 {
    struct instance_data *data = new instance_data();
    data->instance = instance;
-   data->params = {};
-   data->params.control = -1;
    map_object(HKEY(data->instance), data);
    return data;
 }
@@ -147,7 +157,7 @@ static VkResult overlay_CreateInstance(
     struct stat info;
     string path = "/tmp/mangoapp/";
     string command = "mkdir -p " + path;
-    string json_path = path + to_string(getpid()) + ".json"; 
+    string json_path = path + to_string(getpid()) + ".json";
     if( stat(path.c_str(), &info ) != 0 )
         system(command.c_str());
     json j;
diff -pruN 0.6.7.1-1/src/app/layer.json.in 0.6.8-1/src/app/layer.json.in
--- 0.6.7.1-1/src/app/layer.json.in	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/app/layer.json.in	2022-08-01 01:27:11.000000000 +0000
@@ -3,7 +3,7 @@
     "layer" : {
       "name": "VK_LAYER_MANGOAPP_overlay",
       "type": "GLOBAL",
-      "api_version": "1.2.135",
+      "api_version": "1.3.0",
       "library_path": "@ld_libdir_mangohud@libMangoApp.so",
       "implementation_version": "1",
       "description": "Mangoapp Layer",
diff -pruN 0.6.7.1-1/src/app/main.cpp 0.6.8-1/src/app/main.cpp
--- 0.6.7.1-1/src/app/main.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/app/main.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -10,6 +10,7 @@
 #include <thread>
 #include <unistd.h>
 #include "../overlay.h"
+#include "notify.h"
 #include "mangoapp.h"
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
@@ -20,6 +21,7 @@
 
 #include "nlohmann/json.hpp"
 using json = nlohmann::json;
+using namespace std;
 
 static void glfw_error_callback(int error, const char* description)
 {
@@ -27,7 +29,7 @@ static void glfw_error_callback(int erro
 }
 
 swapchain_stats sw_stats {};
-overlay_params *params;
+overlay_params params {};
 static ImVec2 window_size;
 static uint32_t vendorID;
 static std::string deviceName;
@@ -97,13 +99,13 @@ static void ctrl_thread(){
                     // Keep as-is
                     break;
                 case 1:
-                    params->no_display = 1;
+                    params.no_display = 1;
                     break;
                 case 2:
-                    params->no_display = 0;
+                    params.no_display = 0;
                     break;
                 case 3:
-                    params->no_display ? params->no_display = 0 : params->no_display = 1;
+                    params.no_display ? params.no_display = 0 : params.no_display = 1;
                     break;
             }
         }
@@ -134,7 +136,7 @@ static void msg_read_thread(){
     }
     int key = ftok("mangoapp", 65);
     msgid = msgget(key, 0666 | IPC_CREAT);
-    uint32_t previous_pid = 0;
+    // uint32_t previous_pid = 0;
     const struct mangoapp_msg_header *hdr = (const struct mangoapp_msg_header*) raw_msg;
     const struct mangoapp_msg_v1 *mangoapp_v1 = (const struct mangoapp_msg_v1*) raw_msg;
     while (1){
@@ -143,31 +145,31 @@ static void msg_read_thread(){
         size_t msg_size = msgrcv(msgid, (void *) raw_msg, sizeof(raw_msg), 1, 0) + sizeof(long);
         if (hdr->version == 1){
             if (msg_size > offsetof(struct mangoapp_msg_v1, visible_frametime_ns)){
-                update_hud_info_with_frametime(sw_stats, *params, vendorID, mangoapp_v1->visible_frametime_ns);
+                update_hud_info_with_frametime(sw_stats, params, vendorID, mangoapp_v1->visible_frametime_ns);
                 if (msg_size > offsetof(mangoapp_msg_v1, fsrUpscale)){
                     g_fsrUpscale = mangoapp_v1->fsrUpscale;
-                    if (params->fsr_steam_sharpness < 0)
+                    if (params.fsr_steam_sharpness < 0)
                         g_fsrSharpness = mangoapp_v1->fsrSharpness;
                     else
-                        g_fsrSharpness = params->fsr_steam_sharpness - mangoapp_v1->fsrSharpness;
+                        g_fsrSharpness = params.fsr_steam_sharpness - mangoapp_v1->fsrSharpness;
                 }
                 if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam]){
                     steam_focused = get_prop("GAMESCOPE_FOCUSED_APP_GFX") == 769;
                 } else {
                     steam_focused = false;
                 }
-                if (!steam_focused && mangoapp_v1->pid != previous_pid){
-                    string path = "/tmp/mangoapp/" + to_string(mangoapp_v1->pid) + ".json";
-                    ifstream i(path);
-                    if (i.fail()){
-                        sw_stats.engine = EngineTypes::GAMESCOPE;
-                    } else {
-                        json j;
-                        i >> j;
-                        sw_stats.engine = static_cast<EngineTypes> (j["engine"]);
-                    }
-                    previous_pid = mangoapp_v1->pid;
-                }
+                // if (!steam_focused && mangoapp_v1->pid != previous_pid){
+                //     string path = "/tmp/mangoapp/" + to_string(mangoapp_v1->pid) + ".json";
+                //     ifstream i(path);
+                //     if (i.fail()){
+                //         sw_stats.engine = EngineTypes::GAMESCOPE;
+                //     } else {
+                //         json j;
+                //         i >> j;
+                //         sw_stats.engine = static_cast<EngineTypes> (j["engine"]);
+                //     }
+                //     previous_pid = mangoapp_v1->pid;
+                // }
                 if (msg_size > offsetof(mangoapp_msg_v1, latency_ns))
                     gamescope_frametime(mangoapp_v1->app_frametime_ns, mangoapp_v1->latency_ns);
 
@@ -195,7 +197,7 @@ static GLFWwindow* init(const char* glsl
         // Set atom for gamescope to render as an overlay.
         Atom overlay_atom = XInternAtom (x11_display, GamescopeOverlayProperty, False);
         uint32_t value = 1;
-        XChangeProperty(x11_display, x11_window, overlay_atom, XA_ATOM, 32, PropertyNewValue, (unsigned char *)&value, 1);
+        XChangeProperty(x11_display, x11_window, overlay_atom, XA_CARDINAL, 32, PropertyNewValue, (unsigned char *)&value, 1);
     }
 
     glfwMakeContextCurrent(window);
@@ -221,10 +223,13 @@ static bool render(GLFWwindow* window) {
     ImGui_ImplGlfw_NewFrame();
     ImGui_ImplOpenGL3_NewFrame();
     ImGui::NewFrame();
-    position_layer(sw_stats, *params, window_size);
-    render_imgui(sw_stats, *params, window_size, true);
-    glfwSetWindowSize(window, window_size.x + 45.f, window_size.y + 325.f);
-    ImGui::PopStyleVar(3);
+    overlay_new_frame(params);
+    position_layer(sw_stats, params, window_size);
+    render_imgui(sw_stats, params, window_size, true);
+    overlay_end_frame();
+    if (!params.enabled[OVERLAY_PARAM_ENABLED_fps_only])
+        glfwSetWindowSize(window, window_size.x + 45.f, window_size.y + 325.f);
+
     ImGui::EndFrame();
     return last_window_size.x != window_size.x || last_window_size.y != window_size.y;
 }
@@ -245,6 +250,10 @@ int main(int, char**)
 
     // Create window with graphics context
     GLFWwindow* window = init(glsl_version);
+
+    Display *x11_display = glfwGetX11Display();
+    Window x11_window = glfwGetX11Window(window);
+    Atom overlay_atom = XInternAtom (x11_display, GamescopeOverlayProperty, False);
     // Initialize OpenGL loader
 
     bool err = glewInit() != GLEW_OK;
@@ -256,18 +265,15 @@ int main(int, char**)
     }
 
     // Setup Platform/Renderer backends
-    struct device_data *device_data = new struct device_data();
-    device_data->instance = new struct instance_data();
-    device_data->instance->params = {};
-    params = &device_data->instance->params;
-    parse_overlay_config(params, getenv("MANGOHUD_CONFIG"));
-    create_fonts(*params, sw_stats.font1, sw_stats.font_text);
-    HUDElements.convert_colors(*params);
-    init_cpu_stats(*params);
-    notifier.params = params;
+    int control_client = -1;
+    parse_overlay_config(&params, getenv("MANGOHUD_CONFIG"));
+    create_fonts(nullptr, params, sw_stats.font1, sw_stats.font_text);
+    HUDElements.convert_colors(params);
+    init_cpu_stats(params);
+    notifier.params = &params;
     start_notifier(notifier);
-    window_size = ImVec2(params->width, params->height);
-        deviceName = (char*)glGetString(GL_RENDERER);
+    window_size = ImVec2(params.width, params.height);
+    deviceName = (char*)glGetString(GL_RENDERER);
     sw_stats.deviceName = deviceName;
     if (deviceName.find("Radeon") != std::string::npos
     || deviceName.find("AMD") != std::string::npos){
@@ -275,7 +281,7 @@ int main(int, char**)
     } else {
         vendorID = 0x10de;
     }
-    init_gpu_stats(vendorID, 0, *params);
+    init_gpu_stats(vendorID, 0, params);
     init_system_info();
     sw_stats.engine = EngineTypes::GAMESCOPE;
     std::thread(msg_read_thread).detach();
@@ -283,18 +289,21 @@ int main(int, char**)
     if(!logger) logger = std::make_unique<Logger>(HUDElements.params);
     // Main loop
     while (!glfwWindowShouldClose(window)){
-        if (!params->no_display){
+        if (!params.no_display){
             if (mangoapp_paused){
                 glfwRestoreWindow(window);
+                uint32_t value = 1;
+                XChangeProperty(x11_display, x11_window, overlay_atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&value, 1);
+                XSync(x11_display, 0);
                 mangoapp_paused = false;
             }
             {
                 std::unique_lock<std::mutex> lk(mangoapp_m);
-                mangoapp_cv.wait(lk, []{return new_frame || params->no_display;});
+                mangoapp_cv.wait(lk, []{return new_frame || params.no_display;});
                 new_frame = false;
             }
 
-            check_keybinds(*params, vendorID);
+            check_keybinds(params, vendorID);
             // Start the Dear ImGui frame
             {
                 if (render(window)) {
@@ -305,9 +314,9 @@ int main(int, char**)
                     render(window);
                 }
 
-                if (params->control >= 0) {
-                    control_client_check(device_data);
-                    process_control_socket(device_data->instance);
+                if (params.control >= 0) {
+                    control_client_check(params.control, control_client, deviceName);
+                    process_control_socket(control_client, params);
                 }
             }
             // Rendering
@@ -322,9 +331,12 @@ int main(int, char**)
             glfwSwapBuffers(window);
         } else if (!mangoapp_paused) {
             glfwIconifyWindow(window);
+            uint32_t value = 0;
+            XChangeProperty(x11_display, x11_window, overlay_atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&value, 1);
+            XSync(x11_display, 0);
             mangoapp_paused = true;
             std::unique_lock<std::mutex> lk(mangoapp_m);
-            mangoapp_cv.wait(lk, []{return !params->no_display;});
+            mangoapp_cv.wait(lk, []{return !params.no_display;});
         }
     }
 
diff -pruN 0.6.7.1-1/src/blacklist.cpp 0.6.8-1/src/blacklist.cpp
--- 0.6.7.1-1/src/blacklist.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/blacklist.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -1,6 +1,7 @@
 #include <vector>
 #include <string>
 #include <algorithm>
+#include <spdlog/spdlog.h>
 
 #include "blacklist.h"
 #include "string_utils.h"
@@ -35,6 +36,8 @@ static  std::vector<std::string> blackli
     "SocialClubHelper.exe",
     "EADesktop.exe",
     "EALauncher.exe",
+    "StarCitizen_Launcher.exe",
+    "InsurgencyEAC.exe",
 };
 
 
@@ -43,7 +46,7 @@ static bool check_blacklisted() {
     bool blacklisted = std::find(blacklist.begin(), blacklist.end(), proc_name) != blacklist.end();
 
     if(blacklisted) {
-        fprintf(stderr, "INFO: process %s is blacklisted in MangoHud\n", proc_name.c_str());
+        SPDLOG_INFO("process '{}' is blacklisted in MangoHud", proc_name);
     }
 
     return blacklisted;
diff -pruN 0.6.7.1-1/src/config.cpp 0.6.8-1/src/config.cpp
--- 0.6.7.1-1/src/config.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/config.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -10,6 +10,7 @@
 #include "file_utils.h"
 #include "string_utils.h"
 #include "hud_elements.h"
+#include "blacklist.h"
 
 static void parseConfigLine(std::string line, std::unordered_map<std::string, std::string>& options) {
     std::string param, value;
@@ -76,6 +77,11 @@ static void enumerate_config_files(std::
 
     paths.push_back(config_dir + mangohud_dir + "MangoHud.conf");
 
+    if (is_blacklisted()) {
+        // Don't bother looking for conf file
+        return;
+    }
+
     if (!program_name.empty()) {
         paths.push_back(config_dir + mangohud_dir + program_name + ".conf");
     }
diff -pruN 0.6.7.1-1/src/control.cpp 0.6.8-1/src/control.cpp
--- 0.6.7.1-1/src/control.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/control.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -1,35 +1,50 @@
 #include <assert.h>
 #include <cerrno>
 #include <cstring>
+#include <sys/socket.h>
 #include "mesa/util/os_socket.h"
 #include "overlay.h"
+#include "version.h"
 #ifdef MANGOAPP
 #include "app/mangoapp.h"
 #endif
 
+int global_control_client;
+
 using namespace std;
-static void parse_command(struct instance_data *instance_data,
+static void parse_command(overlay_params &params,
                           const char *cmd, unsigned cmdlen,
                           const char *param, unsigned paramlen)
 {
-    if (!strncmp(cmd, "hud", cmdlen)) {
+   if (!strncmp(cmd, "hud", cmdlen)) {
 #ifdef MANGOAPP
       {
          std::lock_guard<std::mutex> lk(mangoapp_m);
-         instance_data->params.no_display = !instance_data->params.no_display;
+         params.no_display = !params.no_display;
       }
       mangoapp_cv.notify_one();
 #else
-      instance_data->params.no_display = !instance_data->params.no_display;
+      params.no_display = !params.no_display;
 #endif
-    }
-    if (!strncmp(cmd, "logging", cmdlen)) {
-      if (logger->is_active())
-         logger->stop_logging();
+   } else if (!strncmp(cmd, "logging", cmdlen)) {
+      if (param && param[0])
+      {
+         int value = atoi(param);
+         if (!value && logger->is_active())
+            logger->stop_logging();
+         else if (value > 0 && !logger->is_active())
+            logger->start_logging();
+      }
       else
-         logger->start_logging();
-
-    }
+      {
+         if (logger->is_active())
+            logger->stop_logging();
+         else
+            logger->start_logging();
+      }
+   } else if (!strncmp(cmd, "fcat", cmdlen)) {
+      params.enabled[OVERLAY_PARAM_ENABLED_fcat] = !params.enabled[OVERLAY_PARAM_ENABLED_fcat];
+   }
 }
 
 #define BUFSIZE 4096
@@ -43,7 +58,7 @@ static void parse_command(struct instanc
  *
  *    :cmd=param;
  */
-static void process_char(struct instance_data *instance_data, char c)
+static void process_char(const int control_client, overlay_params &params, char c)
 {
    static char cmd[BUFSIZE];
    static char param[BUFSIZE];
@@ -65,7 +80,7 @@ static void process_char(struct instance
          break;
       cmd[cmdpos++] = '\0';
       param[parampos++] = '\0';
-      parse_command(instance_data, cmd, cmdpos, param, parampos);
+      parse_command(params, cmd, cmdpos, param, parampos);
       reading_cmd = false;
       reading_param = false;
       break;
@@ -99,7 +114,7 @@ static void process_char(struct instance
    }
 }
 
-static void control_send(struct instance_data *instance_data,
+void control_send(int control_client,
                          const char *cmd, unsigned cmdlen,
                          const char *param, unsigned paramlen)
 {
@@ -120,42 +135,39 @@ static void control_send(struct instance
       buffer[msglen++] = ';';
    }
 
-   os_socket_send(instance_data->control_client, buffer, msglen, 0);
+   os_socket_send(control_client, buffer, msglen, MSG_NOSIGNAL);
 }
 
-static void control_send_connection_string(struct device_data *device_data)
+static void control_send_connection_string(int control_client, const std::string& deviceName)
 {
-   struct instance_data *instance_data = device_data->instance;
-
-   const char *controlVersionCmd = "MesaOverlayControlVersion";
+   const char *controlVersionCmd = "MangoHudControlVersion";
    const char *controlVersionString = "1";
 
-   control_send(instance_data, controlVersionCmd, strlen(controlVersionCmd),
+   control_send(control_client, controlVersionCmd, strlen(controlVersionCmd),
                 controlVersionString, strlen(controlVersionString));
 
    const char *deviceCmd = "DeviceName";
-   const char *deviceName = device_data->properties.deviceName;
 
-   control_send(instance_data, deviceCmd, strlen(deviceCmd),
-                deviceName, strlen(deviceName));
+   control_send(control_client, deviceCmd, strlen(deviceCmd),
+                deviceName.c_str(), deviceName.size());
 
-   const char *mesaVersionCmd = "MesaVersion";
-   const char *mesaVersionString = "Mesa";
+   const char *versionCmd = "MangoHudVersion";
+   const char *versionString = "MangoHud " MANGOHUD_VERSION;
 
-   control_send(instance_data, mesaVersionCmd, strlen(mesaVersionCmd),
-                mesaVersionString, strlen(mesaVersionString));
+   control_send(control_client, versionCmd, strlen(versionCmd),
+                versionString, strlen(versionString));
 
 }
 
-void control_client_check(struct device_data *device_data)
+void control_client_check(int control, int& control_client, const std::string& deviceName)
 {
-   struct instance_data *instance_data = device_data->instance;
-
    /* Already connected, just return. */
-   if (instance_data->control_client >= 0)
+   if (control_client >= 0){
+      global_control_client = control_client;
       return;
+   }
 
-   int socket = os_socket_accept(instance_data->params.control);
+   int socket = os_socket_accept(control);
    if (socket == -1) {
       if (errno != EAGAIN && errno != EWOULDBLOCK && errno != ECONNABORTED)
          fprintf(stderr, "ERROR on socket: %s\n", strerror(errno));
@@ -164,25 +176,24 @@ void control_client_check(struct device_
 
    if (socket >= 0) {
       os_socket_block(socket, false);
-      instance_data->control_client = socket;
-      control_send_connection_string(device_data);
+      control_client = socket;
+      control_send_connection_string(control_client, deviceName);
    }
 }
 
-static void control_client_disconnected(struct instance_data *instance_data)
+static void control_client_disconnected(int& control_client)
 {
-   os_socket_close(instance_data->control_client);
-   instance_data->control_client = -1;
+   os_socket_close(control_client);
+   control_client = -1;
 }
 
-void process_control_socket(struct instance_data *instance_data)
+void process_control_socket(int& control_client, overlay_params &params)
 {
-   const int client = instance_data->control_client;
-   if (client >= 0) {
+   if (control_client >= 0) {
       char buf[BUFSIZE];
 
       while (true) {
-         ssize_t n = os_socket_recv(client, buf, BUFSIZE, 0);
+         ssize_t n = os_socket_recv(control_client, buf, BUFSIZE, 0);
 
          if (n == -1) {
             if (errno == EAGAIN || errno == EWOULDBLOCK) {
@@ -193,14 +204,14 @@ void process_control_socket(struct insta
             if (errno != ECONNRESET)
                fprintf(stderr, "ERROR on connection: %s\n", strerror(errno));
 
-            control_client_disconnected(instance_data);
+            control_client_disconnected(control_client);
          } else if (n == 0) {
             /* recv() returns 0 when the client disconnects */
-            control_client_disconnected(instance_data);
+            control_client_disconnected(control_client);
          }
 
          for (ssize_t i = 0; i < n; i++) {
-            process_char(instance_data, buf[i]);
+            process_char(control_client, params, buf[i]);
          }
 
          /* If we try to read BUFSIZE and receive BUFSIZE bytes from the
diff -pruN 0.6.7.1-1/src/engine_types.h 0.6.8-1/src/engine_types.h
--- 0.6.7.1-1/src/engine_types.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/src/engine_types.h	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,21 @@
+#pragma once
+enum EngineTypes
+{
+   UNKNOWN,
+
+   OPENGL,
+   VULKAN,
+
+   DXVK,
+   VKD3D,
+   DAMAVAND,
+   ZINK,
+
+   WINED3D,
+   FERAL3D,
+   TOGL,
+
+   GAMESCOPE
+};
+
+extern const char* engines[];
diff -pruN 0.6.7.1-1/src/fcat.h 0.6.8-1/src/fcat.h
--- 0.6.7.1-1/src/fcat.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/src/fcat.h	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,63 @@
+#pragma once
+#ifndef MANGOHUD_FCAT_H
+#define MANGOHUD_FCAT_H
+
+#include <iostream>
+#include <vector>
+#include <fstream>
+#include <chrono>
+#include <thread>
+#include <condition_variable>
+#include <array>
+
+#include "timing.hpp"
+
+#include "overlay_params.h"
+#include "overlay.h"
+
+struct fcatoverlay{
+  const struct overlay_params* params = nullptr;
+  const std::array<const ImColor,16> sequence={{{255, 255, 255},{0, 255, 0},{0, 0, 255},{255, 0, 0},{0, 128, 128},{0, 0, 128},{0, 128, 0},{0, 255, 255},{128, 0, 0},{192, 192, 192},{128, 0, 128},{128, 128, 0},{128, 128, 128},{255, 0, 255},{255, 255, 0},{255, 128, 0}}};
+  void update(const struct overlay_params* params_){
+    params=params_;
+  };
+  ImColor get_next_color (const swapchain_stats& sw_stats){
+    size_t currentColor = sw_stats.n_frames % 16;// should probably be sequence.size(); but this doesn't matter as all FCAT analysis tools use this exact 16 colour sequence.
+    ImColor output = sequence[currentColor];
+    return output;
+  };
+  std::array<ImVec2,3> get_overlay_corners()
+  {
+    unsigned short screen_edge=params->fcat_screen_edge;
+    auto window_size = ImVec2(params->fcat_overlay_width,ImGui::GetIO().DisplaySize.y);
+    auto p_min = ImVec2(0.,0.);
+    auto p_max = ImVec2(window_size.x,ImGui::GetIO().DisplaySize.y);
+    //Switch the used screen edge, this enables capture from devices with any screen orientation.
+    //This goes counter-clockwise from the left edge (0)
+    switch (screen_edge)
+      {
+      default:
+      case 0:
+	break;
+      case 1:
+	window_size = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.x);
+	p_min = ImVec2(0,ImGui::GetIO().DisplaySize.y - window_size.y);
+	p_max = ImVec2(ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y);
+	break;
+      case 2:
+	window_size = ImVec2(window_size.x,ImGui::GetIO().DisplaySize.y);
+	p_min = ImVec2(ImGui::GetIO().DisplaySize.x-window_size.x,0);
+	p_max = ImVec2(ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y);
+	break;
+      case 3:
+	window_size = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.x);
+	p_min = ImVec2(0,0);
+	p_max = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.y);
+	break;
+         }
+    std::array<ImVec2,3> output={{p_min,p_max,window_size}};
+    return output;
+  };
+};
+
+#endif
diff -pruN 0.6.7.1-1/src/font.cpp 0.6.8-1/src/font.cpp
--- 0.6.7.1-1/src/font.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/font.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -3,10 +3,14 @@
 #include "font_default.h"
 #include "IconsForkAwesome.h"
 #include "forkawesome.h"
-void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font)
+
+void create_fonts(ImFontAtlas* font_atlas, const overlay_params& params, ImFont*& small_font, ImFont*& text_font)
 {
    auto& io = ImGui::GetIO();
-   io.Fonts->Clear();
+   if (!font_atlas)
+        font_atlas = io.Fonts;
+   font_atlas->Clear();
+
    ImGui::GetIO().FontGlobalScale = params.font_scale; // set here too so ImGui::CalcTextSize is correct
    float font_size = params.font_size;
    if (font_size < FLT_EPSILON)
@@ -31,21 +35,21 @@ void create_fonts(const overlay_params&
 
    ImVector<ImWchar> glyph_ranges;
    ImFontGlyphRangesBuilder builder;
-   builder.AddRanges(io.Fonts->GetGlyphRangesDefault());
+   builder.AddRanges(font_atlas->GetGlyphRangesDefault());
    if (params.font_glyph_ranges & FG_KOREAN)
-      builder.AddRanges(io.Fonts->GetGlyphRangesKorean());
+      builder.AddRanges(font_atlas->GetGlyphRangesKorean());
    if (params.font_glyph_ranges & FG_CHINESE_FULL)
-      builder.AddRanges(io.Fonts->GetGlyphRangesChineseFull());
+      builder.AddRanges(font_atlas->GetGlyphRangesChineseFull());
    if (params.font_glyph_ranges & FG_CHINESE_SIMPLIFIED)
-      builder.AddRanges(io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
+      builder.AddRanges(font_atlas->GetGlyphRangesChineseSimplifiedCommon());
    if (params.font_glyph_ranges & FG_JAPANESE)
-      builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Not exactly Shift JIS compatible?
+      builder.AddRanges(font_atlas->GetGlyphRangesJapanese()); // Not exactly Shift JIS compatible?
    if (params.font_glyph_ranges & FG_CYRILLIC)
-      builder.AddRanges(io.Fonts->GetGlyphRangesCyrillic());
+      builder.AddRanges(font_atlas->GetGlyphRangesCyrillic());
    if (params.font_glyph_ranges & FG_THAI)
-      builder.AddRanges(io.Fonts->GetGlyphRangesThai());
+      builder.AddRanges(font_atlas->GetGlyphRangesThai());
    if (params.font_glyph_ranges & FG_VIETNAMESE)
-      builder.AddRanges(io.Fonts->GetGlyphRangesVietnamese());
+      builder.AddRanges(font_atlas->GetGlyphRangesVietnamese());
    if (params.font_glyph_ranges & FG_LATIN_EXT_A) {
       constexpr ImWchar latin_ext_a[] { 0x0100, 0x017F, 0 };
       builder.AddRanges(latin_ext_a);
@@ -61,23 +65,23 @@ void create_fonts(const overlay_params&
 
    // ImGui takes ownership of the data, no need to free it
    if (!params.font_file.empty() && file_exists(params.font_file)) {
-      io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size, nullptr, same_font && same_size ? glyph_ranges.Data : default_range);
-      io.Fonts->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size, &config, icon_ranges);
+      font_atlas->AddFontFromFileTTF(params.font_file.c_str(), font_size, nullptr, same_font && same_size ? glyph_ranges.Data : default_range);
+      font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size, &config, icon_ranges);
       if (params.no_small_font)
-         small_font = io.Fonts->Fonts[0];
+         small_font = font_atlas->Fonts[0];
       else {
-         small_font = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f, nullptr, default_range);
-         io.Fonts->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size * 0.55f, &config, icon_ranges);
+         small_font = font_atlas->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f, nullptr, default_range);
+         font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size * 0.55f, &config, icon_ranges);
       }
    } else {
       const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
-      io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, nullptr, default_range);
-      io.Fonts->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size, &config, icon_ranges);
+      font_atlas->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, nullptr, default_range);
+      font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size, &config, icon_ranges);
       if (params.no_small_font)
-         small_font = io.Fonts->Fonts[0];
+         small_font = font_atlas->Fonts[0];
       else {
-         small_font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55f, nullptr, default_range);
-         io.Fonts->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size * 0.55f, &config, icon_ranges);
+         small_font = font_atlas->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55f, nullptr, default_range);
+         font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size * 0.55f, &config, icon_ranges);
       }
    }
 
@@ -86,9 +90,9 @@ void create_fonts(const overlay_params&
       font_file_text = params.font_file;
 
    if ((!same_font || !same_size) && file_exists(font_file_text))
-      text_font = io.Fonts->AddFontFromFileTTF(font_file_text.c_str(), font_size_text, nullptr, glyph_ranges.Data);
+      text_font = font_atlas->AddFontFromFileTTF(font_file_text.c_str(), font_size_text, nullptr, glyph_ranges.Data);
    else
-      text_font = io.Fonts->Fonts[0];
+      text_font = font_atlas->Fonts[0];
 
-   io.Fonts->Build();
+   font_atlas->Build();
 }
diff -pruN 0.6.7.1-1/src/gl/gl_hud.cpp 0.6.8-1/src/gl/gl_hud.cpp
--- 0.6.7.1-1/src/gl/gl_hud.cpp	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/src/gl/gl_hud.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,231 @@
+#include <cstdlib>
+#include <functional>
+#include <thread>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <memory>
+#include <unistd.h>
+#include <filesystem.h>
+#include <spdlog/spdlog.h>
+#include <imgui.h>
+#include "gl_hud.h"
+#include "file_utils.h"
+#include "notify.h"
+#include "blacklist.h"
+
+#ifdef HAVE_DBUS
+#include "dbus_info.h"
+#endif
+
+#include <glad/glad.h>
+
+namespace fs = ghc::filesystem;
+
+namespace MangoHud { namespace GL {
+
+struct GLVec
+{
+    GLint v[4];
+
+    GLint operator[] (size_t i)
+    {
+        return v[i];
+    }
+
+    bool operator== (const GLVec& r)
+    {
+        return v[0] == r.v[0]
+            && v[1] == r.v[1]
+            && v[2] == r.v[2]
+            && v[3] == r.v[3];
+    }
+
+    bool operator!= (const GLVec& r)
+    {
+        return !(*this == r);
+    }
+};
+
+struct state {
+    ImGuiContext *imgui_ctx = nullptr;
+};
+
+static GLVec last_vp {}, last_sb {};
+swapchain_stats sw_stats {};
+static state state;
+static uint32_t vendorID;
+static std::string deviceName;
+
+static notify_thread notifier;
+static bool cfg_inited = false;
+static ImVec2 window_size;
+static bool inited = false;
+overlay_params params {};
+
+// seems to quit by itself though
+static std::unique_ptr<notify_thread, std::function<void(notify_thread *)>>
+    stop_it(&notifier, [](notify_thread *n){ stop_notifier(*n); });
+
+void imgui_init()
+{
+    if (cfg_inited)
+        return;
+
+    init_spdlog();
+    parse_overlay_config(&params, getenv("MANGOHUD_CONFIG"));
+    _params = &params;
+
+   //check for blacklist item in the config file
+   for (auto& item : params.blacklist) {
+      add_blacklist(item);
+   }
+
+    if (sw_stats.engine != EngineTypes::ZINK){
+        sw_stats.engine = OPENGL;
+
+        fs::path path("/proc/self/map_files/");
+        for (auto& p : fs::directory_iterator(path)) {
+            auto file = p.path().string();
+            auto sym = read_symlink(file.c_str());
+            if (sym.find("wined3d") != std::string::npos) {
+                sw_stats.engine = WINED3D;
+                break;
+            } else if (sym.find("libtogl.so") != std::string::npos || sym.find("libtogl_client.so") != std::string::npos) {
+                sw_stats.engine = TOGL;
+                break;
+            }
+        }
+    }
+
+    is_blacklisted(true);
+    notifier.params = &params;
+    start_notifier(notifier);
+    window_size = ImVec2(params.width, params.height);
+    init_system_info();
+    cfg_inited = true;
+    init_cpu_stats(params);
+}
+
+//static
+void imgui_create(void *ctx)
+{
+    if (inited)
+        return;
+
+    if (!ctx)
+        return;
+
+    imgui_shutdown();
+    imgui_init();
+    inited = true;
+
+    gladLoadGL();
+
+    GetOpenGLVersion(sw_stats.version_gl.major,
+        sw_stats.version_gl.minor,
+        sw_stats.version_gl.is_gles);
+
+    deviceName = (char*)glGetString(GL_RENDERER);
+    SPDLOG_DEBUG("deviceName: {}", deviceName);
+    sw_stats.deviceName = deviceName;
+    if (deviceName.find("Radeon") != std::string::npos
+    || deviceName.find("AMD") != std::string::npos){
+        vendorID = 0x1002;
+    } else {
+        vendorID = 0x10de;
+    }
+    if (deviceName.find("zink") != std::string::npos)
+        sw_stats.engine = EngineTypes::ZINK;
+    init_gpu_stats(vendorID, 0, params);
+    sw_stats.gpuName = gpu = get_device_name(vendorID, deviceID);
+    SPDLOG_DEBUG("gpu: {}", gpu);
+    // Setup Dear ImGui context
+    IMGUI_CHECKVERSION();
+    ImGuiContext *saved_ctx = ImGui::GetCurrentContext();
+    state.imgui_ctx = ImGui::CreateContext();
+    ImGuiIO& io = ImGui::GetIO(); (void)io;
+    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
+    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
+
+    // Setup Dear ImGui style
+    ImGui::StyleColorsDark();
+    //ImGui::StyleColorsClassic();
+    HUDElements.convert_colors(false, params);
+
+    glGetIntegerv (GL_VIEWPORT, last_vp.v);
+    glGetIntegerv (GL_SCISSOR_BOX, last_sb.v);
+
+    ImGui::GetIO().IniFilename = NULL;
+    ImGui::GetIO().DisplaySize = ImVec2(last_vp[2], last_vp[3]);
+
+    ImGui_ImplOpenGL3_Init();
+
+    create_fonts(nullptr, params, sw_stats.font1, sw_stats.font_text);
+    sw_stats.font_params_hash = params.font_params_hash;
+
+    // Restore global context or ours might clash with apps that use Dear ImGui
+    ImGui::SetCurrentContext(saved_ctx);
+}
+
+void imgui_shutdown()
+{
+    if (state.imgui_ctx) {
+        ImGui::SetCurrentContext(state.imgui_ctx);
+        ImGui_ImplOpenGL3_Shutdown();
+        ImGui::DestroyContext(state.imgui_ctx);
+        state.imgui_ctx = nullptr;
+    }
+    inited = false;
+}
+
+void imgui_set_context(void *ctx)
+{
+    if (!ctx)
+        return;
+    imgui_create(ctx);
+}
+
+void imgui_render(unsigned int width, unsigned int height)
+{
+    if (!state.imgui_ctx)
+        return;
+
+    static int control_client = -1;
+    if (params.control >= 0) {
+        control_client_check(params.control, control_client, deviceName);
+        process_control_socket(control_client, params);
+    }
+
+    check_keybinds(params, vendorID);
+    update_hud_info(sw_stats, params, vendorID);
+
+    ImGuiContext *saved_ctx = ImGui::GetCurrentContext();
+    ImGui::SetCurrentContext(state.imgui_ctx);
+    ImGui::GetIO().DisplaySize = ImVec2(width, height);
+    if (HUDElements.colors.update)
+        HUDElements.convert_colors(params);
+
+    if (sw_stats.font_params_hash != params.font_params_hash)
+    {
+        sw_stats.font_params_hash = params.font_params_hash;
+        create_fonts(nullptr, params, sw_stats.font1, sw_stats.font_text);
+        ImGui_ImplOpenGL3_CreateFontsTexture();
+    }
+
+    ImGui_ImplOpenGL3_NewFrame();
+    ImGui::NewFrame();
+    {
+        std::lock_guard<std::mutex> lk(notifier.mutex);
+        overlay_new_frame(params);
+        position_layer(sw_stats, params, window_size);
+        render_imgui(sw_stats, params, window_size, false);
+        overlay_end_frame();
+    }
+
+    ImGui::Render();
+    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+    ImGui::SetCurrentContext(saved_ctx);
+}
+
+}} // namespaces
diff -pruN 0.6.7.1-1/src/gl/gl_hud.h 0.6.8-1/src/gl/gl_hud.h
--- 0.6.7.1-1/src/gl/gl_hud.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/src/gl/gl_hud.h	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,19 @@
+#pragma once
+#ifndef MANGOHUD_GL_IMGUI_HUD_H
+#define MANGOHUD_GL_IMGUI_HUD_H
+
+#include "overlay.h"
+#include "gl_renderer.h"
+
+namespace MangoHud { namespace GL {
+
+extern overlay_params params;
+void imgui_init();
+void imgui_create(void *ctx);
+void imgui_shutdown();
+void imgui_set_context(void *ctx);
+void imgui_render(unsigned int width, unsigned int height);
+
+}} // namespace
+
+#endif //MANGOHUD_GL_IMGUI_HUD_H
diff -pruN 0.6.7.1-1/src/gl/gl_renderer.cpp 0.6.8-1/src/gl/gl_renderer.cpp
--- 0.6.7.1-1/src/gl/gl_renderer.cpp	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/src/gl/gl_renderer.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,714 @@
+// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
+// - Desktop GL: 2.x 3.x 4.x
+// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
+// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
+
+// Implemented features:
+//  [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
+//  [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
+
+// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
+// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
+// https://github.com/ocornut/imgui
+
+// CHANGELOG
+// (minor and older changes stripped away, please see git history for details)
+//  2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
+//  2020-01-07: OpenGL: Added support for glbindings OpenGL loader.
+//  2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders.
+//  2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility.
+//  2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call.
+//  2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
+//  2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
+//  2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
+//  2019-03-15: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
+//  2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
+//  2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
+//  2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
+//  2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
+//  2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
+//  2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
+//  2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
+//  2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
+//  2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
+//  2018-07-10: OpenGL: Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to compile/link.
+//  2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 examples.
+//  2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
+//  2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the VAO state.
+//  2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't fail if the function is a NULL pointer.
+//  2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150".
+//  2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context.
+//  2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself.
+//  2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150.
+//  2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode.
+//  2017-05-01: OpenGL: Fixed save and restore of current blend func state.
+//  2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE.
+//  2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
+//  2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752)
+
+//----------------------------------------
+// OpenGL    GLSL      GLSL
+// version   version   string
+//----------------------------------------
+//  2.0       110       "#version 110"
+//  2.1       120       "#version 120"
+//  3.0       130       "#version 130"
+//  3.1       140       "#version 140"
+//  3.2       150       "#version 150"
+//  3.3       330       "#version 330 core"
+//  4.0       400       "#version 400 core"
+//  4.1       410       "#version 410 core"
+//  4.2       420       "#version 410 core"
+//  4.3       430       "#version 430 core"
+//  ES 2.0    100       "#version 100"      = WebGL 1.0
+//  ES 3.0    300       "#version 300 es"   = WebGL 2.0
+//----------------------------------------
+
+#include <spdlog/spdlog.h>
+#include <imgui.h>
+#include "gl_renderer.h"
+#include <stdio.h>
+#include <stdint.h>     // intptr_t
+#include <sstream>
+
+#include <spdlog/spdlog.h>
+#include <glad/glad.h>
+
+#include "overlay.h"
+
+namespace MangoHud { namespace GL {
+
+extern overlay_params params;
+
+// OpenGL Data
+static GLuint       g_GlVersion = 0;                // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries.
+static char         g_GlslVersionString[32] = "";   // Specified by user or detected based on compile time GL settings.
+static GLuint       g_FontTexture = 0;
+static GLuint       g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int          g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;                                // Uniforms location
+static int          g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
+static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
+static bool         g_IsGLES = false;
+
+// Functions
+static void ImGui_ImplOpenGL3_DestroyFontsTexture()
+{
+    if (g_FontTexture)
+    {
+        ImGuiIO& io = ImGui::GetIO();
+        glDeleteTextures(1, &g_FontTexture);
+        io.Fonts->SetTexID(0);
+        g_FontTexture = 0;
+    }
+}
+
+bool ImGui_ImplOpenGL3_CreateFontsTexture()
+{
+    ImGui_ImplOpenGL3_DestroyFontsTexture();
+    // Build texture atlas
+    ImGuiIO& io = ImGui::GetIO();
+    unsigned char* pixels;
+    int width, height;
+    io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
+
+    // Upload texture to graphics system
+    GLint last_texture;
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+    glGenTextures(1, &g_FontTexture);
+    glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    //#ifdef GL_UNPACK_ROW_LENGTH
+    if (g_IsGLES || g_GlVersion >= 200)
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
+
+    // Store our identifier
+    io.Fonts->SetTexID((ImTextureID)(intptr_t)g_FontTexture);
+
+    // Restore state
+    glBindTexture(GL_TEXTURE_2D, last_texture);
+
+    return true;
+}
+
+// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file.
+static bool CheckShader(GLuint handle, const char* desc)
+{
+    GLint status = 0, log_length = 0;
+    glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
+    glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
+    if ((GLboolean)status == GL_FALSE)
+        SPDLOG_ERROR("ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile {}!", desc);
+    if (log_length > 1)
+    {
+        ImVector<char> buf;
+        buf.resize((int)(log_length + 1));
+        glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin());
+        SPDLOG_ERROR("{}", buf.begin());
+    }
+    return (GLboolean)status == GL_TRUE;
+}
+
+// If you get an error please report on GitHub. You may try different GL context version or GLSL version.
+static bool CheckProgram(GLuint handle, const char* desc)
+{
+    GLint status = 0, log_length = 0;
+    glGetProgramiv(handle, GL_LINK_STATUS, &status);
+    glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
+    if ((GLboolean)status == GL_FALSE)
+        SPDLOG_ERROR("ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link {}! (with GLSL '{}')", desc, g_GlslVersionString);
+    if (log_length > 1)
+    {
+        ImVector<char> buf;
+        buf.resize((int)(log_length + 1));
+        glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin());
+        SPDLOG_ERROR("{}", buf.begin());
+    }
+    return (GLboolean)status == GL_TRUE;
+}
+
+static bool    ImGui_ImplOpenGL3_CreateDeviceObjects()
+{
+    // Backup GL state
+    GLint last_texture, last_array_buffer;
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
+    //#ifndef IMGUI_IMPL_OPENGL_ES2
+    GLint last_vertex_array;
+    if (g_GlVersion >= 300)
+        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
+
+    // Parse GLSL version string
+    int glsl_version = 120;
+    sscanf(g_GlslVersionString, "#version %d", &glsl_version);
+
+    const GLchar* vertex_shader_glsl_120 =
+        "uniform mat4 ProjMtx;\n"
+        "attribute vec2 Position;\n"
+        "attribute vec2 UV;\n"
+        "attribute vec4 Color;\n"
+        "varying vec2 Frag_UV;\n"
+        "varying vec4 Frag_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Frag_UV = UV;\n"
+        "    Frag_Color = Color;\n"
+        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+        "}\n";
+
+    const GLchar* vertex_shader_glsl_130 =
+        "uniform mat4 ProjMtx;\n"
+        "in vec2 Position;\n"
+        "in vec2 UV;\n"
+        "in vec4 Color;\n"
+        "out vec2 Frag_UV;\n"
+        "out vec4 Frag_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Frag_UV = UV;\n"
+        "    Frag_Color = Color;\n"
+        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+        "}\n";
+
+    const GLchar* vertex_shader_glsl_300_es =
+        "precision mediump float;\n"
+        "layout (location = 0) in vec2 Position;\n"
+        "layout (location = 1) in vec2 UV;\n"
+        "layout (location = 2) in vec4 Color;\n"
+        "uniform mat4 ProjMtx;\n"
+        "out vec2 Frag_UV;\n"
+        "out vec4 Frag_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Frag_UV = UV;\n"
+        "    Frag_Color = Color;\n"
+        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+        "}\n";
+
+    const GLchar* vertex_shader_glsl_410_core =
+        "layout (location = 0) in vec2 Position;\n"
+        "layout (location = 1) in vec2 UV;\n"
+        "layout (location = 2) in vec4 Color;\n"
+        "uniform mat4 ProjMtx;\n"
+        "out vec2 Frag_UV;\n"
+        "out vec4 Frag_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Frag_UV = UV;\n"
+        "    Frag_Color = Color;\n"
+        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+        //"    gl_Position = ProjMtx * vec4(Position.xy,0,1) * vec4(1.0, -1.0, 1, 1);\n"
+        "}\n";
+
+    const GLchar* fragment_shader_glsl_120 =
+        "#ifdef GL_ES\n"
+        "    precision mediump float;\n"
+        "#endif\n"
+        "uniform sampler2D Texture;\n"
+        "varying vec2 Frag_UV;\n"
+        "varying vec4 Frag_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = Frag_Color * vec4(1, 1, 1, texture2D(Texture, Frag_UV.st).r);\n"
+        "}\n";
+
+    const GLchar* fragment_shader_glsl_130 =
+        "uniform sampler2D Texture;\n"
+        "in vec2 Frag_UV;\n"
+        "in vec4 Frag_Color;\n"
+        "out vec4 Out_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).r);\n"
+        "}\n";
+
+    const GLchar* fragment_shader_glsl_300_es =
+        "precision mediump float;\n"
+        "uniform sampler2D Texture;\n"
+        "in vec2 Frag_UV;\n"
+        "in vec4 Frag_Color;\n"
+        "layout (location = 0) out vec4 Out_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).r);\n"
+        "}\n";
+
+    const GLchar* fragment_shader_glsl_410_core =
+        "in vec2 Frag_UV;\n"
+        "in vec4 Frag_Color;\n"
+        "uniform sampler2D Texture;\n"
+        "layout (location = 0) out vec4 Out_Color;\n"
+        "void main()\n"
+        "{\n"
+        "    Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).r);\n"
+        "}\n";
+
+    SPDLOG_DEBUG("glsl_version: {}", glsl_version);
+
+    // Select shaders matching our GLSL versions
+    const GLchar* vertex_shader = NULL;
+    const GLchar* fragment_shader = NULL;
+    if (glsl_version < 130)
+    {
+        vertex_shader = vertex_shader_glsl_120;
+        fragment_shader = fragment_shader_glsl_120;
+    }
+    else if (glsl_version >= 410)
+    {
+        vertex_shader = vertex_shader_glsl_410_core;
+        fragment_shader = fragment_shader_glsl_410_core;
+    }
+    else if (glsl_version == 300)
+    {
+        vertex_shader = vertex_shader_glsl_300_es;
+        fragment_shader = fragment_shader_glsl_300_es;
+    }
+    else
+    {
+        vertex_shader = vertex_shader_glsl_130;
+        fragment_shader = fragment_shader_glsl_130;
+    }
+
+    std::stringstream ss;
+    ss << g_GlslVersionString << vertex_shader;
+    std::string shader = ss.str();
+
+    // Create shaders
+    //const GLchar* vertex_shader_with_version[2] = { g_GlslVersionString, vertex_shader };
+    const GLchar* vertex_shader_with_version[1] = { shader.c_str() };
+    g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+    glShaderSource(g_VertHandle, 1, vertex_shader_with_version, NULL);
+    glCompileShader(g_VertHandle);
+    CheckShader(g_VertHandle, "vertex shader");
+
+    ss.str(""); ss.clear();
+    ss << g_GlslVersionString << fragment_shader;
+    shader = ss.str();
+
+    const GLchar* fragment_shader_with_version[1] = { shader.c_str() };
+    g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+    glShaderSource(g_FragHandle, 1, fragment_shader_with_version, NULL);
+    glCompileShader(g_FragHandle);
+    CheckShader(g_FragHandle, "fragment shader");
+
+    g_ShaderHandle = glCreateProgram();
+    glAttachShader(g_ShaderHandle, g_VertHandle);
+    glAttachShader(g_ShaderHandle, g_FragHandle);
+    glLinkProgram(g_ShaderHandle);
+    CheckProgram(g_ShaderHandle, "shader program");
+
+    g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+    g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+    g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position");
+    g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV");
+    g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+    // Create buffers
+    glGenBuffers(1, &g_VboHandle);
+    glGenBuffers(1, &g_ElementsHandle);
+
+    ImGui_ImplOpenGL3_CreateFontsTexture();
+
+    // Restore modified GL state
+    glBindTexture(GL_TEXTURE_2D, last_texture);
+    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
+    //#ifndef IMGUI_IMPL_OPENGL_ES2
+    if (g_GlVersion >= 300)
+        glBindVertexArray(last_vertex_array);
+
+    return true;
+}
+
+static void    ImGui_ImplOpenGL3_DestroyDeviceObjects()
+{
+    if (g_VboHandle)        { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; }
+    if (g_ElementsHandle)   { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; }
+    if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); }
+    if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); }
+    if (g_VertHandle)       { glDeleteShader(g_VertHandle); g_VertHandle = 0; }
+    if (g_FragHandle)       { glDeleteShader(g_FragHandle); g_FragHandle = 0; }
+    if (g_ShaderHandle)     { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; }
+
+    ImGui_ImplOpenGL3_DestroyFontsTexture();
+}
+
+void GetOpenGLVersion(int& major, int& minor, bool& isGLES)
+{
+    //glGetIntegerv(GL_MAJOR_VERSION, &major);
+    //glGetIntegerv(GL_MINOR_VERSION, &minor);
+
+    const char* version;
+    const char* prefixes[] = {
+        "OpenGL ES-CM ",
+        "OpenGL ES-CL ",
+        "OpenGL ES ",
+        nullptr
+    };
+
+    version = (const char*) glGetString(GL_VERSION);
+    if (!version)
+        return;
+
+    //if (glGetError() == 0x500)
+    {
+        for (int i = 0;  prefixes[i];  i++) {
+            const size_t length = strlen(prefixes[i]);
+            if (strncmp(version, prefixes[i], length) == 0) {
+                version += length;
+                isGLES = true;
+                break;
+            }
+        }
+
+        sscanf(version, "%d.%d", &major, &minor);
+    }
+}
+
+bool    ImGui_ImplOpenGL3_Init(const char* glsl_version)
+{
+    GLint major = 0, minor = 0;
+    GetOpenGLVersion(major, minor, g_IsGLES);
+
+    SPDLOG_INFO("GL version: {}.{} {}", major, minor, g_IsGLES ? "ES" : "");
+
+    if (!g_IsGLES) {
+        // Not GL ES
+        glsl_version = "#version 120";
+        g_GlVersion = major * 100 + minor * 10;
+        if (major >= 4 && minor >= 1)
+            glsl_version = "#version 410";
+        else if (major > 3 || (major == 3 && minor >= 2))
+            glsl_version = "#version 150";
+        else if (major == 3)
+            glsl_version = "#version 130";
+        else if (major < 2)
+            glsl_version = "#version 100";
+    } else {
+        if (major >= 3)
+            g_GlVersion = major * 100 + minor * 10; // GLES >= 3
+        else
+            g_GlVersion = 200; // GLES 2
+
+        // Store GLSL version string so we can refer to it later in case we recreate shaders.
+        // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
+        if (g_GlVersion == 200)
+            glsl_version = "#version 100";
+        else if (g_GlVersion >= 300)
+            glsl_version = "#version 300 es";
+        else
+            glsl_version = "#version 120";
+    }
+
+    // Setup back-end capabilities flags
+    ImGuiIO& io = ImGui::GetIO();
+    io.BackendRendererName = "mangohud_opengl3";
+    //#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
+    if (g_GlVersion >= 320) // GL/GLES 3.2+
+        io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
+
+    // Store GLSL version string so we can refer to it later in case we recreate shaders.
+    // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
+    if (glsl_version == NULL)
+        glsl_version = "#version 120";
+
+    IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));
+    strcpy(g_GlslVersionString, glsl_version);
+    strcat(g_GlslVersionString, "\n");
+
+    // Make a dummy GL call (we don't actually need the result)
+    // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
+    // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
+    GLint current_texture;
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
+
+    return true;
+}
+
+void    ImGui_ImplOpenGL3_Shutdown()
+{
+    ImGui_ImplOpenGL3_DestroyDeviceObjects();
+}
+
+void    ImGui_ImplOpenGL3_NewFrame()
+{
+    if (!g_ShaderHandle)
+        ImGui_ImplOpenGL3_CreateDeviceObjects();
+    else if (!glIsProgram(g_ShaderHandle)) { // TODO Got created in a now dead context?
+        SPDLOG_DEBUG("Recreating lost objects");
+        ImGui_ImplOpenGL3_CreateDeviceObjects();
+    }
+
+    if (!glIsTexture(g_FontTexture)) {
+        SPDLOG_DEBUG("GL Texture lost? Regenerating.");
+        g_FontTexture = 0;
+        ImGui_ImplOpenGL3_CreateFontsTexture();
+    }
+}
+
+static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
+{
+    // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
+    if (params.gl_bind_framebuffer >= 0 && (g_IsGLES || g_GlVersion >= 300))
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, params.gl_bind_framebuffer);
+    glEnable(GL_BLEND);
+    glBlendEquation(GL_FUNC_ADD);
+    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_STENCIL_TEST);
+    glEnable(GL_SCISSOR_TEST);
+    glDisable(GL_FRAMEBUFFER_SRGB);
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+    if (!g_IsGLES)
+    {
+        //#ifdef GL_POLYGON_MODE
+        if (g_GlVersion >= 200)
+            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+        if (g_GlVersion >= 310)
+            glDisable(GL_PRIMITIVE_RESTART);
+    }
+
+    bool clip_origin_lower_left = true;
+    GLenum last_clip_origin = 0;
+    if (!g_IsGLES && /*g_GlVersion >= 450*/ (glad_glClipControl || glad_glClipControlEXT)) {
+        glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
+        if (last_clip_origin == GL_UPPER_LEFT)
+            clip_origin_lower_left = false;
+    }
+
+    // Setup viewport, orthographic projection matrix
+    // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
+    glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
+    float L = draw_data->DisplayPos.x;
+    float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
+    float T = draw_data->DisplayPos.y;
+    float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
+    if (!params.gl_dont_flip && !clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
+    const float ortho_projection[4][4] =
+    {
+        { 2.0f/(R-L),   0.0f,         0.0f,   0.0f },
+        { 0.0f,         2.0f/(T-B),   0.0f,   0.0f },
+        { 0.0f,         0.0f,        -1.0f,   0.0f },
+        { (R+L)/(L-R),  (T+B)/(B-T),  0.0f,   1.0f },
+    };
+    glUseProgram(g_ShaderHandle);
+    glUniform1i(g_AttribLocationTex, 0);
+    glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+
+    if (g_GlVersion >= 330)
+        glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
+
+    (void)vertex_array_object;
+    //#ifndef IMGUI_IMPL_OPENGL_ES2
+    if (g_GlVersion >= 300)
+        glBindVertexArray(vertex_array_object);
+
+    // Bind vertex/index buffers and setup attributes for ImDrawVert
+    glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
+    glEnableVertexAttribArray(g_AttribLocationVtxPos);
+    glEnableVertexAttribArray(g_AttribLocationVtxUV);
+    glEnableVertexAttribArray(g_AttribLocationVtxColor);
+    glVertexAttribPointer(g_AttribLocationVtxPos,   2, GL_FLOAT,         GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
+    glVertexAttribPointer(g_AttribLocationVtxUV,    2, GL_FLOAT,         GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
+    glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE,  sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
+}
+
+// OpenGL3 Render function.
+// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
+// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
+void    ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
+{
+    // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
+    int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
+    int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
+    if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0)
+        return;
+
+    // Backup GL state
+    GLint last_fb = -1;
+    if (params.gl_bind_framebuffer >= 0 && (g_IsGLES || g_GlVersion >= 300))
+        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
+    GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
+    glActiveTexture(GL_TEXTURE0);
+    GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+    GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+
+    // GL_SAMPLER_BINDING
+    GLint last_sampler;
+    if (!g_IsGLES && g_GlVersion >= 330)
+        glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
+
+    GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
+
+//#ifndef IMGUI_IMPL_OPENGL_ES2
+    GLint last_vertex_array_object;
+    if (g_GlVersion >= 300)
+        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
+
+    GLint last_polygon_mode[2];
+    if (!g_IsGLES && g_GlVersion >= 200)
+        glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
+
+    GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
+    GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
+    GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
+    GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
+    GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
+    GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
+    GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
+    GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
+    GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
+    GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
+    GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
+    GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
+    GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
+    // Disable and store SRGB state.
+    GLboolean last_srgb_enabled = glIsEnabled(GL_FRAMEBUFFER_SRGB);
+    GLboolean last_enable_primitive_restart = (!g_IsGLES && g_GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
+
+    // Setup desired GL state
+    // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
+    // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
+    GLuint vertex_array_object = 0;
+    if (g_GlVersion >= 300)
+        glGenVertexArrays(1, &vertex_array_object);
+
+    ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
+
+    // Will project scissor/clipping rectangles into framebuffer space
+    ImVec2 clip_off = draw_data->DisplayPos;         // (0,0) unless using multi-viewports
+    ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
+
+    // Render command lists
+    for (int n = 0; n < draw_data->CmdListsCount; n++)
+    {
+        const ImDrawList* cmd_list = draw_data->CmdLists[n];
+
+        // Upload vertex/index buffers
+        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
+
+        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+        {
+            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+            if (pcmd->UserCallback != NULL)
+            {
+                // User callback, registered via ImDrawList::AddCallback()
+                // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
+                if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
+                    ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
+                else
+                    pcmd->UserCallback(cmd_list, pcmd);
+            }
+            else
+            {
+                // Project scissor/clipping rectangles into framebuffer space
+                ImVec4 clip_rect;
+                clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
+                clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
+                clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
+                clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
+
+                if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
+                {
+                    // Apply scissor/clipping rectangle
+                    if (!params.gl_dont_flip)
+                        glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
+                    else
+                        glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w);
+
+                    // Bind texture, Draw
+                    glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+                    //#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
+                    if (g_GlVersion >= 320) // OGL and OGL ES
+                        glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
+                    else
+                        glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
+                }
+            }
+        }
+    }
+
+    // Destroy the temporary VAO
+    if (g_GlVersion >= 300)
+        glDeleteVertexArrays(1, &vertex_array_object);
+
+    // Restore modified GL state
+    glUseProgram(last_program);
+    glBindTexture(GL_TEXTURE_2D, last_texture);
+
+    if (!g_IsGLES && g_GlVersion >= 330)
+        glBindSampler(0, last_sampler);
+
+    glActiveTexture(last_active_texture);
+
+    if (g_GlVersion >= 300)
+        glBindVertexArray(last_vertex_array_object);
+
+    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
+    glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
+    glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
+    if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
+    if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
+    if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
+    if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
+    if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
+    if (!g_IsGLES && g_GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); }
+
+    if (!g_IsGLES && g_GlVersion >= 200)
+        glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
+
+    glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
+    glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
+
+    if (last_srgb_enabled)
+        glEnable(GL_FRAMEBUFFER_SRGB);
+    if (last_fb >= 0)
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, last_fb);
+}
+
+}} // namespace
diff -pruN 0.6.7.1-1/src/gl/gl_renderer.h 0.6.8-1/src/gl/gl_renderer.h
--- 0.6.7.1-1/src/gl/gl_renderer.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.6.8-1/src/gl/gl_renderer.h	2022-08-01 01:27:11.000000000 +0000
@@ -0,0 +1,47 @@
+// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
+// - Desktop GL: 2.x 3.x 4.x
+// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
+// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
+
+// Implemented features:
+//  [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
+//  [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
+
+// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
+// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
+// https://github.com/ocornut/imgui
+
+// About Desktop OpenGL function loaders:
+//  Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
+//  Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
+//  You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
+
+// About GLSL version:
+//  The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string.
+//  On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
+//  Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
+
+#pragma once
+#ifndef MANGOHUD_IMGUI_IMPL_OPENGL3_H
+#define MANGOHUD_IMGUI_IMPL_OPENGL3_H
+
+namespace MangoHud { namespace GL {
+
+void GetOpenGLVersion(int& major, int& minor, bool& isGLES);
+
+// Backend API
+IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
+IMGUI_IMPL_API void     ImGui_ImplOpenGL3_Shutdown();
+IMGUI_IMPL_API void     ImGui_ImplOpenGL3_NewFrame();
+IMGUI_IMPL_API void     ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
+IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_CreateFontsTexture();
+
+// (Optional) Called by Init/NewFrame/Shutdown
+//IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_CreateFontsTexture();
+//IMGUI_IMPL_API void     ImGui_ImplOpenGL3_DestroyFontsTexture();
+//IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_CreateDeviceObjects();
+//IMGUI_IMPL_API void     ImGui_ImplOpenGL3_DestroyDeviceObjects();
+
+}}
+
+#endif //MANGOHUD_IMGUI_IMPL_OPENGL3_H
diff -pruN 0.6.7.1-1/src/gl/imgui_hud.cpp 0.6.8-1/src/gl/imgui_hud.cpp
--- 0.6.7.1-1/src/gl/imgui_hud.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gl/imgui_hud.cpp	1970-01-01 00:00:00.000000000 +0000
@@ -1,227 +0,0 @@
-#include <cstdlib>
-#include <functional>
-#include <thread>
-#include <string>
-#include <iostream>
-#include <sstream>
-#include <memory>
-#include <unistd.h>
-#include <filesystem.h>
-#include <spdlog/spdlog.h>
-#include <imgui.h>
-#include "font_default.h"
-#include "cpu.h"
-#include "file_utils.h"
-#include "imgui_hud.h"
-#include "notify.h"
-#include "blacklist.h"
-#include "overlay.h"
-
-#ifdef HAVE_DBUS
-#include "dbus_info.h"
-#endif
-
-#include <glad/glad.h>
-
-namespace fs = ghc::filesystem;
-
-namespace MangoHud { namespace GL {
-
-struct GLVec
-{
-    GLint v[4];
-
-    GLint operator[] (size_t i)
-    {
-        return v[i];
-    }
-
-    bool operator== (const GLVec& r)
-    {
-        return v[0] == r.v[0]
-            && v[1] == r.v[1]
-            && v[2] == r.v[2]
-            && v[3] == r.v[3];
-    }
-
-    bool operator!= (const GLVec& r)
-    {
-        return !(*this == r);
-    }
-};
-
-struct state {
-    ImGuiContext *imgui_ctx = nullptr;
-};
-
-static GLVec last_vp {}, last_sb {};
-swapchain_stats sw_stats {};
-static state state;
-static uint32_t vendorID;
-static std::string deviceName;
-
-static notify_thread notifier;
-static bool cfg_inited = false;
-static ImVec2 window_size;
-static bool inited = false;
-overlay_params params {};
-
-// seems to quit by itself though
-static std::unique_ptr<notify_thread, std::function<void(notify_thread *)>>
-    stop_it(&notifier, [](notify_thread *n){ stop_notifier(*n); });
-
-void imgui_init()
-{
-    if (cfg_inited)
-        return;
-
-    init_spdlog();
-    parse_overlay_config(&params, getenv("MANGOHUD_CONFIG"));
-    _params = &params;
-
-   //check for blacklist item in the config file
-   for (auto& item : params.blacklist) {
-      add_blacklist(item);
-   }
-
-    if (sw_stats.engine != EngineTypes::ZINK){
-        sw_stats.engine = OPENGL;
-
-        fs::path path("/proc/self/map_files/");
-        for (auto& p : fs::directory_iterator(path)) {
-            auto file = p.path().string();
-            auto sym = read_symlink(file.c_str());
-            if (sym.find("wined3d") != std::string::npos) {
-                sw_stats.engine = WINED3D;
-                break;
-            } else if (sym.find("libtogl.so") != std::string::npos || sym.find("libtogl_client.so") != std::string::npos) {
-                sw_stats.engine = TOGL;
-                break;
-            }
-        }
-    }
-
-    is_blacklisted(true);
-    notifier.params = &params;
-    start_notifier(notifier);
-    window_size = ImVec2(params.width, params.height);
-    init_system_info();
-    cfg_inited = true;
-    init_cpu_stats(params);
-}
-
-//static
-void imgui_create(void *ctx)
-{
-    if (inited)
-        return;
-
-    if (!ctx)
-        return;
-
-    imgui_shutdown();
-    imgui_init();
-    inited = true;
-
-    gladLoadGL();
-
-    GetOpenGLVersion(sw_stats.version_gl.major,
-        sw_stats.version_gl.minor,
-        sw_stats.version_gl.is_gles);
-
-    deviceName = (char*)glGetString(GL_RENDERER);
-    SPDLOG_DEBUG("deviceName: {}", deviceName);
-    sw_stats.deviceName = deviceName;
-    if (deviceName.find("Radeon") != std::string::npos
-    || deviceName.find("AMD") != std::string::npos){
-        vendorID = 0x1002;
-    } else {
-        vendorID = 0x10de;
-    }
-    if (deviceName.find("zink") != std::string::npos)
-        sw_stats.engine = EngineTypes::ZINK;
-    init_gpu_stats(vendorID, 0, params);
-    sw_stats.gpuName = gpu = get_device_name(vendorID, deviceID);
-    SPDLOG_DEBUG("gpu: {}", gpu);
-    // Setup Dear ImGui context
-    IMGUI_CHECKVERSION();
-    ImGuiContext *saved_ctx = ImGui::GetCurrentContext();
-    state.imgui_ctx = ImGui::CreateContext();
-    ImGuiIO& io = ImGui::GetIO(); (void)io;
-    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
-    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
-
-    // Setup Dear ImGui style
-    ImGui::StyleColorsDark();
-    //ImGui::StyleColorsClassic();
-    HUDElements.convert_colors(false, params);
-
-    glGetIntegerv (GL_VIEWPORT, last_vp.v);
-    glGetIntegerv (GL_SCISSOR_BOX, last_sb.v);
-
-    ImGui::GetIO().IniFilename = NULL;
-    ImGui::GetIO().DisplaySize = ImVec2(last_vp[2], last_vp[3]);
-
-    ImGui_ImplOpenGL3_Init();
-
-    create_fonts(params, sw_stats.font1, sw_stats.font_text);
-    sw_stats.font_params_hash = params.font_params_hash;
-
-    // Restore global context or ours might clash with apps that use Dear ImGui
-    ImGui::SetCurrentContext(saved_ctx);
-}
-
-void imgui_shutdown()
-{
-    if (state.imgui_ctx) {
-        ImGui::SetCurrentContext(state.imgui_ctx);
-        ImGui_ImplOpenGL3_Shutdown();
-        ImGui::DestroyContext(state.imgui_ctx);
-        state.imgui_ctx = nullptr;
-    }
-    inited = false;
-}
-
-void imgui_set_context(void *ctx)
-{
-    if (!ctx)
-        return;
-    imgui_create(ctx);
-}
-
-void imgui_render(unsigned int width, unsigned int height)
-{
-    if (!state.imgui_ctx)
-        return;
-
-    check_keybinds(params, vendorID);
-    update_hud_info(sw_stats, params, vendorID);
-
-    ImGuiContext *saved_ctx = ImGui::GetCurrentContext();
-    ImGui::SetCurrentContext(state.imgui_ctx);
-    ImGui::GetIO().DisplaySize = ImVec2(width, height);
-    if (HUDElements.colors.update)
-        HUDElements.convert_colors(params);
-
-    if (sw_stats.font_params_hash != params.font_params_hash)
-    {
-        sw_stats.font_params_hash = params.font_params_hash;
-        create_fonts(params, sw_stats.font1, sw_stats.font_text);
-        ImGui_ImplOpenGL3_CreateFontsTexture();
-    }
-
-    ImGui_ImplOpenGL3_NewFrame();
-    ImGui::NewFrame();
-    {
-        std::lock_guard<std::mutex> lk(notifier.mutex);
-        position_layer(sw_stats, params, window_size);
-        render_imgui(sw_stats, params, window_size, false);
-    }
-    ImGui::PopStyleVar(3);
-
-    ImGui::Render();
-    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-    ImGui::SetCurrentContext(saved_ctx);
-}
-
-}} // namespaces
diff -pruN 0.6.7.1-1/src/gl/imgui_hud.h 0.6.8-1/src/gl/imgui_hud.h
--- 0.6.7.1-1/src/gl/imgui_hud.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gl/imgui_hud.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-#pragma once
-#ifndef MANGOHUD_GL_IMGUI_HUD_H
-#define MANGOHUD_GL_IMGUI_HUD_H
-
-#include "overlay.h"
-#include "imgui_impl_opengl3.h"
-
-namespace MangoHud { namespace GL {
-
-extern overlay_params params;
-void imgui_init();
-void imgui_create(void *ctx);
-void imgui_shutdown();
-void imgui_set_context(void *ctx);
-void imgui_render(unsigned int width, unsigned int height);
-
-}} // namespace
-
-#endif //MANGOHUD_GL_IMGUI_HUD_H
\ No newline at end of file
diff -pruN 0.6.7.1-1/src/gl/imgui_impl_opengl3.cpp 0.6.8-1/src/gl/imgui_impl_opengl3.cpp
--- 0.6.7.1-1/src/gl/imgui_impl_opengl3.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gl/imgui_impl_opengl3.cpp	1970-01-01 00:00:00.000000000 +0000
@@ -1,718 +0,0 @@
-// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
-// - Desktop GL: 2.x 3.x 4.x
-// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
-// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
-
-// Implemented features:
-//  [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
-//  [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
-
-// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
-// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
-// https://github.com/ocornut/imgui
-
-// CHANGELOG
-// (minor and older changes stripped away, please see git history for details)
-//  2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
-//  2020-01-07: OpenGL: Added support for glbindings OpenGL loader.
-//  2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders.
-//  2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility.
-//  2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call.
-//  2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
-//  2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
-//  2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
-//  2019-03-15: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
-//  2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
-//  2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
-//  2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
-//  2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
-//  2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
-//  2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
-//  2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
-//  2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
-//  2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
-//  2018-07-10: OpenGL: Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to compile/link.
-//  2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 examples.
-//  2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
-//  2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the VAO state.
-//  2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't fail if the function is a NULL pointer.
-//  2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150".
-//  2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context.
-//  2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself.
-//  2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150.
-//  2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode.
-//  2017-05-01: OpenGL: Fixed save and restore of current blend func state.
-//  2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE.
-//  2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
-//  2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752)
-
-//----------------------------------------
-// OpenGL    GLSL      GLSL
-// version   version   string
-//----------------------------------------
-//  2.0       110       "#version 110"
-//  2.1       120       "#version 120"
-//  3.0       130       "#version 130"
-//  3.1       140       "#version 140"
-//  3.2       150       "#version 150"
-//  3.3       330       "#version 330 core"
-//  4.0       400       "#version 400 core"
-//  4.1       410       "#version 410 core"
-//  4.2       420       "#version 410 core"
-//  4.3       430       "#version 430 core"
-//  ES 2.0    100       "#version 100"      = WebGL 1.0
-//  ES 3.0    300       "#version 300 es"   = WebGL 2.0
-//----------------------------------------
-
-#include <spdlog/spdlog.h>
-#include <imgui.h>
-#include "imgui_impl_opengl3.h"
-#include <stdio.h>
-#include <stdint.h>     // intptr_t
-#include <sstream>
-
-#include <spdlog/spdlog.h>
-#include <glad/glad.h>
-
-#include "overlay.h"
-
-namespace MangoHud { namespace GL {
-
-extern overlay_params params;
-
-// OpenGL Data
-static GLuint       g_GlVersion = 0;                // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries.
-static char         g_GlslVersionString[32] = "";   // Specified by user or detected based on compile time GL settings.
-static GLuint       g_FontTexture = 0;
-static GLuint       g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
-static int          g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;                                // Uniforms location
-static int          g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
-static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
-static bool         g_IsGLES = false;
-
-// Functions
-static void ImGui_ImplOpenGL3_DestroyFontsTexture()
-{
-    if (g_FontTexture)
-    {
-        ImGuiIO& io = ImGui::GetIO();
-        glDeleteTextures(1, &g_FontTexture);
-        io.Fonts->SetTexID(0);
-        g_FontTexture = 0;
-    }
-}
-
-bool ImGui_ImplOpenGL3_CreateFontsTexture()
-{
-    ImGui_ImplOpenGL3_DestroyFontsTexture();
-    // Build texture atlas
-    ImGuiIO& io = ImGui::GetIO();
-    unsigned char* pixels;
-    int width, height;
-    io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
-
-    // Upload texture to graphics system
-    GLint last_texture;
-    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
-    glGenTextures(1, &g_FontTexture);
-    glBindTexture(GL_TEXTURE_2D, g_FontTexture);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    //#ifdef GL_UNPACK_ROW_LENGTH
-    if (g_IsGLES || g_GlVersion >= 200)
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
-
-    // Store our identifier
-    io.Fonts->SetTexID((ImTextureID)(intptr_t)g_FontTexture);
-
-    // Restore state
-    glBindTexture(GL_TEXTURE_2D, last_texture);
-
-    return true;
-}
-
-// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file.
-static bool CheckShader(GLuint handle, const char* desc)
-{
-    GLint status = 0, log_length = 0;
-    glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
-    glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
-    if ((GLboolean)status == GL_FALSE)
-        SPDLOG_ERROR("ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile {}!", desc);
-    if (log_length > 1)
-    {
-        ImVector<char> buf;
-        buf.resize((int)(log_length + 1));
-        glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin());
-        SPDLOG_ERROR("{}", buf.begin());
-    }
-    return (GLboolean)status == GL_TRUE;
-}
-
-// If you get an error please report on GitHub. You may try different GL context version or GLSL version.
-static bool CheckProgram(GLuint handle, const char* desc)
-{
-    GLint status = 0, log_length = 0;
-    glGetProgramiv(handle, GL_LINK_STATUS, &status);
-    glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
-    if ((GLboolean)status == GL_FALSE)
-        SPDLOG_ERROR("ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link {}! (with GLSL '{}')", desc, g_GlslVersionString);
-    if (log_length > 1)
-    {
-        ImVector<char> buf;
-        buf.resize((int)(log_length + 1));
-        glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin());
-        SPDLOG_ERROR("{}", buf.begin());
-    }
-    return (GLboolean)status == GL_TRUE;
-}
-
-static bool    ImGui_ImplOpenGL3_CreateDeviceObjects()
-{
-    // Backup GL state
-    GLint last_texture, last_array_buffer;
-    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
-    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
-    //#ifndef IMGUI_IMPL_OPENGL_ES2
-    GLint last_vertex_array;
-    if (g_GlVersion >= 300)
-        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
-
-    // Parse GLSL version string
-    int glsl_version = 120;
-    sscanf(g_GlslVersionString, "#version %d", &glsl_version);
-
-    const GLchar* vertex_shader_glsl_120 =
-        "uniform mat4 ProjMtx;\n"
-        "attribute vec2 Position;\n"
-        "attribute vec2 UV;\n"
-        "attribute vec4 Color;\n"
-        "varying vec2 Frag_UV;\n"
-        "varying vec4 Frag_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Frag_UV = UV;\n"
-        "    Frag_Color = Color;\n"
-        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
-        "}\n";
-
-    const GLchar* vertex_shader_glsl_130 =
-        "uniform mat4 ProjMtx;\n"
-        "in vec2 Position;\n"
-        "in vec2 UV;\n"
-        "in vec4 Color;\n"
-        "out vec2 Frag_UV;\n"
-        "out vec4 Frag_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Frag_UV = UV;\n"
-        "    Frag_Color = Color;\n"
-        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
-        "}\n";
-
-    const GLchar* vertex_shader_glsl_300_es =
-        "precision mediump float;\n"
-        "layout (location = 0) in vec2 Position;\n"
-        "layout (location = 1) in vec2 UV;\n"
-        "layout (location = 2) in vec4 Color;\n"
-        "uniform mat4 ProjMtx;\n"
-        "out vec2 Frag_UV;\n"
-        "out vec4 Frag_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Frag_UV = UV;\n"
-        "    Frag_Color = Color;\n"
-        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
-        "}\n";
-
-    const GLchar* vertex_shader_glsl_410_core =
-        "layout (location = 0) in vec2 Position;\n"
-        "layout (location = 1) in vec2 UV;\n"
-        "layout (location = 2) in vec4 Color;\n"
-        "uniform mat4 ProjMtx;\n"
-        "out vec2 Frag_UV;\n"
-        "out vec4 Frag_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Frag_UV = UV;\n"
-        "    Frag_Color = Color;\n"
-        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
-        //"    gl_Position = ProjMtx * vec4(Position.xy,0,1) * vec4(1.0, -1.0, 1, 1);\n"
-        "}\n";
-
-    const GLchar* fragment_shader_glsl_120 =
-        "#ifdef GL_ES\n"
-        "    precision mediump float;\n"
-        "#endif\n"
-        "uniform sampler2D Texture;\n"
-        "varying vec2 Frag_UV;\n"
-        "varying vec4 Frag_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_FragColor = Frag_Color * vec4(1, 1, 1, texture2D(Texture, Frag_UV.st).r);\n"
-        "}\n";
-
-    const GLchar* fragment_shader_glsl_130 =
-        "uniform sampler2D Texture;\n"
-        "in vec2 Frag_UV;\n"
-        "in vec4 Frag_Color;\n"
-        "out vec4 Out_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).r);\n"
-        "}\n";
-
-    const GLchar* fragment_shader_glsl_300_es =
-        "precision mediump float;\n"
-        "uniform sampler2D Texture;\n"
-        "in vec2 Frag_UV;\n"
-        "in vec4 Frag_Color;\n"
-        "layout (location = 0) out vec4 Out_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).r);\n"
-        "}\n";
-
-    const GLchar* fragment_shader_glsl_410_core =
-        "in vec2 Frag_UV;\n"
-        "in vec4 Frag_Color;\n"
-        "uniform sampler2D Texture;\n"
-        "layout (location = 0) out vec4 Out_Color;\n"
-        "void main()\n"
-        "{\n"
-        "    Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).r);\n"
-        "}\n";
-
-#ifndef NDEBUG
-    fprintf(stderr, "glsl_version: %d\n", glsl_version);
-#endif
-    // Select shaders matching our GLSL versions
-    const GLchar* vertex_shader = NULL;
-    const GLchar* fragment_shader = NULL;
-    if (glsl_version < 130)
-    {
-        vertex_shader = vertex_shader_glsl_120;
-        fragment_shader = fragment_shader_glsl_120;
-    }
-    else if (glsl_version >= 410)
-    {
-        vertex_shader = vertex_shader_glsl_410_core;
-        fragment_shader = fragment_shader_glsl_410_core;
-    }
-    else if (glsl_version == 300)
-    {
-        vertex_shader = vertex_shader_glsl_300_es;
-        fragment_shader = fragment_shader_glsl_300_es;
-    }
-    else
-    {
-        vertex_shader = vertex_shader_glsl_130;
-        fragment_shader = fragment_shader_glsl_130;
-    }
-
-    std::stringstream ss;
-    ss << g_GlslVersionString << vertex_shader;
-    std::string shader = ss.str();
-
-    // Create shaders
-    //const GLchar* vertex_shader_with_version[2] = { g_GlslVersionString, vertex_shader };
-    const GLchar* vertex_shader_with_version[1] = { shader.c_str() };
-    g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
-    glShaderSource(g_VertHandle, 1, vertex_shader_with_version, NULL);
-    glCompileShader(g_VertHandle);
-    CheckShader(g_VertHandle, "vertex shader");
-
-    ss.str(""); ss.clear();
-    ss << g_GlslVersionString << fragment_shader;
-    shader = ss.str();
-
-    const GLchar* fragment_shader_with_version[1] = { shader.c_str() };
-    g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
-    glShaderSource(g_FragHandle, 1, fragment_shader_with_version, NULL);
-    glCompileShader(g_FragHandle);
-    CheckShader(g_FragHandle, "fragment shader");
-
-    g_ShaderHandle = glCreateProgram();
-    glAttachShader(g_ShaderHandle, g_VertHandle);
-    glAttachShader(g_ShaderHandle, g_FragHandle);
-    glLinkProgram(g_ShaderHandle);
-    CheckProgram(g_ShaderHandle, "shader program");
-
-    g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
-    g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
-    g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position");
-    g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV");
-    g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color");
-
-    // Create buffers
-    glGenBuffers(1, &g_VboHandle);
-    glGenBuffers(1, &g_ElementsHandle);
-
-    ImGui_ImplOpenGL3_CreateFontsTexture();
-
-    // Restore modified GL state
-    glBindTexture(GL_TEXTURE_2D, last_texture);
-    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
-    //#ifndef IMGUI_IMPL_OPENGL_ES2
-    if (g_GlVersion >= 300)
-        glBindVertexArray(last_vertex_array);
-
-    return true;
-}
-
-static void    ImGui_ImplOpenGL3_DestroyDeviceObjects()
-{
-#ifndef NDEBUG
-    fprintf(stderr, "%s\n", __func__);
-#endif
-    if (g_VboHandle)        { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; }
-    if (g_ElementsHandle)   { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; }
-    if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); }
-    if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); }
-    if (g_VertHandle)       { glDeleteShader(g_VertHandle); g_VertHandle = 0; }
-    if (g_FragHandle)       { glDeleteShader(g_FragHandle); g_FragHandle = 0; }
-    if (g_ShaderHandle)     { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; }
-
-    ImGui_ImplOpenGL3_DestroyFontsTexture();
-}
-
-void GetOpenGLVersion(int& major, int& minor, bool& isGLES)
-{
-    //glGetIntegerv(GL_MAJOR_VERSION, &major);
-    //glGetIntegerv(GL_MINOR_VERSION, &minor);
-
-    const char* version;
-    const char* prefixes[] = {
-        "OpenGL ES-CM ",
-        "OpenGL ES-CL ",
-        "OpenGL ES ",
-        nullptr
-    };
-
-    version = (const char*) glGetString(GL_VERSION);
-    if (!version)
-        return;
-
-    //if (glGetError() == 0x500)
-    {
-        for (int i = 0;  prefixes[i];  i++) {
-            const size_t length = strlen(prefixes[i]);
-            if (strncmp(version, prefixes[i], length) == 0) {
-                version += length;
-                isGLES = true;
-                break;
-            }
-        }
-
-        sscanf(version, "%d.%d", &major, &minor);
-    }
-}
-
-bool    ImGui_ImplOpenGL3_Init(const char* glsl_version)
-{
-    GLint major = 0, minor = 0;
-    GetOpenGLVersion(major, minor, g_IsGLES);
-
-    SPDLOG_INFO("GL version: {}.{} {}", major, minor, g_IsGLES ? "ES" : "");
-
-    if (!g_IsGLES) {
-        // Not GL ES
-        glsl_version = "#version 120";
-        g_GlVersion = major * 100 + minor * 10;
-        if (major >= 4 && minor >= 1)
-            glsl_version = "#version 410";
-        else if (major > 3 || (major == 3 && minor >= 2))
-            glsl_version = "#version 150";
-        else if (major == 3)
-            glsl_version = "#version 130";
-        else if (major < 2)
-            glsl_version = "#version 100";
-    } else {
-        if (major >= 3)
-            g_GlVersion = major * 100 + minor * 10; // GLES >= 3
-        else
-            g_GlVersion = 200; // GLES 2
-
-        // Store GLSL version string so we can refer to it later in case we recreate shaders.
-        // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
-        if (g_GlVersion == 200)
-            glsl_version = "#version 100";
-        else if (g_GlVersion >= 300)
-            glsl_version = "#version 300 es";
-        else
-            glsl_version = "#version 120";
-    }
-
-    // Setup back-end capabilities flags
-    ImGuiIO& io = ImGui::GetIO();
-    io.BackendRendererName = "imgui_impl_opengl3";
-    //#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
-    if (g_GlVersion >= 320) // GL/GLES 3.2+
-        io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
-
-    // Store GLSL version string so we can refer to it later in case we recreate shaders.
-    // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
-    if (glsl_version == NULL)
-        glsl_version = "#version 120";
-
-    IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));
-    strcpy(g_GlslVersionString, glsl_version);
-    strcat(g_GlslVersionString, "\n");
-
-    // Make a dummy GL call (we don't actually need the result)
-    // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
-    // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
-    GLint current_texture;
-    glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
-
-    return true;
-}
-
-void    ImGui_ImplOpenGL3_Shutdown()
-{
-    ImGui_ImplOpenGL3_DestroyDeviceObjects();
-}
-
-void    ImGui_ImplOpenGL3_NewFrame()
-{
-    if (!g_ShaderHandle)
-        ImGui_ImplOpenGL3_CreateDeviceObjects();
-    else if (!glIsProgram(g_ShaderHandle)) { // TODO Got created in a now dead context?
-        SPDLOG_DEBUG("Recreating lost objects");
-        ImGui_ImplOpenGL3_CreateDeviceObjects();
-    }
-
-    if (!glIsTexture(g_FontTexture)) {
-        SPDLOG_DEBUG("GL Texture lost? Regenerating.");
-        g_FontTexture = 0;
-        ImGui_ImplOpenGL3_CreateFontsTexture();
-    }
-}
-
-static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
-{
-    // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
-    if (params.gl_bind_framebuffer >= 0 && (g_IsGLES || g_GlVersion >= 300))
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, params.gl_bind_framebuffer);
-    glEnable(GL_BLEND);
-    glBlendEquation(GL_FUNC_ADD);
-    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-    glDisable(GL_CULL_FACE);
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_STENCIL_TEST);
-    glEnable(GL_SCISSOR_TEST);
-    glDisable(GL_FRAMEBUFFER_SRGB);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
-    if (!g_IsGLES)
-    {
-        //#ifdef GL_POLYGON_MODE
-        if (g_GlVersion >= 200)
-            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-        if (g_GlVersion >= 310)
-            glDisable(GL_PRIMITIVE_RESTART);
-    }
-
-    bool clip_origin_lower_left = true;
-    GLenum last_clip_origin = 0;
-    if (!g_IsGLES && /*g_GlVersion >= 450*/ (glad_glClipControl || glad_glClipControlEXT)) {
-        glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
-        if (last_clip_origin == GL_UPPER_LEFT)
-            clip_origin_lower_left = false;
-    }
-
-    // Setup viewport, orthographic projection matrix
-    // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
-    glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
-    float L = draw_data->DisplayPos.x;
-    float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
-    float T = draw_data->DisplayPos.y;
-    float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
-    if (!params.gl_dont_flip && !clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
-    const float ortho_projection[4][4] =
-    {
-        { 2.0f/(R-L),   0.0f,         0.0f,   0.0f },
-        { 0.0f,         2.0f/(T-B),   0.0f,   0.0f },
-        { 0.0f,         0.0f,        -1.0f,   0.0f },
-        { (R+L)/(L-R),  (T+B)/(B-T),  0.0f,   1.0f },
-    };
-    glUseProgram(g_ShaderHandle);
-    glUniform1i(g_AttribLocationTex, 0);
-    glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
-
-    if (g_GlVersion >= 330)
-        glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
-
-    (void)vertex_array_object;
-    //#ifndef IMGUI_IMPL_OPENGL_ES2
-    if (g_GlVersion >= 300)
-        glBindVertexArray(vertex_array_object);
-
-    // Bind vertex/index buffers and setup attributes for ImDrawVert
-    glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
-    glEnableVertexAttribArray(g_AttribLocationVtxPos);
-    glEnableVertexAttribArray(g_AttribLocationVtxUV);
-    glEnableVertexAttribArray(g_AttribLocationVtxColor);
-    glVertexAttribPointer(g_AttribLocationVtxPos,   2, GL_FLOAT,         GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
-    glVertexAttribPointer(g_AttribLocationVtxUV,    2, GL_FLOAT,         GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
-    glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE,  sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
-}
-
-// OpenGL3 Render function.
-// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
-// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
-void    ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
-{
-    // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
-    int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
-    int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
-    if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0)
-        return;
-
-    // Backup GL state
-    GLint last_fb = -1;
-    if (params.gl_bind_framebuffer >= 0 && (g_IsGLES || g_GlVersion >= 300))
-        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
-    GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
-    glActiveTexture(GL_TEXTURE0);
-    GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
-    GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
-
-    // GL_SAMPLER_BINDING
-    GLint last_sampler;
-    if (!g_IsGLES && g_GlVersion >= 330)
-        glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
-
-    GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
-
-//#ifndef IMGUI_IMPL_OPENGL_ES2
-    GLint last_vertex_array_object;
-    if (g_GlVersion >= 300)
-        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
-
-    GLint last_polygon_mode[2];
-    if (!g_IsGLES && g_GlVersion >= 200)
-        glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
-
-    GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
-    GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
-    GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
-    GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
-    GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
-    GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
-    GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
-    GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
-    GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
-    GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
-    GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
-    GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
-    GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
-    // Disable and store SRGB state.
-    GLboolean last_srgb_enabled = glIsEnabled(GL_FRAMEBUFFER_SRGB);
-    GLboolean last_enable_primitive_restart = (!g_IsGLES && g_GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
-
-    // Setup desired GL state
-    // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
-    // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
-    GLuint vertex_array_object = 0;
-    if (g_GlVersion >= 300)
-        glGenVertexArrays(1, &vertex_array_object);
-
-    ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
-
-    // Will project scissor/clipping rectangles into framebuffer space
-    ImVec2 clip_off = draw_data->DisplayPos;         // (0,0) unless using multi-viewports
-    ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
-
-    // Render command lists
-    for (int n = 0; n < draw_data->CmdListsCount; n++)
-    {
-        const ImDrawList* cmd_list = draw_data->CmdLists[n];
-
-        // Upload vertex/index buffers
-        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
-        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
-
-        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
-        {
-            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
-            if (pcmd->UserCallback != NULL)
-            {
-                // User callback, registered via ImDrawList::AddCallback()
-                // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
-                if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
-                    ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
-                else
-                    pcmd->UserCallback(cmd_list, pcmd);
-            }
-            else
-            {
-                // Project scissor/clipping rectangles into framebuffer space
-                ImVec4 clip_rect;
-                clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
-                clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
-                clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
-                clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
-
-                if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
-                {
-                    // Apply scissor/clipping rectangle
-                    if (!params.gl_dont_flip)
-                        glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
-                    else
-                        glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w);
-
-                    // Bind texture, Draw
-                    glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
-                    //#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
-                    if (g_GlVersion >= 320) // OGL and OGL ES
-                        glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
-                    else
-                        glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
-                }
-            }
-        }
-    }
-
-    // Destroy the temporary VAO
-    if (g_GlVersion >= 300)
-        glDeleteVertexArrays(1, &vertex_array_object);
-
-    // Restore modified GL state
-    glUseProgram(last_program);
-    glBindTexture(GL_TEXTURE_2D, last_texture);
-
-    if (!g_IsGLES && g_GlVersion >= 330)
-        glBindSampler(0, last_sampler);
-
-    glActiveTexture(last_active_texture);
-
-    if (g_GlVersion >= 300)
-        glBindVertexArray(last_vertex_array_object);
-
-    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
-    glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
-    glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
-    if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
-    if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
-    if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
-    if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
-    if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
-    if (!g_IsGLES && g_GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); }
-
-    if (!g_IsGLES && g_GlVersion >= 200)
-        glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
-
-    glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
-    glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
-
-    if (last_srgb_enabled)
-        glEnable(GL_FRAMEBUFFER_SRGB);
-    if (last_fb >= 0)
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, last_fb);
-}
-
-}} // namespace
diff -pruN 0.6.7.1-1/src/gl/imgui_impl_opengl3.h 0.6.8-1/src/gl/imgui_impl_opengl3.h
--- 0.6.7.1-1/src/gl/imgui_impl_opengl3.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gl/imgui_impl_opengl3.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
-// - Desktop GL: 2.x 3.x 4.x
-// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
-// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
-
-// Implemented features:
-//  [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
-//  [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
-
-// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
-// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
-// https://github.com/ocornut/imgui
-
-// About Desktop OpenGL function loaders:
-//  Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
-//  Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
-//  You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
-
-// About GLSL version:
-//  The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string.
-//  On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
-//  Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
-
-#pragma once
-#ifndef MANGOHUD_IMGUI_IMPL_OPENGL3_H
-#define MANGOHUD_IMGUI_IMPL_OPENGL3_H
-
-namespace MangoHud { namespace GL {
-
-void GetOpenGLVersion(int& major, int& minor, bool& isGLES);
-
-// Backend API
-IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
-IMGUI_IMPL_API void     ImGui_ImplOpenGL3_Shutdown();
-IMGUI_IMPL_API void     ImGui_ImplOpenGL3_NewFrame();
-IMGUI_IMPL_API void     ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
-IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_CreateFontsTexture();
-
-// (Optional) Called by Init/NewFrame/Shutdown
-//IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_CreateFontsTexture();
-//IMGUI_IMPL_API void     ImGui_ImplOpenGL3_DestroyFontsTexture();
-//IMGUI_IMPL_API bool     ImGui_ImplOpenGL3_CreateDeviceObjects();
-//IMGUI_IMPL_API void     ImGui_ImplOpenGL3_DestroyDeviceObjects();
-
-}}
-
-#endif //MANGOHUD_IMGUI_IMPL_OPENGL3_H
diff -pruN 0.6.7.1-1/src/gl/inject_egl.cpp 0.6.8-1/src/gl/inject_egl.cpp
--- 0.6.7.1-1/src/gl/inject_egl.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gl/inject_egl.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -9,7 +9,7 @@
 #include "mesa/util/macros.h"
 #include "mesa/util/os_time.h"
 #include "blacklist.h"
-#include "imgui_hud.h"
+#include "gl_hud.h"
 
 using namespace MangoHud::GL;
 
diff -pruN 0.6.7.1-1/src/gl/inject_glx.cpp 0.6.8-1/src/gl/inject_glx.cpp
--- 0.6.7.1-1/src/gl/inject_glx.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gl/inject_glx.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -18,7 +18,7 @@
 #include <iomanip>
 
 #include <glad/glad.h>
-#include "imgui_hud.h"
+#include "gl_hud.h"
 
 using namespace MangoHud::GL;
 
diff -pruN 0.6.7.1-1/src/gpu.cpp 0.6.8-1/src/gpu.cpp
--- 0.6.7.1-1/src/gpu.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gpu.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -17,7 +17,6 @@ using namespace std::chrono_literals;
 
 struct gpuInfo gpu_info {};
 amdgpu_files amdgpu {};
-decltype(&getAmdGpuInfo) getAmdGpuInfo_actual = nullptr;
 
 bool checkNvidia(const char *pci_dev){
     bool nvSuccess = false;
diff -pruN 0.6.7.1-1/src/gpu.h 0.6.8-1/src/gpu.h
--- 0.6.7.1-1/src/gpu.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/gpu.h	2022-08-01 01:27:11.000000000 +0000
@@ -42,7 +42,6 @@ extern struct gpuInfo gpu_info;
 
 void getNvidiaGpuInfo(const struct overlay_params& params);
 void getAmdGpuInfo(void);
-extern decltype(&getAmdGpuInfo) getAmdGpuInfo_actual;
 bool checkNvidia(const char *pci_dev);
 extern void nvapi_util();
 extern bool checkNVAPI();
diff -pruN 0.6.7.1-1/src/hud_elements.cpp 0.6.8-1/src/hud_elements.cpp
--- 0.6.7.1-1/src/hud_elements.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/hud_elements.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -21,6 +21,8 @@
 #define CHAR_CELSIUS    "\xe2\x84\x83"
 #define CHAR_FAHRENHEIT "\xe2\x84\x89"
 
+using namespace std;
+
 // Cut from https://github.com/ocornut/imgui/pull/2943
 // Probably move to ImGui
 float SRGBToLinear(float in)
@@ -120,6 +122,26 @@ void HudElements::convert_colors(bool do
     convert_colors(params);
 }
 
+/**
+* Go to next column or second column on new row
+*/
+void ImguiNextColumnOrNewRow(int column = -1)
+{
+    if (column > -1 && column < ImGui::TableGetColumnCount())
+        ImGui::TableSetColumnIndex(column);
+    else
+    {
+        ImGui::TableNextColumn();
+        if (ImGui::TableGetColumnIndex() == 0 && ImGui::TableGetColumnCount() > 1)
+            ImGui::TableNextColumn();
+    }
+}
+
+void ImGuiTableSetColumnIndex(int column)
+{
+    ImGui::TableSetColumnIndex(std::max(0, std::min(column, ImGui::TableGetColumnCount() - 1)));
+}
+
 void HudElements::time(){
     if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_time]){
         ImGui::TableNextRow(); ImGui::TableNextColumn();
@@ -167,16 +189,13 @@ void HudElements::gpu_stats(){
             // ImGui::Text("%s", "%");
         }
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_temp]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.temp);
             ImGui::SameLine(0, 1.0f);
             ImGui::Text("°C");
         }
-        if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_core_clock] || HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_power]){
-            ImGui::TableNextRow(); ImGui::TableNextColumn();
-        }
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_core_clock]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.CoreClock);
             ImGui::SameLine(0, 1.0f);
             ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -184,7 +203,7 @@ void HudElements::gpu_stats(){
             ImGui::PopFont();
         }
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_power]) {
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
 #ifdef MANGOAPP
             right_aligned_text(text_color, HUDElements.ralign_width, "%.1f", gpu_info.powerUsage);
 #else
@@ -232,24 +251,23 @@ void HudElements::cpu_stats(){
         }
 
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_temp]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().temp);
             ImGui::SameLine(0, 1.0f);
             ImGui::Text("°C");
         }
-        if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_mhz] || HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_power]){
-            ImGui::TableNextRow(); ImGui::TableNextColumn();
-        }
+
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_mhz]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().cpu_mhz);
             ImGui::SameLine(0, 1.0f);
             ImGui::PushFont(HUDElements.sw_stats->font1);
             ImGui::Text("MHz");
             ImGui::PopFont();
         }
+
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_power]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
         #ifdef MANGOAPP
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", cpuStats.GetCPUDataTotal().power);
         #else
@@ -288,13 +306,13 @@ void HudElements::core_load(){
                 right_aligned_text(load_color, HUDElements.ralign_width, "%d", cpu_load_percent);
                 ImGui::SameLine(0, 1.0f);
                 ImGui::TextColored(load_color, "%%");
-                ImGui::TableNextColumn();
+                ImguiNextColumnOrNewRow();
             }
             else {
                 right_aligned_text(text_color, HUDElements.ralign_width, "%i", int(cpuData.percent));
                 ImGui::SameLine(0, 1.0f);
                 ImGui::Text("%%");
-                ImGui::TableNextColumn();
+                ImguiNextColumnOrNewRow();
             }
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuData.mhz);
             ImGui::SameLine(0, 1.0f);
@@ -326,7 +344,7 @@ void HudElements::io_stats(){
             ImGui::PopFont();
         }
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_write]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             const float val = g_io_stats.per_second.write;
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, val < 100 ? "%.1f" : "%.f", val);
             ImGui::SameLine(0,1.0f);
@@ -354,7 +372,7 @@ void HudElements::vram(){
         ImGui::PopFont();
 #ifndef MANGOAPP
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_mem_clock]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", gpu_info.MemClock);
             ImGui::SameLine(0, 1.0f);
             ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -379,7 +397,7 @@ void HudElements::ram(){
     }
 
     if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram] && HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_swap]){
-        ImGui::TableNextColumn();
+        ImguiNextColumnOrNewRow();
         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", swapused);
         ImGui::SameLine(0,1.0f);
         ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -406,7 +424,7 @@ void HudElements::procmem()
     ImGui::PopFont();
 
     if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_shared]){
-        ImGui::TableNextColumn();
+        ImguiNextColumnOrNewRow();
         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.shared, unit));
         ImGui::SameLine(0,1.0f);
         ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -414,13 +432,8 @@ void HudElements::procmem()
         ImGui::PopFont();
     }
 
-    if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_shared] && HUDElements.params->table_columns < 4){
-        ImGui::TableNextRow();
-        ImGui::TableNextColumn();
-    }
-
     if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_virt]){
-        ImGui::TableNextColumn();
+        ImguiNextColumnOrNewRow();
         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.virt, unit));
         ImGui::SameLine(0,1.0f);
         ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -455,7 +468,7 @@ void HudElements::fps(){
         ImGui::Text("FPS");
         ImGui::PopFont();
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_frametime]){
-            ImGui::TableNextColumn();
+            ImguiNextColumnOrNewRow();
             right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", 1000 / HUDElements.sw_stats->fps);
             ImGui::SameLine(0, 1.0f);
             ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -470,8 +483,9 @@ void HudElements::fps(){
 
 void HudElements::fps_only(){
     if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_fps_only]){
+        ImGui::TableNextRow(); ImGui::TableNextColumn();
+        auto load_color = HUDElements.colors.text;
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_fps_color_change]){
-            ImGui::TableNextRow(); ImGui::TableNextColumn();
             int fps = int(HUDElements.sw_stats->fps);
             struct LOAD_DATA fps_data = {
             HUDElements.colors.fps_value_low,
@@ -480,13 +494,9 @@ void HudElements::fps_only(){
             HUDElements.params->fps_value[0],
             HUDElements.params->fps_value[1]
             };
-            auto load_color = change_on_load_temp(fps_data, fps);
-            ImGui::TextColored(load_color, "%.0f", HUDElements.sw_stats->fps);
-        }
-        else {
-            ImGui::TableNextRow(); ImGui::TableNextColumn();
-            ImGui::TextColored(HUDElements.colors.text, "%.0f", HUDElements.sw_stats->fps);
+            load_color = change_on_load_temp(fps_data, fps);
         }
+        ImGui::TextColored(load_color, "%.0f", HUDElements.sw_stats->fps);
     }
 }
 
@@ -563,11 +573,9 @@ void HudElements::frame_timing(){
         ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
         ImGui::PushFont(HUDElements.sw_stats->font1);
         ImGui::TextColored(HUDElements.colors.engine, "%s", "Frametime");
-        for (size_t i = 0; i < HUDElements.params->table_columns - 1; i++)
-            ImGui::TableNextColumn();
+        ImGui::TableSetColumnIndex(ImGui::TableGetColumnCount() - 1);
         ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
-        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "min: %.1fms, max: %.1fms", min_frametime, max_frametime);
-        ImGui::PopFont();
+        right_aligned_text(HUDElements.colors.text, ImGui::GetContentRegionAvail().x, "min: %.1fms, max: %.1fms", min_frametime, max_frametime);
         ImGui::TableNextRow(); ImGui::TableNextColumn();
         char hash[40];
         snprintf(hash, sizeof(hash), "##%s", overlay_param_names[OVERLAY_PARAM_ENABLED_frame_timing]);
@@ -576,28 +584,29 @@ void HudElements::frame_timing(){
         ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
         double min_time = 0.0f;
         double max_time = 50.0f;
+#ifdef MANGOAPP
+        const ImVec2 sz = ImGui::CalcTextSize("1000.0ms");
+        float width = ImGui::GetWindowContentRegionWidth() - sz.x;
+#else
+        float width = ImGui::GetWindowContentRegionWidth();
+#endif
         if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_histogram]){
             ImGui::PlotHistogram(hash, get_time_stat, HUDElements.sw_stats,
                                 ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
                                 NULL, min_time, max_time,
-                                ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns, 50));
+                                ImVec2(width, 50));
         } else {
-#ifdef MANGOAPP
-        int width = ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns - 30;
-#else
-        int width = ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns;
-#endif
             ImGui::PlotLines(hash, get_time_stat, HUDElements.sw_stats,
                             ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
                             NULL, min_time, max_time,
                             ImVec2(width, 50));
+        }
 #ifdef MANGOAPP
-            ImGui::SameLine();
-            ImGui::PushFont(HUDElements.sw_stats->font1);
-            ImGui::Text("%.1fms", frametime / 1000.f);
-            ImGui::PopFont();
+        ImGui::SameLine();
+        ImGuiTableSetColumnIndex(ImGui::TableGetColumnCount() - 1);
+        right_aligned_text(HUDElements.colors.text, ImGui::GetContentRegionAvail().x, "%.1fms", frametime / 1000.f);
 #endif
-        }
+        ImGui::PopFont();
         ImGui::PopStyleColor();
     }
 }
@@ -614,8 +623,11 @@ void HudElements::media_player(){
     scaled_font.Scale = HUDElements.params->font_scale_media_player;
     ImGui::PushFont(&scaled_font);
     {
-        std::lock_guard<std::mutex> lck(main_metadata.mtx);
-        render_mpris_metadata(*HUDElements.params, main_metadata, frame_timing);
+        std::unique_lock<std::mutex> lck(main_metadata.mtx, std::try_to_lock);
+        if (lck.owns_lock())
+            render_mpris_metadata(*HUDElements.params, main_metadata, frame_timing);
+        else
+            SPDLOG_DEBUG("failed to acquire lock");
     }
     ImGui::PopFont();
 #endif
@@ -624,12 +636,11 @@ void HudElements::media_player(){
 void HudElements::resolution(){
     if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_resolution]){
         ImGui::TableNextRow(); ImGui::TableNextColumn();
-        unsigned res_width  = ImGui::GetIO().DisplaySize.x;
-        unsigned res_height = ImGui::GetIO().DisplaySize.y;
+        const auto res  = ImGui::GetIO().DisplaySize;
         ImGui::PushFont(HUDElements.sw_stats->font1);
         ImGui::TextColored(HUDElements.colors.engine, "Resolution");
-        ImGui::TableNextColumn();
-        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "%ix%i", res_width, res_height);
+        ImGuiTableSetColumnIndex(HUDElements.text_column);
+        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "%.0fx%.0f", res.x, res.y);
         ImGui::PopFont();
     }
 }
@@ -642,7 +653,7 @@ void HudElements::show_fps_limit(){
         ImGui::TableNextRow(); ImGui::TableNextColumn();
         ImGui::PushFont(HUDElements.sw_stats->font1);
         ImGui::TextColored(HUDElements.colors.engine, "%s","FPS limit");
-        ImGui::TableNextColumn();
+        ImGuiTableSetColumnIndex(HUDElements.text_column);
         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", fps);
         ImGui::PopFont();
     }
@@ -682,7 +693,7 @@ void HudElements::gamemode(){
         ImGui::TableNextRow(); ImGui::TableNextColumn();
         ImGui::PushFont(HUDElements.sw_stats->font1);
         ImGui::TextColored(HUDElements.colors.engine, "%s", "GAMEMODE");
-        ImGui::TableNextColumn();
+        ImGuiTableSetColumnIndex(HUDElements.text_column);
         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", HUDElements.gamemode_bol ? "ON" : "OFF");
         ImGui::PopFont();
     }
@@ -693,7 +704,7 @@ void HudElements::vkbasalt(){
         ImGui::TableNextRow(); ImGui::TableNextColumn();
         ImGui::PushFont(HUDElements.sw_stats->font1);
         ImGui::TextColored(HUDElements.colors.engine, "%s", "VKBASALT");
-        ImGui::TableNextColumn();
+        ImGuiTableSetColumnIndex(HUDElements.text_column);
         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", HUDElements.vkbasalt_bol ? "ON" : "OFF");
         ImGui::PopFont();
     }
@@ -728,7 +739,7 @@ void HudElements::battery(){
                 ImGui::Text("%%");
             }
             if (Battery_Stats.current_watt != 0) {
-                ImGui::TableNextColumn();
+                ImguiNextColumnOrNewRow();
                 right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", Battery_Stats.current_watt);
                 ImGui::SameLine(0,1.0f);
                 ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -745,12 +756,12 @@ void HudElements::battery(){
                 ImGui::PushFont(HUDElements.sw_stats->font1);
                 ImGui::TextColored(HUDElements.colors.text, "%s", "Remaining Time");
                 ImGui::PopFont();
-                ImGui::TableNextColumn(); ImGui::TableNextColumn();
+                ImGuiTableSetColumnIndex(2);
                 // ImGui::TextColored(HUDElements.colors.text, "%02.0f:%02.0f:%02.0f", hours, minutes, seconds);
                 right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%02.0f:%02.0f", hours, minutes);
             }
             else {
-                ImGui::TableNextColumn();
+                ImguiNextColumnOrNewRow();
                 right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_PLUG);
             }
         }
@@ -775,9 +786,9 @@ void HudElements::gamescope_fsr(){
         ImGui::TextColored(HUDElements.colors.engine, "%s", "FSR");
         ImGui::TableNextColumn();
         right_aligned_text(FSR_COLOR, HUDElements.ralign_width, "%s", FSR_TEXT.c_str());
-        ImGui::TableNextColumn();
         if (g_fsrUpscale){
             if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_hide_fsr_sharpness]) {
+                ImguiNextColumnOrNewRow();
                 right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", g_fsrSharpness);
                 ImGui::SameLine(0,1.0f);
                 ImGui::PushFont(HUDElements.sw_stats->font1);
@@ -854,53 +865,52 @@ void HudElements::gamescope_frame_timing
 void HudElements::gamepad_battery()
 {
 #ifdef __linux__
-    gamepad_update();
-
-    if (gamepad_found) {
-        gamepad_info();
-        for (int i = 0; i < gamepad_count; i++) {
-            std::string battery = gamepad_data[i].battery;
-            std::string name = gamepad_data[i].name;
-            std::string battery_percent = gamepad_data[i].battery_percent;
-            bool report_percent = gamepad_data[i].report_percent;
-            bool charging = gamepad_data[i].is_charging;
+    if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery]) {
+        if (gamepad_found) {
+            for (int i = 0; i < gamepad_count; i++) {
+                std::string battery = gamepad_data[i].battery;
+                std::string name = gamepad_data[i].name;
+                std::string battery_percent = gamepad_data[i].battery_percent;
+                bool report_percent = gamepad_data[i].report_percent;
+                bool charging = gamepad_data[i].is_charging;
 
-            ImGui::TableNextRow(); ImGui::TableNextColumn();
-            ImGui::PushFont(HUDElements.sw_stats->font1);
-            ImGui::TextColored(HUDElements.colors.engine, "%s", name.c_str());
-            ImGui::TableNextColumn();
-            if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery_icon]) {
-                if (charging)
-                    right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
-                else {
-                    if (battery == "Full")
-                        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_FULL);
-                    else if (battery == "High")
-                        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_THREE_QUARTERS);
-                    else if (battery == "Normal")
-                        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_HALF);
-                    else if (battery == "Low")
-                        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_QUARTER);
-                    else if (battery == "Unknown")
+                ImGui::TableNextRow(); ImGui::TableNextColumn();
+                ImGui::PushFont(HUDElements.sw_stats->font1);
+                ImGui::TextColored(HUDElements.colors.engine, "%s", name.c_str());
+                ImGui::TableNextColumn();
+                if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery_icon]) {
+                    if (charging)
                         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
-                }
-            }
-            else {
-                if (charging)
-                    right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
-                else if (report_percent) {
-                    right_aligned_text(HUDElements.colors.text,HUDElements.ralign_width, "%s", battery_percent.c_str());
-                    ImGui::SameLine(0,1.0f);
-                    ImGui::Text("%%");
+                    else {
+                        if (battery == "Full")
+                            right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_FULL);
+                        else if (battery == "High")
+                            right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_THREE_QUARTERS);
+                        else if (battery == "Normal")
+                            right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_HALF);
+                        else if (battery == "Low")
+                            right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_QUARTER);
+                        else if (battery == "Unknown")
+                            right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
+                    }
                 }
                 else {
-                    if (battery == "Unknown")
+                    if (charging)
                         right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
-                    else
-                        right_aligned_text(HUDElements.colors.text,HUDElements.ralign_width, "%s", battery.c_str());
+                    else if (report_percent) {
+                        right_aligned_text(HUDElements.colors.text,HUDElements.ralign_width, "%s", battery_percent.c_str());
+                        ImGui::SameLine(0,1.0f);
+                        ImGui::Text("%%");
+                    }
+                    else {
+                        if (battery == "Unknown")
+                            right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
+                        else
+                            right_aligned_text(HUDElements.colors.text,HUDElements.ralign_width, "%s", battery.c_str());
+                    }
                 }
+                ImGui::PopFont();
             }
-            ImGui::PopFont();
         }
     }
 #endif
@@ -912,8 +922,8 @@ void HudElements::frame_count(){
         ImGui::TableNextColumn();
         ImGui::PushFont(HUDElements.sw_stats->font1);
         ImGui::TextColored(HUDElements.colors.engine, "Frame Count");
-        ImGui::TableNextColumn();
-        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%llu", HUDElements.sw_stats->n_frames);
+        ImGuiTableSetColumnIndex(HUDElements.text_column);
+        right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%" PRIu64, HUDElements.sw_stats->n_frames);
         ImGui::PopFont();
     }
 }
@@ -1054,12 +1064,12 @@ void HudElements::graphs(){
         ImGui::PlotLines("", arr.data(),
                 arr.size(), 0,
                 NULL, HUDElements.min, HUDElements.max,
-                ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns, 50));
+                ImVec2(ImGui::GetWindowContentRegionWidth(), 50));
     } else {
         ImGui::PlotHistogram("", arr.data(),
-        arr.size(), 0,
-        NULL, HUDElements.min, HUDElements.max,
-        ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns, 50));
+            arr.size(), 0,
+            NULL, HUDElements.min, HUDElements.max,
+            ImVec2(ImGui::GetWindowContentRegionWidth(), 50));
     }
     ImGui::Dummy(ImVec2(0.0f,5.0f));
     ImGui::PopStyleColor(1);
diff -pruN 0.6.7.1-1/src/hud_elements.h 0.6.8-1/src/hud_elements.h
--- 0.6.7.1-1/src/hud_elements.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/hud_elements.h	2022-08-01 01:27:11.000000000 +0000
@@ -20,6 +20,7 @@ class HudElements{
         float res_width, res_height;
         bool is_vulkan, gamemode_bol = false, vkbasalt_bol = false;
         int place;
+        int text_column = 1;
         Clock::time_point last_exec;
         std::vector<std::pair<std::string, std::string>> options;
         std::vector<std::pair<void(*)(), std::string >> ordered_functions;
diff -pruN 0.6.7.1-1/src/keybinds.cpp 0.6.8-1/src/keybinds.cpp
--- 0.6.7.1-1/src/keybinds.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/keybinds.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -26,7 +26,6 @@ void check_keybinds(struct overlay_param
          logger->stop_logging();
       } else {
          logger->start_logging();
-         std::thread(update_hw_info, std::ref(params), vendorID).detach();
          benchmark.fps_data.clear();
       }
    }
diff -pruN 0.6.7.1-1/src/logging.cpp 0.6.8-1/src/logging.cpp
--- 0.6.7.1-1/src/logging.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/logging.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -7,6 +7,8 @@
 #include "file_utils.h"
 #include "string_utils.h"
 
+using namespace std;
+
 string os, cpu, gpu, ram, kernel, driver, cpusched;
 bool sysInfoFetched = false;
 double fps;
@@ -60,8 +62,8 @@ void writeSummary(string filename){
   auto& logArray = logger->get_log_data();
   filename = filename.substr(0, filename.size() - 4);
   filename += "_summary.csv";
-  printf("%s\n", filename.c_str());
-  SPDLOG_DEBUG("Writing summary log file [{}]", filename, logArray.size());
+  SPDLOG_INFO("{}", filename);
+  SPDLOG_DEBUG("Writing summary log file [{}]", filename);
   std::ofstream out(filename, ios::out | ios::app);
   if (out){
     out << "0.1% Min FPS," << "1% Min FPS," << "97% Percentile FPS," << "Average FPS," << "GPU Load," << "CPU Load" << "\n";
@@ -100,8 +102,9 @@ void writeSummary(string filename){
     result = total_cpu / sorted.size();
     out << result;
   } else {
-    printf("MANGOHUD: Failed to write log file\n");
+    SPDLOG_ERROR("Failed to write log file");
   }
+  out.close();
 }
 
 void writeFile(string filename){
@@ -109,27 +112,39 @@ void writeFile(string filename){
   SPDLOG_DEBUG("Writing log file [{}], {} entries", filename, logArray.size());
   std::ofstream out(filename, ios::out | ios::app);
   if (out){
-  out << "os," << "cpu," << "gpu," << "ram," << "kernel," << "driver," << "cpuscheduler" << endl;
-  out << os << "," << cpu << "," << gpu << "," << ram << "," << kernel << "," << driver << "," << cpusched << endl;
-  out << "fps," << "frametime," << "cpu_load," << "gpu_load," << "cpu_temp," << "gpu_temp," << "gpu_core_clock," << "gpu_mem_clock," << "gpu_vram_used," << "gpu_power," << "ram_used," << "elapsed" << endl;
-
-  for (size_t i = 0; i < logArray.size(); i++){
-    out << logArray[i].fps << ",";
-    out << logArray[i].frametime << ",";
-    out << logArray[i].cpu_load << ",";
-    out << logArray[i].gpu_load << ",";
-    out << logArray[i].cpu_temp << ",";
-    out << logArray[i].gpu_temp << ",";
-    out << logArray[i].gpu_core_clock << ",";
-    out << logArray[i].gpu_mem_clock << ",";
-    out << logArray[i].gpu_vram_used << ",";
-    out << logArray[i].gpu_power << ",";
-    out << logArray[i].ram_used << ",";
-    out << std::chrono::duration_cast<std::chrono::nanoseconds>(logArray[i].previous).count() << "\n";
-  }
+    if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_log_versioning]){
+      printf("log versioning");
+      out << "v1" << endl;
+      out << MANGOHUD_VERSION << endl;
+      out << "---------------------SYSTEM INFO---------------------" << endl;
+    }
+
+    out << "os," << "cpu," << "gpu," << "ram," << "kernel," << "driver," << "cpuscheduler" << endl;
+    out << os << "," << cpu << "," << gpu << "," << ram << "," << kernel << "," << driver << "," << cpusched << endl;
+
+    if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_log_versioning])
+      out << "--------------------FRAME METRICS--------------------" << endl;
+
+    out << "fps," << "frametime," << "cpu_load," << "gpu_load," << "cpu_temp," << "gpu_temp," << "gpu_core_clock," << "gpu_mem_clock," << "gpu_vram_used," << "gpu_power," << "ram_used," << "elapsed" << endl;
+
+    for (size_t i = 0; i < logArray.size(); i++){
+      out << logArray[i].fps << ",";
+      out << logArray[i].frametime << ",";
+      out << logArray[i].cpu_load << ",";
+      out << logArray[i].gpu_load << ",";
+      out << logArray[i].cpu_temp << ",";
+      out << logArray[i].gpu_temp << ",";
+      out << logArray[i].gpu_core_clock << ",";
+      out << logArray[i].gpu_mem_clock << ",";
+      out << logArray[i].gpu_vram_used << ",";
+      out << logArray[i].gpu_power << ",";
+      out << logArray[i].ram_used << ",";
+      out << std::chrono::duration_cast<std::chrono::nanoseconds>(logArray[i].previous).count() << "\n";
+    }
   } else {
-    printf("MANGOHUD: Failed to write log file\n");
+    SPDLOG_ERROR("Failed to write log file");
   }
+  out.close();
 }
 
 string get_log_suffix(){
@@ -142,7 +157,9 @@ string get_log_suffix(){
 }
 
 Logger::Logger(const overlay_params* in_params)
-  : m_params(in_params),
+  : output_folder(in_params->output_folder),
+	log_interval(in_params->log_interval),
+	log_duration(in_params->log_duration),
     m_logging_on(false),
     m_values_valid(false)
 {
@@ -155,7 +172,7 @@ void Logger::start_logging() {
   m_values_valid = false;
   m_logging_on = true;
   m_log_start = Clock::now();
-  if(m_params->log_interval != 0){
+  if(log_interval != 0){
     std::thread(&Logger::logging, this).detach();
   }
 }
@@ -167,11 +184,11 @@ void Logger::stop_logging() {
 
   calculate_benchmark_data();
 
-  if(!m_params->output_folder.empty()) {
+  if(!output_folder.empty()) {
     std::string program = get_wine_exe_name();
     if (program.empty())
         program = get_program_name();
-    m_log_files.emplace_back(m_params->output_folder + "/" + program + "_" + get_log_suffix());
+    m_log_files.emplace_back(output_folder + "/" + program + "_" + get_log_suffix());
     std::thread writefile (writeFile, m_log_files.back());
     std::thread writesummary (writeSummary, m_log_files.back());
     writefile.join();
@@ -185,13 +202,16 @@ void Logger::stop_logging() {
 #endif
   }
   clear_log_data();
+  control_client_check(HUDElements.params->control, global_control_client, gpu.c_str());
+  const char * cmd = "LoggingFinished";
+  control_send(global_control_client, cmd, strlen(cmd), 0, 0);
 }
 
 void Logger::logging(){
   wait_until_data_valid();
   while (is_active()){
       try_log();
-      this_thread::sleep_for(chrono::milliseconds(m_params->log_interval));
+      this_thread::sleep_for(std::chrono::milliseconds(log_interval));
   }
 }
 
@@ -206,7 +226,7 @@ void Logger::try_log() {
   currentLogData.frametime = frametime;
   m_log_array.push_back(currentLogData);
 
-  if(m_params->log_duration && (elapsedLog >= std::chrono::seconds(m_params->log_duration))){
+  if(log_duration && (elapsedLog >= std::chrono::seconds(log_duration))){
     stop_logging();
   }
 }
@@ -253,7 +273,7 @@ void Logger::calculate_benchmark_data(){
   size_t max_label_size = 0;
 
   float result;
-  for (std::string percentile : m_params->benchmark_percentiles) {
+  for (std::string percentile : HUDElements.params->benchmark_percentiles) {
       // special case handling for a mean-based average
       if (percentile == "AVG") {
         result = benchmark.total / sorted.size();
diff -pruN 0.6.7.1-1/src/logging.h 0.6.8-1/src/logging.h
--- 0.6.7.1-1/src/logging.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/logging.h	2022-08-01 01:27:11.000000000 +0000
@@ -13,7 +13,6 @@
 
 #include "overlay_params.h"
 
-using namespace std;
 struct logData{
   double fps;
   uint64_t frametime;
@@ -54,7 +53,9 @@ public:
   void upload_last_log();
   void upload_last_logs();
   void calculate_benchmark_data();
-  const overlay_params* m_params;
+  const std::string output_folder;
+  const int64_t log_interval;
+  const int64_t log_duration;
 
 private:
   std::vector<logData> m_log_array;
@@ -70,13 +71,13 @@ private:
 
 extern std::unique_ptr<Logger> logger;
 
-extern string os, cpu, gpu, ram, kernel, driver, cpusched;
+extern std::string os, cpu, gpu, ram, kernel, driver, cpusched;
 extern bool sysInfoFetched;
 extern double fps;
 extern uint64_t frametime;
 extern logData currentLogData;
 
-string exec(string command);
+std::string exec(std::string command);
 void autostart_log(int sleep);
 
 #endif //MANGOHUD_LOGGING_H
diff -pruN 0.6.7.1-1/src/mangohud.json.in 0.6.8-1/src/mangohud.json.in
--- 0.6.7.1-1/src/mangohud.json.in	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/mangohud.json.in	2022-08-01 01:27:11.000000000 +0000
@@ -3,7 +3,7 @@
     "layer" : {
       "name": "VK_LAYER_@PROJECT_NAME@_overlay",
       "type": "GLOBAL",
-      "api_version": "1.2.135",
+      "api_version": "1.3.0",
       "library_path": "@ld_libdir_mangohud@libMangoHud.so",
       "implementation_version": "1",
       "description": "Vulkan Hud Overlay",
diff -pruN 0.6.7.1-1/src/meson.build 0.6.8-1/src/meson.build
--- 0.6.7.1-1/src/meson.build	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/meson.build	2022-08-01 01:27:11.000000000 +0000
@@ -87,8 +87,8 @@ if is_unixy
 
   opengl_files = files(
     'gl/glad.c',
-    'gl/imgui_impl_opengl3.cpp',
-    'gl/imgui_hud.cpp',
+    'gl/gl_renderer.cpp',
+    'gl/gl_hud.cpp',
     'gl/inject_egl.cpp',
   )
 
@@ -100,7 +100,7 @@ if is_unixy
   if get_option('with_nvml') == 'system'
     nvml_h_found = cc.has_header('nvml.h')
     if not nvml_h_found
-      error('nvml.h was not found. Disable with \'-Dwith_nvml=disabled\' if gpu stats by NVML is not needed.')
+      error('nvml.h was not found. Disable with \'-Dwith_nvml=disabled\' if gpu stats by NVML are not needed.')
     endif
     pre_args += '-DUSE_SYSTEM_NVML'
   endif
@@ -121,7 +121,7 @@ if is_unixy
 
     xnvctrl_h_found = cc.has_header('NVCtrl/NVCtrl.h')
     if not xnvctrl_h_found
-      error('NVCtrl.h was not found. Disable with \'-Dwith_xnvctrl=disabled\' if gpu stats by XNVCtrl is not needed.')
+      error('NVCtrl.h was not found. Disable with \'-Dwith_xnvctrl=disabled\' if gpu stats by XNVCtrl are not needed.')
     endif
 
     pre_args += '-DHAVE_XNVCTRL'
@@ -248,6 +248,7 @@ if get_option('mangoapp') and sizeof_ptr
       json_dep,
     ],
     include_directories : [inc_common],
+    install_tag : 'mangoapp',
     link_args : link_args,
     install : true
   )
@@ -257,6 +258,7 @@ if get_option('mangohudctl') and sizeof_
 mangoapp = executable(
   'mangohudctl',
   files('app/control.cpp'),
+  install_tag : 'mangoapp', #TODO MangoHud layer itself currently doesn't support it
   install : true
 )
 endif
@@ -282,35 +284,32 @@ if get_option('mangoapp_layer')
     gnu_symbol_visibility : 'hidden',
     include_directories : [inc_common],
     link_args : link_args,
+    install_tag : 'mangoapp',
+    install_dir : libdir_mangohud,
     install : true
   )
 endif
 
 configure_file(input : 'mangohud.json.in',
   output : '@0@.json'.format(meson.project_name()),
-  configuration : {'ld_libdir_mangohud' : ld_libdir_mangohud_vk,
+  configuration : {'ld_libdir_mangohud' : ld_libdir_mangohud_vk.replace('\$', '$'),
                   'PROJECT_NAME' : meson.project_name().to_upper()},
   install : true,
   install_dir : join_paths(get_option('datadir'), 'vulkan', 'implicit_layer.d'),
+  install_tag : 'runtime',
 )
 
 configure_file(input : '../bin/mangohud.in',
   output : 'mangohud',
   configuration : conf_data,
   install_dir : get_option('bindir'),
+  install_tag : 'scripts',
 )
 
-if get_option('include_doc')
-  install_data(
-    files('../bin/MangoHud.conf'),
-    install_dir : join_paths(get_option('datadir'), 'doc', 'mangohud'),
-    rename : ['MangoHud.conf.example']
-  )
-endif
-
 configure_file(input : 'app/layer.json.in',
   output : 'libMangoApp.json',
-  configuration : {'ld_libdir_mangohud' : ld_libdir_mangohud_vk},
+  configuration : {'ld_libdir_mangohud' : ld_libdir_mangohud_vk.replace('\$', '$')},
   install : true,
   install_dir : join_paths(get_option('datadir'), 'vulkan', 'implicit_layer.d'),
+  install_tag : 'mangoapp',
 )
diff -pruN 0.6.7.1-1/src/overlay.cpp 0.6.8-1/src/overlay.cpp
--- 0.6.7.1-1/src/overlay.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/overlay.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -14,8 +14,10 @@
 #include "gpu.h"
 #include "memory.h"
 #include "timing.hpp"
+#include "fcat.h"
 #include "mesa/util/macros.h"
 #include "battery.h"
+#include "gamepad.h"
 #include "string_utils.h"
 #include "file_utils.h"
 #include "pci_ids.h"
@@ -29,14 +31,16 @@
 #endif
 
 namespace fs = ghc::filesystem;
+using namespace std;
 
 #ifdef HAVE_DBUS
 float g_overflow = 50.f /* 3333ms * 0.5 / 16.6667 / 2 (to edge and back) */;
 #endif
 
 string gpuString,wineVersion,wineProcess;
-int32_t deviceID;
+uint32_t deviceID;
 bool gui_open = false;
+bool fcat_open = false;
 struct benchmark_stats benchmark;
 struct fps_limit fps_limit_stats {};
 ImVec2 real_font_size;
@@ -48,6 +52,7 @@ bool gpu_metrics_exists = false;
 bool steam_focused = false;
 vector<float> frametime_data(200,0.f);
 int fan_speed;
+fcatoverlay fcatstatus;
 
 void init_spdlog()
 {
@@ -72,6 +77,20 @@ void init_spdlog()
    spdlog::set_level(spdlog::level::level_enum::debug);
 #endif
    spdlog::cfg::load_env_levels();
+
+   // Use MANGOHUD_LOG_LEVEL to correspond to SPDLOG_LEVEL
+   if (getenv("MANGOHUD_LOG_LEVEL")) {
+      std::string log_level = getenv("MANGOHUD_LOG_LEVEL");
+      vector<string> levels;
+      levels = {"off","info","err","debug"};
+      for (auto & element : levels) {
+         transform(log_level.begin(), log_level.end(), log_level.begin(), ::tolower);
+         if(log_level == element ) {
+            spdlog::set_level(spdlog::level::from_str(log_level));
+         }
+      }
+   }
+
 }
 
 void FpsLimiter(struct fps_limit& stats){
@@ -101,8 +120,8 @@ void update_hw_info(const struct overlay
 #endif
    }
    if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] || logger->is_active()) {
-      if (vendorID == 0x1002 && getAmdGpuInfo_actual)
-         getAmdGpuInfo_actual();
+      if (vendorID == 0x1002)
+         getAmdGpuInfo();
 
       if (gpu_metrics_exists)
          amdgpu_get_metrics();
@@ -114,6 +133,12 @@ void update_hw_info(const struct overlay
 #ifdef __linux__
    if (params.enabled[OVERLAY_PARAM_ENABLED_battery])
       Battery_Stats.update();
+   if (params.enabled[OVERLAY_PARAM_ENABLED_gamepad_battery]) {
+      gamepad_update();
+      if (gamepad_found) {
+            gamepad_info();
+      }
+   }
    if (params.enabled[OVERLAY_PARAM_ENABLED_ram] || params.enabled[OVERLAY_PARAM_ENABLED_swap] || logger->is_active())
       update_meminfo();
    if (params.enabled[OVERLAY_PARAM_ENABLED_procmem])
@@ -138,7 +163,7 @@ void update_hw_info(const struct overlay
    if (graph_data.size() >= kMaxGraphEntries)
       graph_data.pop_front();
    graph_data.push_back(currentLogData);
-   logger->notify_data_valid();
+   if (logger) logger->notify_data_valid();
    HUDElements.update_exec();
 }
 
@@ -274,6 +299,18 @@ float get_time_stat(void *_data, int _id
    return data->frames_stats[idx].stats[data->stat_selector] / data->time_dividor;
 }
 
+void overlay_new_frame(const struct overlay_params& params)
+{
+   ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
+   ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8,-3));
+   ImGui::PushStyleVar(ImGuiStyleVar_Alpha, params.alpha);
+}
+
+void overlay_end_frame()
+{
+   ImGui::PopStyleVar(3);
+}
+
 void position_layer(struct swapchain_stats& data, const struct overlay_params& params, const ImVec2& window_size)
 {
    unsigned width = ImGui::GetIO().DisplaySize.x;
@@ -284,9 +321,6 @@ void position_layer(struct swapchain_sta
 
    ImGui::SetNextWindowBgAlpha(params.background_alpha);
    ImGui::SetNextWindowSize(window_size, ImGuiCond_Always);
-   ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
-   ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8,-3));
-   ImGui::PushStyleVar(ImGuiStyleVar_Alpha, params.alpha);
    switch (params.position) {
    case LAYER_POSITION_TOP_LEFT:
       data.main_window_pos = ImVec2(margin + params.offset_x, margin + params.offset_y);
@@ -537,13 +571,14 @@ void render_imgui(swapchain_stats& data,
 
    if (!params.no_display && !steam_focused){
       ImGui::Begin("Main", &gui_open, ImGuiWindowFlags_NoDecoration);
-      ImGui::BeginTable("hud", params.table_columns, ImGuiTableFlags_NoClip);
-      HUDElements.place = 0;
-      for (auto& func : HUDElements.ordered_functions){
-         func.first();
-         HUDElements.place += 1;
+      if (ImGui::BeginTable("hud", params.table_columns, ImGuiTableFlags_NoClip)) {
+         HUDElements.place = 0;
+         for (auto& func : HUDElements.ordered_functions){
+            func.first();
+            HUDElements.place += 1;
+         }
+         ImGui::EndTable();
       }
-      ImGui::EndTable();
 
       if(logger->is_active())
          ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(data.main_window_pos.x + window_size.x - 15, data.main_window_pos.y + 15), 10, params.engine_color, 20);
@@ -552,6 +587,22 @@ void render_imgui(swapchain_stats& data,
       if((now - logger->last_log_end()) < 12s && !logger->is_active())
          render_benchmark(data, params, window_size, height, now);
    }
+
+   if(params.enabled[OVERLAY_PARAM_ENABLED_fcat])
+     {
+       fcatstatus.update(&params);
+       auto window_corners = fcatstatus.get_overlay_corners();
+       auto p_min=window_corners[0];
+       auto p_max=window_corners[1];
+       auto window_size= window_corners[2];
+       ImGui::SetNextWindowPos(p_min, ImGuiCond_Always);
+       ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0));
+       ImGui::SetNextWindowSize(window_size);
+       ImGui::Begin("FCAT", &fcat_open, ImGuiWindowFlags_NoDecoration| ImGuiWindowFlags_NoBackground);
+       ImGui::GetWindowDrawList()->AddRectFilled(p_min,p_max,fcatstatus.get_next_color(data),0.0);
+       ImGui::End();
+       ImGui::PopStyleVar();
+     }
 }
 
 void init_cpu_stats(overlay_params& params)
@@ -624,23 +675,31 @@ void init_gpu_stats(uint32_t& vendorID,
        || gpu.find("AMD") != std::string::npos) {
       string path;
       string drm = "/sys/class/drm/";
-      getAmdGpuInfo_actual = getAmdGpuInfo;
 
       auto dirs = ls(drm.c_str(), "card");
       for (auto& dir : dirs) {
          path = drm + dir;
 
-         SPDLOG_DEBUG("amdgpu path check: {}/device/vendor", path);
+         SPDLOG_DEBUG("amdgpu path check: {}", path);
+         if (pci_bus_parsed && pci_dev) {
+            string pci_device = read_symlink((path + "/device").c_str());
+            SPDLOG_DEBUG("PCI device symlink: '{}'", pci_device);
+            if (!ends_with(pci_device, pci_dev)) {
+               SPDLOG_DEBUG("skipping GPU, no PCI ID match");
+               continue;
+            }
+         }
+
          FILE *fp;
          string device = path + "/device/device";
          if ((fp = fopen(device.c_str(), "r"))){
             uint32_t temp = 0;
             if (fscanf(fp, "%x", &temp) == 1) {
-            // if (temp != reported_deviceID && deviceID != 0){
-            //    fclose(fp);
-            //    SPDLOG_DEBUG("DeviceID does not match vulkan report {}", reported_deviceID);
-            //    continue;
-            // }
+               if (!pci_bus_parsed && reported_deviceID && temp != reported_deviceID){
+                  fclose(fp);
+                  SPDLOG_DEBUG("DeviceID does not match vulkan report {:X}", reported_deviceID);
+                  continue;
+               }
                deviceID = temp;
             }
             fclose(fp);
@@ -656,15 +715,6 @@ void init_gpu_stats(uint32_t& vendorID,
             fclose(fp);
          }
 
-         if (pci_bus_parsed && pci_dev) {
-            string pci_device = read_symlink((path + "/device").c_str());
-            SPDLOG_DEBUG("PCI device symlink: '{}'", pci_device);
-            if (!ends_with(pci_device, pci_dev)) {
-               SPDLOG_DEBUG("skipping GPU, no PCI ID match");
-               continue;
-            }
-         }
-
          const std::string device_path = path + "/device";
          const std::string gpu_metrics_path = device_path + "/gpu_metrics";
          if (amdgpu_check_metrics(gpu_metrics_path)) {
@@ -780,7 +830,8 @@ void init_system_info(){
             if (wine_env)
                unsetenv("WINELOADERNOEXEC");
             wineVersion = exec(findVersion.str());
-            std::cout << "WINE VERSION = " << wineVersion << "\n";
+            trim(wineVersion);
+            SPDLOG_DEBUG("WINE version: {}", wineVersion);
             if (wine_env)
                setenv("WINELOADERNOEXEC", wine_env, 1);
          }
@@ -813,7 +864,7 @@ void init_system_info(){
 #endif
 }
 
-std::string get_device_name(int32_t vendorID, int32_t deviceID)
+std::string get_device_name(uint32_t vendorID, uint32_t deviceID)
 {
    string desc;
 #ifdef __linux__
@@ -845,7 +896,7 @@ void update_fan(){
          break;
       }
    }
-   
+
    if (!hwmon_path.empty())
       fan_speed = stoi(read_line(hwmon_path));
    else
diff -pruN 0.6.7.1-1/src/overlay.h 0.6.8-1/src/overlay.h
--- 0.6.7.1-1/src/overlay.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/overlay.h	2022-08-01 01:27:11.000000000 +0000
@@ -2,7 +2,6 @@
 #ifndef MANGOHUD_OVERLAY_H
 #define MANGOHUD_OVERLAY_H
 
-#ifndef MANGOAPP_LAYER
 #include <string>
 #include <stdint.h>
 #include <vector>
@@ -11,18 +10,13 @@
 #include "version.h"
 #include "overlay_params.h"
 #include "hud_elements.h"
+#include "engine_types.h"
 
 #ifdef HAVE_DBUS
 #include "dbus_info.h"
 extern float g_overflow;
 #endif
-#endif
 #include "logging.h"
-#include "notify.h"
-#include "vk_enum_to_str.h"
-#include <vulkan/vk_layer.h>
-
-using namespace std;
 
 struct frame_stat {
    uint64_t stats[OVERLAY_PLOTS_MAX];
@@ -30,27 +24,6 @@ struct frame_stat {
 
 static const int kMaxGraphEntries = 50;
 
-enum EngineTypes
-{
-   UNKNOWN,
-
-   OPENGL,
-   VULKAN,
-
-   DXVK,
-   VKD3D,
-   DAMAVAND,
-   ZINK,
-
-   WINED3D,
-   FERAL3D,
-   TOGL,
-
-   GAMESCOPE
-};
-
-extern const char* engines[];
-#ifndef MANGOAPP_LAYER
 struct swapchain_stats {
    uint64_t n_frames;
    enum overlay_plots stat_selector;
@@ -107,40 +80,9 @@ struct LOAD_DATA {
    unsigned med_load;
    unsigned high_load;
 };
-#endif
-/* Mapped from VkInstace/VkPhysicalDevice */
-struct instance_data {
-   struct vk_instance_dispatch_table vtable;
-   VkInstance instance;
-   struct overlay_params params;
-   uint32_t api_version;
-   string engineName, engineVersion;
-   enum EngineTypes engine;
-   notify_thread notifier;
-   int control_client;
-};
-
-/* Mapped from VkDevice */
-struct queue_data;
-struct device_data {
-   struct instance_data *instance;
-
-   PFN_vkSetDeviceLoaderData set_device_loader_data;
-
-   struct vk_device_dispatch_table vtable;
-   VkPhysicalDevice physical_device;
-   VkDevice device;
-
-   VkPhysicalDeviceProperties properties;
-
-   struct queue_data *graphic_queue;
-
-   std::vector<struct queue_data *> queues;
-};
 
-#ifndef MANGOAPP_LAYER
 extern struct fps_limit fps_limit_stats;
-extern int32_t deviceID;
+extern uint32_t deviceID;
 
 extern struct benchmark_stats benchmark;
 extern ImVec2 real_font_size;
@@ -152,6 +94,8 @@ extern bool steam_focused;
 extern int fan_speed;
 
 void init_spdlog();
+void overlay_new_frame(const struct overlay_params& params);
+void overlay_end_frame();
 void position_layer(struct swapchain_stats& data, const struct overlay_params& params, const ImVec2& window_size);
 void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, bool is_vulkan);
 void update_hud_info(struct swapchain_stats& sw_stats, const struct overlay_params& params, uint32_t vendorID);
@@ -162,19 +106,20 @@ void init_cpu_stats(overlay_params& para
 void check_keybinds(overlay_params& params, uint32_t vendorID);
 void init_system_info(void);
 void FpsLimiter(struct fps_limit& stats);
-std::string get_device_name(int32_t vendorID, int32_t deviceID);
-void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font);
+std::string get_device_name(uint32_t vendorID, uint32_t deviceID);
+void create_fonts(ImFontAtlas* font_atlas, const overlay_params& params, ImFont*& small_font, ImFont*& text_font);
 void right_aligned_text(ImVec4& col, float off_x, const char *fmt, ...);
 void center_text(const std::string& text);
 ImVec4 change_on_load_temp(LOAD_DATA& data, unsigned current);
 float get_time_stat(void *_data, int _idx);
 void stop_hw_updater();
-extern void control_client_check(struct device_data *device_data);
-extern void process_control_socket(struct instance_data *instance_data);
+extern void control_client_check(int control, int& control_client, const std::string& deviceName);
+extern void process_control_socket(int& control_client, overlay_params &params);
+extern void control_send(int control_client, const char *cmd, unsigned cmdlen, const char *param, unsigned paramlen);
+extern int global_control_client;
 #ifdef HAVE_DBUS
 void render_mpris_metadata(const overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing);
 #endif
 void update_fan();
-#endif //MANGOAPP_LAYER
 
 #endif //MANGOHUD_OVERLAY_H
diff -pruN 0.6.7.1-1/src/overlay_params.cpp 0.6.8-1/src/overlay_params.cpp
--- 0.6.7.1-1/src/overlay_params.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/overlay_params.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -96,9 +96,15 @@ parse_position(const char *str)
 static int
 parse_control(const char *str)
 {
-   int ret = os_socket_listen_abstract(str, 1);
+   std::string path(str);
+   size_t npos = path.find("%p");
+   if (npos != std::string::npos)
+      path.replace(npos, 2, std::to_string(getpid()));
+   SPDLOG_DEBUG("Socket: {}", path);
+
+   int ret = os_socket_listen_abstract(path.c_str(), 1);
    if (ret < 0) {
-      SPDLOG_ERROR("Couldn't create socket pipe at '{}'\n", str);
+      SPDLOG_ERROR("Couldn't create socket pipe at '{}'", path);
       SPDLOG_ERROR("ERROR: '{}'", strerror(errno));
       return ret;
    }
@@ -402,6 +408,8 @@ parse_gl_size_query(const char *str)
 #define parse_gl_bind_framebuffer(s) parse_unsigned(s)
 #define parse_gl_dont_flip(s) parse_unsigned(s) != 0
 #define parse_round_corners(s) parse_unsigned(s)
+#define parse_fcat_overlay_width(s) parse_unsigned(s)
+#define parse_fcat_screen_edge(s) parse_unsigned(s)
 
 #define parse_cpu_color(s) parse_color(s)
 #define parse_gpu_color(s) parse_color(s)
@@ -527,6 +535,7 @@ parse_overlay_env(struct overlay_params
          params->enabled[OVERLAY_PARAM_ENABLED_hide_fsr_sharpness] = 0;
          params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = 0;
          params->enabled[OVERLAY_PARAM_ENABLED_read_cfg] = read_cfg;
+         params->enabled[OVERLAY_PARAM_ENABLED_fcat] = 0;
       }
 #define OVERLAY_PARAM_BOOL(name)                                       \
       if (!strcmp(#name, key)) {                                       \
@@ -576,8 +585,9 @@ parse_overlay_config(struct overlay_para
    params->enabled[OVERLAY_PARAM_ENABLED_frametime] = true;
    params->enabled[OVERLAY_PARAM_ENABLED_fps_only] = false;
    params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery] = false;
-   params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery_icon] = true;
+   params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery_icon] = false;
    params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = false;
+   params->enabled[OVERLAY_PARAM_ENABLED_fcat] = false;
    params->fps_sampling_period = 500000000; /* 500ms */
    params->width = 0;
    params->height = 140;
@@ -589,6 +599,8 @@ parse_overlay_config(struct overlay_para
    params->offset_y = 0;
    params->background_alpha = 0.5;
    params->alpha = 1.0;
+   params->fcat_screen_edge = 0;
+   params->fcat_overlay_width = 24;
    params->time_format = "%T";
    params->gpu_color = 0x2e9762;
    params->cpu_color = 0x2e97cb;
@@ -669,6 +681,7 @@ parse_overlay_config(struct overlay_para
          params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam] = 0;
          params->enabled[OVERLAY_PARAM_ENABLED_hide_fsr_sharpness] = 0;
          params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = 0;
+         params->enabled[OVERLAY_PARAM_ENABLED_fcat] = 0;
          params->options.erase("full");
       }
       for (auto& it : params->options) {
@@ -699,6 +712,10 @@ parse_overlay_config(struct overlay_para
       parse_overlay_env(params, env);
    }
 
+   // If fps_only param is enabled disable legacy_layout
+   if (params->enabled[OVERLAY_PARAM_ENABLED_fps_only])
+      params->enabled[OVERLAY_PARAM_ENABLED_legacy_layout] = false;
+
    if (is_blacklisted())
       return;
 
@@ -741,17 +758,20 @@ parse_overlay_config(struct overlay_para
    if (!params->table_columns)
       params->table_columns = 3;
 
+   params->table_columns = std::max(1u, std::min(64u, params->table_columns));
+
    if (!params->font_size) {
       params->font_size = 24;
    }
 
    //increase hud width if io read and write
    if (!params->width) {
+      params->width = params->font_size * params->font_scale * params->table_columns * 4;
+
       if ((params->enabled[OVERLAY_PARAM_ENABLED_io_read] || params->enabled[OVERLAY_PARAM_ENABLED_io_write])) {
-         params->width = 13 * params->font_size * params->font_scale;
-      } else {
-         params->width = params->font_size * params->font_scale * 11.7;
+         params->width += 2 * params->font_size * params->font_scale;
       }
+
       // Treat it like hud would need to be ~7 characters wider with default font.
       if (params->no_small_font)
          params->width += 7 * params->font_size * params->font_scale;
@@ -810,9 +830,16 @@ parse_overlay_config(struct overlay_para
 
    // Needs ImGui context but it is null here for OpenGL so just note it and update somewhere else
    HUDElements.colors.update = true;
+   if (params->no_small_font)
+      HUDElements.text_column = 2;
+   else
+      HUDElements.text_column = 1;
 
-   if(logger && logger->m_params == nullptr) logger.reset();
-   if(!logger) logger = std::make_unique<Logger>(HUDElements.params);
+   if(logger && logger->is_active()){
+      SPDLOG_DEBUG("Stopped logging because config reloaded");
+      logger->stop_logging();
+   }
+   logger = std::make_unique<Logger>(params);
    if(params->autostart_log && !logger->is_active())
       std::thread(autostart_log, params->autostart_log).detach();
 #ifdef MANGOAPP
diff -pruN 0.6.7.1-1/src/overlay_params.h 0.6.8-1/src/overlay_params.h
--- 0.6.7.1-1/src/overlay_params.h	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/overlay_params.h	2022-08-01 01:27:11.000000000 +0000
@@ -83,6 +83,8 @@ typedef unsigned long KeySym;
    OVERLAY_PARAM_BOOL(hide_fsr_sharpness)            \
    OVERLAY_PARAM_BOOL(fan)                           \
    OVERLAY_PARAM_BOOL(throttling_status)             \
+   OVERLAY_PARAM_BOOL(fcat)                          \
+   OVERLAY_PARAM_BOOL(log_versioning)                \
    OVERLAY_PARAM_CUSTOM(fps_sampling_period)         \
    OVERLAY_PARAM_CUSTOM(output_folder)               \
    OVERLAY_PARAM_CUSTOM(output_file)                 \
@@ -152,6 +154,8 @@ typedef unsigned long KeySym;
    OVERLAY_PARAM_CUSTOM(autostart_log)               \
    OVERLAY_PARAM_CUSTOM(round_corners)               \
    OVERLAY_PARAM_CUSTOM(fsr_steam_sharpness)         \
+   OVERLAY_PARAM_CUSTOM(fcat_screen_edge)            \
+   OVERLAY_PARAM_CUSTOM(fcat_overlay_width)          \
 
 enum overlay_param_position {
    LAYER_POSITION_TOP_LEFT,
@@ -214,7 +218,7 @@ struct overlay_params {
    int gl_bind_framebuffer {-1};
    enum gl_size_query gl_size_query {GL_SIZE_DRAWABLE};
    bool gl_dont_flip {false};
-   uint64_t log_duration;
+   int64_t log_duration, log_interval;
    unsigned cpu_color, gpu_color, vram_color, ram_color, engine_color, io_color, frametime_color, background_color, text_color, wine_color, battery_color;
    std::vector<unsigned> gpu_load_color;
    std::vector<unsigned> cpu_load_color;
@@ -241,7 +245,7 @@ struct overlay_params {
    std::string media_player_name;
    std::string cpu_text, gpu_text;
    std::vector<std::string> blacklist;
-   unsigned log_interval, autostart_log;
+   unsigned autostart_log;
    std::vector<std::string> media_player_format;
    std::vector<std::string> benchmark_percentiles;
    std::string font_file, font_file_text;
@@ -252,6 +256,8 @@ struct overlay_params {
    std::unordered_map<std::string,std::string> options;
    int permit_upload;
    int fsr_steam_sharpness;
+   unsigned short fcat_screen_edge;
+   unsigned short fcat_overlay_width;
 
    size_t font_params_hash;
 };
diff -pruN 0.6.7.1-1/src/vulkan.cpp 0.6.8-1/src/vulkan.cpp
--- 0.6.7.1-1/src/vulkan.cpp	2022-05-12 12:28:41.000000000 +0000
+++ 0.6.8-1/src/vulkan.cpp	2022-08-01 01:27:11.000000000 +0000
@@ -50,6 +50,8 @@
 #include "blacklist.h"
 #include "pci_ids.h"
 
+using namespace std;
+
 float offset_x, offset_y, hudSpacing;
 int hudFirstRow, hudSecondRow;
 VkPhysicalDeviceDriverProperties driverProps = {};
@@ -60,8 +62,37 @@ namespace MangoHud { namespace GL {
 }}
 #endif
 
-/* Mapped from VkCommandBuffer */
+/* Mapped from VkInstace/VkPhysicalDevice */
+struct instance_data {
+   struct vk_instance_dispatch_table vtable;
+   VkInstance instance;
+   struct overlay_params params;
+   uint32_t api_version;
+   string engineName, engineVersion;
+   enum EngineTypes engine;
+   notify_thread notifier;
+   int control_client;
+};
+
+/* Mapped from VkDevice */
 struct queue_data;
+struct device_data {
+   struct instance_data *instance;
+
+   PFN_vkSetDeviceLoaderData set_device_loader_data;
+
+   struct vk_device_dispatch_table vtable;
+   VkPhysicalDevice physical_device;
+   VkDevice device;
+
+   VkPhysicalDeviceProperties properties;
+
+   struct queue_data *graphic_queue;
+
+   std::vector<struct queue_data *> queues;
+};
+
+/* Mapped from VkCommandBuffer */
 struct command_buffer_data {
    struct device_data *device;
 
@@ -134,6 +165,7 @@ struct swapchain_data {
 
    /**/
    ImGuiContext* imgui_context;
+   ImFontAtlas* font_atlas;
    ImVec2 window_size;
 
    struct swapchain_stats sw_stats;
@@ -214,6 +246,7 @@ static struct instance_data *new_instanc
    data->instance = instance;
    data->params = {};
    data->params.control = -1;
+   data->control_client = -1;
    map_object(HKEY(data->instance), data);
    return data;
 }
@@ -356,6 +389,7 @@ static struct swapchain_data *new_swapch
    data->device = device_data;
    data->swapchain = swapchain;
    data->window_size = ImVec2(instance_data->params.width, instance_data->params.height);
+   data->font_atlas = IM_NEW(ImFontAtlas);
    map_object(HKEY(data->swapchain), data);
    return data;
 }
@@ -422,8 +456,8 @@ static void snapshot_swapchain_frame(str
    check_keybinds(instance_data->params, device_data->properties.vendorID);
 #ifdef __linux__
    if (instance_data->params.control >= 0) {
-      control_client_check(device_data);
-      process_control_socket(instance_data);
+      control_client_check(instance_data->params.control, instance_data->control_client, gpu.c_str());
+      process_control_socket(instance_data->control_client, instance_data->params);
    }
 #endif
 }
@@ -443,11 +477,11 @@ static void compute_swapchain_display(st
    ImGui::NewFrame();
    {
       ::scoped_lock lk(instance_data->notifier.mutex);
+      overlay_new_frame(instance_data->params);
       position_layer(data->sw_stats, instance_data->params, data->window_size);
       render_imgui(data->sw_stats, instance_data->params, data->window_size, true);
+      overlay_end_frame();
    }
-   ImGui::PopStyleVar(3);
-
    ImGui::EndFrame();
    ImGui::Render();
 
@@ -670,16 +704,15 @@ static void check_fonts(struct swapchain
    struct device_data *device_data = data->device;
    struct instance_data *instance_data = device_data->instance;
    auto& params = instance_data->params;
-   ImGuiIO& io = ImGui::GetIO();
 
    if (params.font_params_hash != data->sw_stats.font_params_hash)
    {
       SPDLOG_DEBUG("Recreating font image");
-      VkDescriptorSet desc_set = (VkDescriptorSet)io.Fonts->TexID;
-      create_fonts(instance_data->params, data->sw_stats.font1, data->sw_stats.font_text);
+      VkDescriptorSet desc_set = (VkDescriptorSet)data->font_atlas->TexID;
+      create_fonts(data->font_atlas, instance_data->params, data->sw_stats.font1, data->sw_stats.font_text);
       unsigned char* pixels;
       int width, height;
-      io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
+      data->font_atlas->GetTexDataAsAlpha8(&pixels, &width, &height);
 
       // wait for rendering to complete, if any
       device_data->vtable.DeviceWaitIdle(device_data->device);
@@ -690,7 +723,7 @@ static void check_fonts(struct swapchain
       else
          desc_set = create_image_with_desc(data, width, height, VK_FORMAT_R8_UNORM, data->font_image, data->font_mem, data->font_image_view);
 
-      io.Fonts->SetTexID((ImTextureID)desc_set);
+      data->font_atlas->SetTexID((ImTextureID)desc_set);
       data->font_uploaded = false;
       data->sw_stats.font_params_hash = params.font_params_hash;
       SPDLOG_DEBUG("Default font tex size: {}x{}px", width, height);
@@ -708,10 +741,9 @@ static void ensure_swapchain_fonts(struc
       return;
 
    data->font_uploaded = true;
-   ImGuiIO& io = ImGui::GetIO();
    unsigned char* pixels;
    int width, height;
-   io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
+   data->font_atlas->GetTexDataAsAlpha8(&pixels, &width, &height);
    size_t upload_size = width * height * 1 * sizeof(char);
    upload_image_data(device_data, command_buffer, pixels, upload_size, width, height, data->upload_font_buffer, data->upload_font_buffer_mem, data->font_image);
 }
@@ -862,7 +894,7 @@ static struct overlay_draw *render_swapc
 #if 1 // disable if using >1 font textures
    VkDescriptorSet desc_set[1] = {
       //data->descriptor_set
-      reinterpret_cast<VkDescriptorSet>(ImGui::GetIO().Fonts->Fonts[0]->ContainerAtlas->TexID)
+      reinterpret_cast<VkDescriptorSet>(data->font_atlas->TexID)
    };
    device_data->vtable.CmdBindDescriptorSets(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
                                              data->pipeline_layout, 0, 1, desc_set, 0, NULL);
@@ -1276,7 +1308,7 @@ static void setup_swapchain_data(struct
    data->height = pCreateInfo->imageExtent.height;
    data->format = pCreateInfo->imageFormat;
 
-   data->imgui_context = ImGui::CreateContext();
+   data->imgui_context = ImGui::CreateContext(data->font_atlas);
    ImGui::SetCurrentContext(data->imgui_context);
 
    ImGui::GetIO().IniFilename = NULL;
@@ -1433,6 +1465,7 @@ static void shutdown_swapchain_data(stru
    device_data->vtable.DestroySampler(device_data->device, data->font_sampler, NULL);
    shutdown_swapchain_font(data);
 
+   IM_FREE(data->font_atlas);
    ImGui::DestroyContext(data->imgui_context);
 }
 
@@ -1563,7 +1596,7 @@ static VkResult overlay_QueuePresentKHR(
       struct overlay_draw *draw = before_present(swapchain_data,
                                                    queue_data,
                                                    pPresentInfo->pWaitSemaphores,
-                                                   pPresentInfo->waitSemaphoreCount,
+                                                   i == 0 ? pPresentInfo->waitSemaphoreCount : 0,
                                                    image_index);
 
       /* Because the submission of the overlay draw waits on the semaphores
