diff --git a/display/d.mon/render_cmd.py b/display/d.mon/render_cmd.py index e9af69e673c..bdad7404e4d 100644 --- a/display/d.mon/render_cmd.py +++ b/display/d.mon/render_cmd.py @@ -1,12 +1,41 @@ #!/usr/bin/env python3 import os import sys +import glob import tempfile +from pathlib import Path from grass.script import core as grass from grass.script import task as gtask from grass.exceptions import CalledModuleError +non_rendering_modules = ( + "d.colorlist", + "d.font", + "d.fontlist", + "d.frame", + "d.info", + "d.mon", + "d.out.file", + "d.to.rast", + "d.what.rast", + "d.what.vect", + "d.where", +) + + +# remove empty mapfile from non-rendering modules +def remove_mapfile(mapfile): + # adopted from Map.DeleteLayer() in gui/wxpython/core/render.py + base = os.path.split(mapfile)[0] + mapfile = os.path.split(mapfile)[1] + tempbase = mapfile.split(".")[0] + if base == "" or tempbase == "": + return + basefile = os.path.join(base, tempbase) + r".*" + for f in glob.glob(basefile): + os.remove(f) + # read environment variables from file def read_env_file(env_file): @@ -42,26 +71,18 @@ def render(cmd, mapfile): env["GRASS_RENDER_FILE"] = mapfile try: grass.run_command(cmd[0], env=env, **cmd[1]) + # display driver can generate a blank map file unnecessarily for + # non-rendering modules; delete it + if cmd[0] in non_rendering_modules and os.path.exists(mapfile): + remove_mapfile(mapfile) + except CalledModuleError as e: grass.debug("Unable to render: {0}".format(e), 1) # update cmd file def update_cmd_file(cmd_file, cmd, mapfile): - if cmd[0] in ( - "d.colorlist", - "d.font", - "d.fontlist", - "d.frame", - "d.info", - "d.mon", - "d.out.file", - "d.redraw", - "d.to.rast", - "d.what.rast", - "d.what.vect", - "d.where", - ): + if cmd[0] in non_rendering_modules: return mode = "w" if cmd[0] == "d.erase" else "a" @@ -157,13 +178,22 @@ def read_stdin(cmd): mapfile += ".png" else: mapfile += ".ppm" + # to force rendering by wx monitors, but don't create a map file for + # non-rendering modules + if cmd[0] not in non_rendering_modules: + Path(mapfile).touch() else: mapfile = None adjust_region(width, height) read_stdin(cmd) - render(cmd, mapfile) + # wx monitors will render new layers internally so don't render them here; + # also, some display modules print information to the terminal rather than + # rendering any contents on the monitor so allow them to run here + if not mon.startswith("wx") or cmd[0] in non_rendering_modules: + render(cmd, mapfile) + update_cmd_file(os.path.join(path, "cmd"), cmd, mapfile) if cmd[0] == "d.erase" and os.path.exists(legfile): os.remove(legfile)