View Issue Details

IDProjectCategoryView StatusLast Update
0004190The Dark ModDesign/Codingpublic27.12.2018 17:33
ReporterNagaHuntress Assigned Tocabalistic  
PrioritynormalSeveritynormalReproducibilityhave not tried
Status resolvedResolutionfixed 
OSLinux 
Product VersionSVN 
Target VersionTDM 2.07Fixed in VersionTDM 2.07 
Summary0004190: A patch to allow alt-tabbing under Linux
DescriptionI've created a patch to fix the problem where it was impossible alt-tab (or use any other window manager key combos) to switch away from TDM. This patch works for both windowed and full screen modes.

Changes:
 - It will no longer grab exclusive input of the keyboard by default. This allows the window manager to process the keyboard input and do things like alt-tabbing. To get the old behaviour set 'in_grabkeyboard' to 1 (Exception: Full screen console will now ungrab, previously only windowed console would ungrab.).
 - In order to get the above behaviour to work in full screen mode, full screen mode initialisation has been modified so that it asks the window manager to handle the window as a full screen window. To get the old behaviour set 'v_nowmfullscreen' to 1 (this will force it to grab the keyboard input too, regardless of 'in_grabkeyboard' or other conditions).


I've only tested it on Linux Mint 17.2, 64 bit.
TagsNo tags attached.

Relationships

related to 0003568 resolvedduzenko fullscreen windowed option 
related to 0004288 resolved Minimizing TDM 

Activities

NagaHuntress

NagaHuntress

30.07.2015 15:55

reporter  

tdm-linux-window-manager-key-fix.diff (6,660 bytes)   
Index: sys/linux/glimp.cpp
===================================================================
--- sys/linux/glimp.cpp	(revision 6521)
+++ sys/linux/glimp.cpp	(working copy)
@@ -25,12 +25,20 @@
 #include <fcntl.h>
 #include <unistd.h>
 
+#include <X11/Xatom.h>
+
 extern "C" {
 #	include "libXNVCtrl/NVCtrlLib.h"
 }
 
 idCVar sys_videoRam( "sys_videoRam", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "Texture memory on the video card (in megabytes) - 0: autodetect", 0, 512 );
+/**
+If set and full screen is used, it will NOT notify the window manager that the window is full screen. It will tell X to manage the window directly and it will grab inputs for mouse and keyboard for itself. This will only check at screen initialization time.
 
+This option is useful when the window manager doesn't understand, respect or play nicely with a full screen request.
+ */
+idCVar v_nowmfullscreen( "v_nowmfullscreen", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "Do not use the window manager for fullscreen. If this is set and full screen is used, it will not notify the window manager and will monopolize both mouse and keyboard inputs. Only used at screen initialization.");
+
 Display *dpy = NULL;
 static int scrnum = 0;
 
@@ -47,6 +55,11 @@
 static int num_vidmodes;
 static bool vidmode_active = false;
 
+/** Set true if fullscreen mode was set without asking the window manager to treat this window as full screen.
+\see {v_nowmfullscreen}
+*/
+bool vidmode_nowmfullscreen = false;
+
 // backup gamma ramp
 static int save_rampsize = 0;
 static unsigned short *save_red, *save_green, *save_blue;
@@ -476,13 +489,23 @@
 	attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
 	attr.event_mask = X_MASK;
 	if (vidmode_active) {
-		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
-			CWEventMask | CWOverrideRedirect;
-		attr.override_redirect = True;
+		if(v_nowmfullscreen.GetBool()) {
+			/*We're not going to cooperate with any window managers, so the window will grab full control.*/
+			mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
+				CWEventMask | CWOverrideRedirect | CWBorderPixel;
+			vidmode_nowmfullscreen = true;
+			attr.override_redirect = True;
+		} else {
+			/*Create a normal window and later inform the window manager that this is fullscreen.*/
+			mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
+				CWEventMask | CWBorderPixel;
+			vidmode_nowmfullscreen = false;
+		}
 		attr.backing_store = NotUseful;
 		attr.save_under = False;
 	} else {
 		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+		vidmode_nowmfullscreen = false;
 	}
 
 	win = XCreateWindow(dpy, root, 0, 0,
@@ -490,6 +513,16 @@
 						0, visinfo->depth, InputOutput,
 						visinfo->visual, mask, &attr);
 
+	if(vidmode_active && !vidmode_nowmfullscreen) {
+		/*Tell the window manager that this is a full screen window.*/
+		const Atom atoms[2] = { XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False), None };
+		XChangeProperty(
+			dpy, 
+			win, 
+			XInternAtom(dpy, "_NET_WM_STATE", False),
+			XA_ATOM, 32, PropModeReplace, (const unsigned char *)atoms, 1
+			);
+	}
 	XStoreName(dpy, win, GAME_NAME);
 
 	// don't let the window be resized
Index: sys/linux/input.cpp
===================================================================
--- sys/linux/input.cpp	(revision 6521)
+++ sys/linux/input.cpp	(working copy)
@@ -25,7 +25,13 @@
 idCVar in_mouse( "in_mouse", "1", CVAR_SYSTEM | CVAR_ARCHIVE, "" );
 idCVar in_dgamouse( "in_dgamouse", "1", CVAR_SYSTEM | CVAR_ARCHIVE, "" );
 idCVar in_nograb( "in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "" );
+/**
+When set, it grabs X's keyboard input so that it's exclusively handled by the game. Also while set, it prevents the window manager from handling keyboard input, which means that any fancy key combinations handlinded by the window manager can't be handled, preventing common functions like: alt-tabbing, work space switching, volume changing, etc. 
 
+Note: Even if set, grabbing of the keyboard is disabled under certain conditions, such as when the console is open.
+*/
+idCVar in_grabkeyboard( "in_grabkeyboard", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "When set, the keyboard is grabbed, so input goes exclusively to this game. When cleared the window manager is allowed to handle input from the keyboard." );
+
 // have a working xkb extension
 static bool have_xkb = false;
 
@@ -32,6 +38,9 @@
 // toggled by grab calls - decides if we ignore MotionNotify events
 static bool mouse_active = false;
 
+///Flags if the keyboard has been already been grabbed.
+static bool keyboard_grabbed = false;
+
 // non-DGA pointer-warping mouse input
 static int mwx, mwy;
 static int mx = 0, my = 0;
@@ -171,12 +180,16 @@
 		mwy = glConfig.vidHeight / 2;
 		mx = my = 0;
 	}
+
+	/*Grab the keyboard if we're configured to grab it, or if we're doing full screen without the window manager.*/
+	if((vidmode_nowmfullscreen || in_grabkeyboard.GetBool()) && !keyboard_grabbed) {
+		keyboard_grabbed = true;
+		XGrabKeyboard( dpy, win,
+			       False,
+			       GrabModeAsync, GrabModeAsync,
+			       CurrentTime );
+	}
 	
-	XGrabKeyboard( dpy, win,
-				  False,
-				  GrabModeAsync, GrabModeAsync,
-				  CurrentTime );
-	
 	XSync( dpy, False );
 
 	mouse_active = true;
@@ -196,7 +209,10 @@
 						  mouse_accel_denominator, mouse_threshold );
 	
 	XUngrabPointer( dpy, CurrentTime );
-	XUngrabKeyboard( dpy, CurrentTime );
+	if(keyboard_grabbed) {
+		XUngrabKeyboard( dpy, CurrentTime );
+		keyboard_grabbed = false;
+	}
 	
 	XWarpPointer( dpy, None, win,
 				 0, 0, 0, 0,
@@ -219,6 +235,18 @@
 		#endif
 		return;
 	}
+	/*Check if the keyboard should be grabbed or ungrabbed.*/
+	if(!vidmode_nowmfullscreen && keyboard_grabbed && (!grabIt || !in_grabkeyboard.GetBool())) {
+		XUngrabKeyboard( dpy, CurrentTime );
+		keyboard_grabbed = false;
+	} else if((vidmode_nowmfullscreen || (grabIt && in_grabkeyboard.GetBool())) && !keyboard_grabbed) {
+		/*Grab the keyboard if we're configured to grab it and set to grab, or if we're doing full screen without the window manager.*/
+		keyboard_grabbed = true;
+		XGrabKeyboard( dpy, win,
+			       False,
+			       GrabModeAsync, GrabModeAsync,
+			       CurrentTime );
+	}
 	
 	if ( glConfig.isFullscreen ) {
 		if ( !grabIt ) {
Index: sys/linux/local.h
===================================================================
--- sys/linux/local.h	(revision 6521)
+++ sys/linux/local.h	(working copy)
@@ -34,6 +34,8 @@
 extern Display *dpy;
 extern Window win;
 
+extern bool vidmode_nowmfullscreen;
+
 // input.cpp
 extern bool dga_found;
 void Sys_XEvents();
NagaHuntress

NagaHuntress

11.08.2015 09:49

reporter  

tdm-linux-window-manager-key-fix-v2.diff (8,523 bytes)   
Index: sys/linux/glimp.cpp
===================================================================
--- sys/linux/glimp.cpp	(revision 6527)
+++ sys/linux/glimp.cpp	(working copy)
@@ -25,12 +25,20 @@
 #include <fcntl.h>
 #include <unistd.h>
 
+#include <X11/Xatom.h>
+
 extern "C" {
 #	include "libXNVCtrl/NVCtrlLib.h"
 }
 
 idCVar sys_videoRam( "sys_videoRam", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "Texture memory on the video card (in megabytes) - 0: autodetect", 0, 512 );
+/**
+If set and full screen is used, it will NOT notify the window manager that the window is full screen. It will tell X to manage the window directly and it will grab inputs for mouse and keyboard for itself. This will only check at screen initialization time.
 
+This option is useful when the window manager doesn't understand, respect or play nicely with a full screen request.
+ */
+idCVar v_nowmfullscreen( "v_nowmfullscreen", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "Do not use the window manager for fullscreen. If this is set and full screen is used, it will not notify the window manager and will monopolize both mouse and keyboard inputs. Only used at screen initialization.");
+
 Display *dpy = NULL;
 static int scrnum = 0;
 
@@ -47,6 +55,11 @@
 static int num_vidmodes;
 static bool vidmode_active = false;
 
+/** Set true if fullscreen mode was set without asking the window manager to treat this window as full screen.
+\see {v_nowmfullscreen}
+*/
+bool vidmode_nowmfullscreen = false;
+
 // backup gamma ramp
 static int save_rampsize = 0;
 static unsigned short *save_red, *save_green, *save_blue;
@@ -476,13 +489,23 @@
 	attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
 	attr.event_mask = X_MASK;
 	if (vidmode_active) {
-		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
-			CWEventMask | CWOverrideRedirect;
-		attr.override_redirect = True;
+		if(v_nowmfullscreen.GetBool()) {
+			/*We're not going to cooperate with any window managers, so the window will grab full control.*/
+			mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
+				CWEventMask | CWOverrideRedirect | CWBorderPixel;
+			vidmode_nowmfullscreen = true;
+			attr.override_redirect = True;
+		} else {
+			/*Create a normal window and later inform the window manager that this is fullscreen.*/
+			mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
+				CWEventMask | CWBorderPixel;
+			vidmode_nowmfullscreen = false;
+		}
 		attr.backing_store = NotUseful;
 		attr.save_under = False;
 	} else {
 		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+		vidmode_nowmfullscreen = false;
 	}
 
 	win = XCreateWindow(dpy, root, 0, 0,
@@ -490,6 +513,16 @@
 						0, visinfo->depth, InputOutput,
 						visinfo->visual, mask, &attr);
 
+	if(vidmode_active && !vidmode_nowmfullscreen) {
+		/*Tell the window manager that this is a full screen window.*/
+		const Atom atoms[2] = { XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False), None };
+		XChangeProperty(
+			dpy, 
+			win, 
+			XInternAtom(dpy, "_NET_WM_STATE", False),
+			XA_ATOM, 32, PropModeReplace, (const unsigned char *)atoms, 1
+			);
+	}
 	XStoreName(dpy, win, GAME_NAME);
 
 	// don't let the window be resized
Index: sys/linux/input.cpp
===================================================================
--- sys/linux/input.cpp	(revision 6527)
+++ sys/linux/input.cpp	(working copy)
@@ -19,6 +19,7 @@
 #include "../../idlib/precompiled.h"
 #include "../posix/posix_public.h"
 #include "local.h"
+#include "framework/KeyInput.h"
 
 #include <pthread.h>
 
@@ -25,7 +26,17 @@
 idCVar in_mouse( "in_mouse", "1", CVAR_SYSTEM | CVAR_ARCHIVE, "" );
 idCVar in_dgamouse( "in_dgamouse", "1", CVAR_SYSTEM | CVAR_ARCHIVE, "" );
 idCVar in_nograb( "in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "" );
+/**
+When set, it grabs X's keyboard input so that it's exclusively handled by the game. Also while set, it prevents the window manager from handling keyboard input, which means that any fancy key combinations handlinded by the window manager can't be handled, preventing common functions like: alt-tabbing, work space switching, volume changing, etc. 
 
+Note: Even if set, grabbing of the keyboard is disabled under certain conditions, such as when the console is open.
+*/
+idCVar in_grabkeyboard( "in_grabkeyboard", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "When set, the keyboard is grabbed, so input goes exclusively to this game. When cleared the window manager is allowed to handle input from the keyboard." );
+/**
+When set, it grabs X's mouse input so that it's exclusively handled by the game. This will ensure the mouse is trapped to this winow.
+ */
+idCVar in_grabmouse( "in_grabmouse", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "When set, the mouse is grabbed, so input goes exclusively to this game." );
+
 // have a working xkb extension
 static bool have_xkb = false;
 
@@ -32,6 +43,11 @@
 // toggled by grab calls - decides if we ignore MotionNotify events
 static bool mouse_active = false;
 
+///Flags if the keyboard has been already been grabbed.
+static bool keyboard_grabbed = false;
+///Flags if the mouse has been already been grabbed.
+static bool mouse_grabbed = false;
+
 // non-DGA pointer-warping mouse input
 static int mwx, mwy;
 static int mx = 0, my = 0;
@@ -138,15 +154,19 @@
 	XSync( dpy, False );
 
 	XDefineCursor( dpy, win, Sys_XCreateNullCursor( dpy, win ) );
+
 	
-	XGrabPointer( dpy, win,
-				 False,
-				 MOUSE_MASK,
-				 GrabModeAsync, GrabModeAsync,
-				 win,
-				 None,
-				 CurrentTime );
-
+	if((vidmode_nowmfullscreen || in_grabmouse.GetBool()) && !mouse_grabbed) {
+		mouse_grabbed = true;
+		XGrabPointer( dpy, win,
+			      False,
+			      MOUSE_MASK,
+			      GrabModeAsync, GrabModeAsync,
+			      win,
+			      None,
+			      CurrentTime );
+	}
+		
 	XGetPointerControl( dpy, &mouse_accel_numerator, &mouse_accel_denominator,
 					   &mouse_threshold );
 	
@@ -171,12 +191,16 @@
 		mwy = glConfig.vidHeight / 2;
 		mx = my = 0;
 	}
+
+	/*Grab the keyboard if we're configured to grab it, or if we're doing full screen without the window manager.*/
+	if((vidmode_nowmfullscreen || in_grabkeyboard.GetBool()) && !keyboard_grabbed) {
+		keyboard_grabbed = true;
+		XGrabKeyboard( dpy, win,
+			       False,
+			       GrabModeAsync, GrabModeAsync,
+			       CurrentTime );
+	}
 	
-	XGrabKeyboard( dpy, win,
-				  False,
-				  GrabModeAsync, GrabModeAsync,
-				  CurrentTime );
-	
 	XSync( dpy, False );
 
 	mouse_active = true;
@@ -195,8 +219,14 @@
 	XChangePointerControl( dpy, true, true, mouse_accel_numerator, 
 						  mouse_accel_denominator, mouse_threshold );
 	
-	XUngrabPointer( dpy, CurrentTime );
-	XUngrabKeyboard( dpy, CurrentTime );
+	if(mouse_grabbed) {
+		XUngrabPointer( dpy, CurrentTime );
+		mouse_grabbed = false;
+	}
+	if(keyboard_grabbed) {
+		XUngrabKeyboard( dpy, CurrentTime );
+		keyboard_grabbed = false;
+	}
 	
 	XWarpPointer( dpy, None, win,
 				 0, 0, 0, 0,
@@ -219,6 +249,33 @@
 		#endif
 		return;
 	}
+	/*Check if the keyboard should be grabbed or ungrabbed.*/
+	if(!vidmode_nowmfullscreen && keyboard_grabbed && (!grabIt || !in_grabkeyboard.GetBool())) {
+		XUngrabKeyboard( dpy, CurrentTime );
+		keyboard_grabbed = false;
+	} else if((vidmode_nowmfullscreen || (grabIt && in_grabkeyboard.GetBool())) && !keyboard_grabbed) {
+		/*Grab the keyboard if we're configured to grab it and set to grab, or if we're doing full screen without the window manager.*/
+		keyboard_grabbed = true;
+		XGrabKeyboard( dpy, win,
+			       False,
+			       GrabModeAsync, GrabModeAsync,
+			       CurrentTime );
+	}
+
+	/*Check if the mouse should be grabbed or ungrabbed.*/
+	if(!vidmode_nowmfullscreen && mouse_grabbed && (!grabIt || !in_grabmouse.GetBool())) {
+		XUngrabPointer( dpy, CurrentTime );
+		mouse_grabbed = false;
+	} else if((vidmode_nowmfullscreen || (grabIt && in_grabmouse.GetBool())) && !mouse_grabbed) {
+		mouse_grabbed = true;
+		XGrabPointer( dpy, win,
+			      False,
+			      MOUSE_MASK,
+			      GrabModeAsync, GrabModeAsync,
+			      win,
+			      None,
+			      CurrentTime );
+	}
 	
 	if ( glConfig.isFullscreen ) {
 		if ( !grabIt ) {
Index: sys/linux/local.h
===================================================================
--- sys/linux/local.h	(revision 6527)
+++ sys/linux/local.h	(working copy)
@@ -34,6 +34,8 @@
 extern Display *dpy;
 extern Window win;
 
+extern bool vidmode_nowmfullscreen;
+
 // input.cpp
 extern bool dga_found;
 void Sys_XEvents();
NagaHuntress

NagaHuntress

11.08.2015 09:55

reporter   ~0007712

I've uploaded version 2 of the fix. This version adds the CVar 'in_grabmouse' to handle the mouse the same way the keyboard is handled. This will fix the bug where the mouse will be locked to the window until workspaces are switched.

The proper fix to the bug is detect focus loss and gain, and ungrab and grab respectively, however, I haven't had time to investigate that solution properly.

That said, this fix should work good enough for the bug, although it may have problems if the mouse moves fast enough to escape the window before being moved back to the center.
MirceaKitsune

MirceaKitsune

27.09.2015 00:23

reporter   ~0007804

I would like this please! I often alt + tab from fullscreen games to other windows on my system, but TDM doesn't currently allow this which is an annoyance. +1 to the patch.
stgatilov

stgatilov

21.09.2017 17:19

administrator   ~0009323

Well...
As I said, I cannot see how this patch affects a native Linux, since I have only a VM, and TDM works very weird in VM.
So I'm afraid I won't be able to accept this patch (I cannot test it properly).
nbohr1more

nbohr1more

21.09.2017 17:46

developer   ~0009324

I've pinged the Linux crew but thus far no takers. This may be moved to 2.07
grayman

grayman

14.12.2017 14:59

administrator   ~0009783

I only work in Windows, so I can't test it.

Since it's been 3 months since NB's post, with no response from anyone who can test the patch, I'm moving it to 2.07.
cabalistic

cabalistic

09.06.2018 18:49

developer   ~0010510

If there are no takers, assign it to me. I should be able to squeeze in some Linux dev time somewhere.
stgatilov

stgatilov

10.06.2018 13:25

administrator   ~0010513

Assigned to you.
If you integrate this feature and make sure it works well, it would be great! This is a long-awaited fix which most developers can't handle.
nbohr1more

nbohr1more

19.12.2018 18:00

developer   ~0010975

Ping?

Would this be possible before 2.07 beta is over?
cabalistic

cabalistic

19.12.2018 18:36

developer   ~0010979

I'll try to get some Linux coding time in over the holidays.
cabalistic

cabalistic

26.12.2018 08:07

developer   ~0011129

I applied the patch and gave it a spin. Keyboard handling works fine as advertised, including alt-tabbing. The mouse test is a bit inconclusive. For me, the mouse was still kept trapped in the window, but the WM did allow me to move it when holding ALT+TAB, so during that hold I can move the mouse outside and then use other windows. Not ideal, but might be WM-specific, and it's usable. Since I got no clue how to improve it further, I committed it.
stgatilov

stgatilov

26.12.2018 14:04

administrator   ~0011131

Just one minor rumble.

It would have been better it you commit this change to trunk and discuss including it into release on forums. The "target version" setting is followed only until beta starts, later all except minor changes should be discussed.

I'll built new Linux version and test it.
I found that if I disable "mouse integration", then mouse works normally inside VM =)
cabalistic

cabalistic

26.12.2018 15:10

developer   ~0011132

Sorry. nbohr specifically pinged me to include it into 2.07, and the change is relatively minor, so I didn't really think about it :-/
stgatilov

stgatilov

27.12.2018 16:49

administrator   ~0011147

Last edited: 27.12.2018 16:50

View 2 revisions

For me in VirtualBox it looks like this:
1) Windowed mode has not changed: when TDM is active, everything is normal. When I Alt+Tab, the window borders disappear, but rendered viewport is still on top. It may or may not be VM-specific.
2) I did not use fullscreen mode before. With the change it seems to work, and I can Alt+Tab: then TDM becomes invisible.
3) After running TDM my mouse cursor disappears. Maybe this was happening before change too --- not sure.
4) With the change mouselook is disabled when I Alt+Tab. When I alt+tab back, mouse movements move player forward/backward/sideways instead of rotating camera. This continues until I press left Alt+Shift, after that it seems to work. I suppose these are Ubuntu hotkeys, which are no longer suppressed.

Overally, I don't have positive impression from the change =)
It is still clumsy, and far behind what Windows build does. Maybe it's VM.

cabalistic

cabalistic

27.12.2018 17:33

developer   ~0011149

1) works fine on my Linux laptop.
3) not happening for me.
4) yes, I faced the same. I think the issue is that the game does register the ALT key press, but does not see the ALT release event because it loses focus in-between. So when you switch back to the game, it assumes that the ALT key is held and thus moves the player when moving the mouse. It was enough for me to press ALT key again.

So yeah, not ideal. Linux is fantastic for work (at least certain kinds), but terrible as a multimedia/gaming OS.

Issue History

Date Modified Username Field Change
30.07.2015 15:55 NagaHuntress New Issue
30.07.2015 15:55 NagaHuntress File Added: tdm-linux-window-manager-key-fix.diff
30.07.2015 16:48 SteveL Assigned To => SteveL
30.07.2015 16:48 SteveL Status new => assigned
30.07.2015 16:48 SteveL Status assigned => acknowledged
11.08.2015 09:49 NagaHuntress File Added: tdm-linux-window-manager-key-fix-v2.diff
11.08.2015 09:55 NagaHuntress Note Added: 0007712
27.09.2015 00:23 MirceaKitsune Note Added: 0007804
07.10.2016 04:21 nbohr1more Relationship added related to 0003568
22.11.2016 18:43 nbohr1more Relationship added related to 0004288
15.02.2017 04:37 grayman Assigned To SteveL =>
15.02.2017 04:37 grayman Status acknowledged => new
21.09.2017 17:10 nbohr1more Assigned To => stgatilov
21.09.2017 17:10 nbohr1more Status new => assigned
21.09.2017 17:10 nbohr1more Product Version => SVN
21.09.2017 17:10 nbohr1more Target Version => TDM 2.06
21.09.2017 17:18 stgatilov Assigned To stgatilov =>
21.09.2017 17:19 stgatilov Note Added: 0009323
21.09.2017 17:46 nbohr1more Note Added: 0009324
21.09.2017 19:04 nbohr1more Status assigned => confirmed
14.12.2017 14:59 grayman Note Added: 0009783
14.12.2017 14:59 grayman Target Version TDM 2.06 => TDM 2.07
09.06.2018 18:49 cabalistic Note Added: 0010510
10.06.2018 13:20 stgatilov Assigned To => cabalistic
10.06.2018 13:20 stgatilov Status confirmed => assigned
10.06.2018 13:25 stgatilov Note Added: 0010513
19.12.2018 18:00 nbohr1more Note Added: 0010975
19.12.2018 18:36 cabalistic Note Added: 0010979
26.12.2018 08:07 cabalistic Note Added: 0011129
26.12.2018 08:08 cabalistic Status assigned => resolved
26.12.2018 08:08 cabalistic Fixed in Version => TDM 2.07
26.12.2018 08:08 cabalistic Resolution open => fixed
26.12.2018 14:04 stgatilov Note Added: 0011131
26.12.2018 15:10 cabalistic Note Added: 0011132
27.12.2018 16:49 stgatilov Note Added: 0011147
27.12.2018 16:50 stgatilov Note Edited: 0011147 View Revisions
27.12.2018 17:33 cabalistic Note Added: 0011149