Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 36 additions & 30 deletions lib/python/gremlin_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,20 @@ def get_linuxcnc_ini_file():
ans = p.split()[p.split().index('-ini')+1]
return ans

def _glade_is_running():
"""True when the glade interface designer, not gladevcp, is the host.

Glade instantiates the widget to draw its own preview and has no window to
embed into.
"""
if 'glade' not in sys.argv[0] or 'gladevcp' in sys.argv[0]:
return False
for d in os.environ['PATH'].split(':'):
f = os.path.join(d,sys.argv[0])
if os.path.isfile(f) and os.access(f, os.X_OK):
return True
return False

class GremlinView():
"""Implement a standalone gremlin with some buttons
and provide means to embed using a glade ui file"""
Expand All @@ -143,6 +157,11 @@ def __init__(self
):

self.alive = alive
self.parent = parent
#: True when the box is to be handed to a parent widget rather than
#: shown in the ui file's own window. False under the glade designer,
#: which has no window to hand it to.
self.embedded = parent is not None and not _glade_is_running()
linuxcnc_running = False
if ini_check():
linuxcnc_running = True
Expand Down Expand Up @@ -263,10 +282,19 @@ def __init__(self
self.x = 0
self.y = 0

# prevent flashing topwindow
self.topwindow.iconify()
self.topwindow.show_all()
self.topwindow.hide()
if self.embedded:
# Handed over before anything is realized. A GtkGLArea's GL context
# belongs to the window it was realized under, and
# Gtk.Widget.reparent() keeps a widget realized - which leaves the
# preview drawing into a framebuffer nothing composites.
self.topwindow.remove(self.gbox)
self.parent.add(self.gbox)
self.gbox.connect('destroy',self._gboxquit)
else:
# prevent flashing topwindow
self.topwindow.iconify()
self.topwindow.show_all()
self.topwindow.hide()

self.preview_file(None)
if linuxcnc_running:
Expand All @@ -282,7 +310,6 @@ def __init__(self
self.last_file = None
self.last_file_mtime = None

self.parent = parent
if self.parent is None:
# topwindow (standalone) application
# print "TOP:",gtk_theme_name
Expand All @@ -301,7 +328,10 @@ def __init__(self
# settings.set_string_property('gtk-theme-name',gtk_theme_name,"")

self.topwindow.connect('destroy',self._topwindowquit)
self.topwindow.show_all()
if self.embedded:
self.gbox.show_all()
else:
self.topwindow.show_all()
self.running = True

if self.last_file is not None:
Expand All @@ -321,30 +351,6 @@ def _periodic(self,arg):
self.ct +=1
self.halg.poll()

if (self.parent is not None) and (self.ct) == 2:
# not sure why delay is needed for reparenting
# but without, the display of the (rgb) axes
# and the cone to not appear in gremlin
# print "REPARENT:",self.gbox, self.parent
#-----------------------------------------------------------------------------
# determine if glade interface designer is running
# to avoid assertion error:
# gtk_widget_reparent_fixup_child: assertion failed: (client_data != NULL)
is_glade = False
if 'glade' in sys.argv[0] and 'gladevcp' not in sys.argv[0]:
for d in os.environ['PATH'].split(':'):
f = os.path.join(d,sys.argv[0])
if ( os.path.isfile(f)
and os.access(f, os.X_OK)):
is_glade = True
break
#-----------------------------------------------------------------------------
if (not is_glade):
self.gbox.reparent(self.parent)
self.gbox.show_all()
self.gbox.connect('destroy',self._gboxquit)
return True

try:
current_file = self.halg._current_file
except AttributeError:
Expand Down
17 changes: 11 additions & 6 deletions lib/python/rs274/glcanon_gl.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,11 +472,11 @@ def _context_token() -> int:
The width probe's answer belongs to the context it was made in, so the
cache needs to notice when a different context becomes current. There is no
portable "current context" call, so this asks the two window-system
bindings the preview is ever built on - EGL (Qt on most builds, and the
test corpus) and GLX (``gremlin.py``, ``togl.c``) - and takes whichever
answers. EGL first: where both libraries are present but GLX is what is in
use, ``eglGetCurrentContext`` returns EGL_NO_CONTEXT and the GLX call is
reached.
bindings the preview is ever built on - EGL (Qt on most builds, GTK under
Wayland, and the test corpus) and GLX (``togl.c``, and GTK under X11) - and
takes whichever answers. EGL first: where both libraries are present but
GLX is what is in use, ``eglGetCurrentContext`` returns EGL_NO_CONTEXT and
the GLX call is reached.

0 means the question could not be asked - no library, no symbol, no current
context. The caller then behaves as it did before this was here, caching
Expand Down Expand Up @@ -1543,6 +1543,11 @@ def __init__(self) -> None:
def ensure(self, w: int, h: int) -> None:
if self.fbo and (w, h) == (self.w, self.h):
return
# Restored, not zeroed: the caller's framebuffer is not always the
# window - GtkGLArea and QOpenGLWidget both draw the visible frame into
# an FBO of their own. Read after the early return, since glGetIntegerv
# can stall the pipeline.
prev_fbo = int(glGetIntegerv(GL_FRAMEBUFFER_BINDING))
self.delete()
self.w, self.h = w, h
self.fbo = glGenFramebuffers(1)
Expand All @@ -1564,7 +1569,7 @@ def ensure(self, w: int, h: int) -> None:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, self.depth)
status = glCheckFramebufferStatus(GL_FRAMEBUFFER)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glBindFramebuffer(GL_FRAMEBUFFER, prev_fbo)
if status != GL_FRAMEBUFFER_COMPLETE:
self.delete()
raise RuntimeError(
Expand Down
Loading
Loading