Index: tigervnc-1.12.0/vncviewer/DesktopWindow.cxx =================================================================== --- tigervnc-1.12.0.orig/vncviewer/DesktopWindow.cxx +++ tigervnc-1.12.0/vncviewer/DesktopWindow.cxx @@ -236,6 +236,8 @@ DesktopWindow::~DesktopWindow() delete statsGraph; + delete viewport; + instances.erase(this); if (instances.size() == 0) Index: tigervnc-1.12.0/vncviewer/Viewport.cxx =================================================================== --- tigervnc-1.12.0.orig/vncviewer/Viewport.cxx +++ tigervnc-1.12.0/vncviewer/Viewport.cxx @@ -192,6 +192,18 @@ Viewport::Viewport(int w, int h, const r Viewport::~Viewport() { + // Send release for every pressed key + for(DownMap::iterator iter = downKeySym.begin(); iter != downKeySym.end(); ++iter) { + try { + if (iter->first > 0xff) + cc->writer()->writeKeyEvent(iter->second, 0, false); + else + cc->writer()->writeKeyEvent(iter->second, iter->first, false); + } catch (rdr::Exception& e) { + // ignore + } + } + // Unregister all timeouts in case they get a change tro trigger // again later when this object is already gone. Fl::remove_timeout(handlePointerTimeout, this); Index: tigervnc-1.12.0/vncviewer/vncviewer.cxx =================================================================== --- tigervnc-1.12.0.orig/vncviewer/vncviewer.cxx +++ tigervnc-1.12.0/vncviewer/vncviewer.cxx @@ -113,6 +113,7 @@ static const char *about_text() return buffer; } +static CConn *cc; void abort_vncviewer(const char *error, ...) { @@ -176,8 +177,6 @@ void about_vncviewer() static void mainloop(const char* vncserver, network::Socket* sock) { while (true) { - CConn *cc; - exitMainloop = false; cc = new CConn(vncServerName, sock); @@ -262,6 +261,16 @@ static void CleanupSignalHandler(int sig // CleanupSignalHandler allows C++ object cleanup to happen because it calls // exit() rather than the default which is to abort. vlog.info(_("Termination signal %d has been received. TigerVNC Viewer will now exit."), sig); + delete cc; + exit(1); +} + +static int CleanupXIOErrorHandler(Display *dpy) +{ + // CleanupSignalHandler allows C++ object cleanup to happen because it calls + // exit() rather than the default which is to abort. + vlog.info("XErrorHandler called"); + delete cc; exit(1); } @@ -744,6 +753,9 @@ int main(int argc, char** argv) XkbSetDetectableAutoRepeat(fl_display, True, NULL); #endif + fl_open_display(); + XSetIOErrorHandler(CleanupXIOErrorHandler); + init_fltk(); enable_touch();