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();
