Example #1
0
		internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
Example #2
0
		void SetWMStyles(Hwnd hwnd, CreateParams cp) {
			MotifWmHints		mwmHints;
			MotifFunctions		functions;
			MotifDecorations	decorations;
			int[]			atoms;
			int			atom_count;
			Rectangle		client_rect;
			Form			form;
			IntPtr			window_type;
			bool			hide_from_taskbar;
			IntPtr			transient_for_parent;
			
			// Windows we manage ourselves don't need WM window styles.
			if (cp.HasWindowManager && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
				return;
			}

			atoms = new int[8];
			mwmHints = new MotifWmHints();
			functions = 0;
			decorations = 0;
			window_type = _NET_WM_WINDOW_TYPE_NORMAL;
			transient_for_parent = IntPtr.Zero;

			mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
			mwmHints.functions = (IntPtr)0;
			mwmHints.decorations = (IntPtr)0;

			form = cp.control as Form;

			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
				/* tool windows get no window manager
				   decorations.
				*/

				/* just because the window doesn't get any decorations doesn't
				   mean we should disable the functions.  for instance, without
				   MotifFunctions.Maximize, changing the windowstate to Maximized
				   is ignored by metacity. */
				functions |= MotifFunctions.Move | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize;
			} else if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
				/* allow borderless window to be maximized */
				functions |= MotifFunctions.All | MotifFunctions.Resize;
			} else {
				if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
					functions |= MotifFunctions.Move;
					decorations |= MotifDecorations.Title | MotifDecorations.Menu;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_THICKFRAME)) {
					functions |= MotifFunctions.Move | MotifFunctions.Resize;
					decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
					functions |= MotifFunctions.Minimize;
					decorations |= MotifDecorations.Minimize;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
					functions |= MotifFunctions.Maximize;
					decorations |= MotifDecorations.Maximize;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_SIZEBOX)) {
					functions |= MotifFunctions.Resize;
					decorations |= MotifDecorations.ResizeH;
				}

				if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
					decorations |= MotifDecorations.Border;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_BORDER)) {
					decorations |= MotifDecorations.Border;
				}
			
				if (StyleSet (cp.Style, WindowStyles.WS_DLGFRAME)) {
					decorations |= MotifDecorations.Border;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
					functions |= MotifFunctions.Close;
				}
				else {
					functions &= ~(MotifFunctions.Maximize | MotifFunctions.Minimize | MotifFunctions.Close);
					decorations &= ~(MotifDecorations.Menu | MotifDecorations.Maximize | MotifDecorations.Minimize);
					if (cp.Caption == "") {
						functions &= ~MotifFunctions.Move;
						decorations &= ~(MotifDecorations.Title | MotifDecorations.ResizeH);
					}
				}
			}

			if ((functions & MotifFunctions.Resize) == 0) {
				hwnd.fixed_size = true;
				Rectangle fixed_rectangle = new Rectangle (cp.X, cp.Y, cp.Width, cp.Height);
				SetWindowMinMax(hwnd.Handle, fixed_rectangle, fixed_rectangle.Size, fixed_rectangle.Size, cp);
			} else {
				hwnd.fixed_size = false;
			}

			mwmHints.functions = (IntPtr)functions;
			mwmHints.decorations = (IntPtr)decorations;

			DriverDebug ("SetWMStyles ({0}, {1}) functions = {2}, decorations = {3}", hwnd, cp, functions, decorations);

			if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
				// needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
				// and get those windows in front of their parents
				window_type = _NET_WM_WINDOW_TYPE_UTILITY;
			} else {
				window_type = _NET_WM_WINDOW_TYPE_NORMAL;
			}
			
			if (!cp.IsSet (WindowExStyles.WS_EX_APPWINDOW)) {
				hide_from_taskbar = true;
			} else if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW) &&  form != null && form.Parent != null && !form.ShowInTaskbar) {
				hide_from_taskbar = true;
			} else {
				hide_from_taskbar = false;
			}

			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
				if (form != null && !hwnd.reparented) {
					if (form.Owner != null && form.Owner.Handle != IntPtr.Zero) {
						Hwnd owner_hwnd = Hwnd.ObjectFromHandle (form.Owner.Handle);
						if (owner_hwnd != null)
							transient_for_parent = owner_hwnd.whole_window;
					}
				}
			} 
			if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
				transient_for_parent = hwnd.parent.whole_window;
			}
			
			FormWindowState current_state = GetWindowState (hwnd.Handle);
			if (current_state == (FormWindowState)(-1))
				current_state = FormWindowState.Normal;

			client_rect = TranslateClientRectangleToXClientRectangle (hwnd);

			lock (XlibLock) {
				atom_count = 0;

				atoms [0] = window_type.ToInt32 ();
				XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);

				XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);

				if (transient_for_parent != IntPtr.Zero) {
					XSetTransientForHint (DisplayHandle, hwnd.whole_window, transient_for_parent);
				}

				MoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);

				if (hide_from_taskbar) {
					/* this line keeps the window from showing up in gnome's taskbar */
					atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
				}
				/* we need to add these atoms in the
				 * event we're maximized, since we're
				 * replacing the existing
				 * _NET_WM_STATE here.  If we don't
				 * add them, future calls to
				 * GetWindowState will return Normal
				 * for a window which is maximized. */
				if (current_state == FormWindowState.Maximized) {
					atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_HORZ.ToInt32();
					atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_VERT.ToInt32();
				}
				
				if (form != null && form.Modal) {
					atoms[atom_count++] = _NET_WM_STATE_MODAL.ToInt32 ();
				}
				
				XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);

				atom_count = 0;
				IntPtr[] atom_ptrs = new IntPtr[2];
				atom_ptrs[atom_count++] = WM_DELETE_WINDOW;
				if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_CONTEXTHELP)) {
					atom_ptrs[atom_count++] = _NET_WM_CONTEXT_HELP;
				}

				XSetWMProtocols(DisplayHandle, hwnd.whole_window, atom_ptrs, atom_count);
			}
		}
Example #3
0
		internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements)
		{
			DebugHelper.TraceWriteLine ("XChangeProperty");
			return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
		}
Example #4
0
		public void SetWMStyles (CreateParams cp)
		{
			MotifWmHints mwmHints;
			MotifFunctions functions;
			MotifDecorations decorations;
			IntPtr[] atoms;
			int atom_count;
			Rectangle client_rect;

			// Child windows don't need WM window styles
			if (StyleSet (cp.Style, WindowStyles.WS_CHILDWINDOW))
				return;

			atoms = new IntPtr[8];
			mwmHints = new MotifWmHints();
			functions = 0;
			decorations = 0;

			mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
			mwmHints.functions = (IntPtr)0;
			mwmHints.decorations = (IntPtr)0;

			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)
			    || !StyleSet (cp.Style, WindowStyles.WS_CAPTION | WindowStyles.WS_BORDER | WindowStyles.WS_DLGFRAME)) {
				/* tool windows get no window manager
				   decorations, and neither do windows
				   which lack CAPTION/BORDER/DLGFRAME
				   styles.
				*/

				/* just because the window doesn't get any decorations doesn't
				   mean we should disable the functions.  for instance, without
				   MotifFunctions.Maximize, changing the windowstate to Maximized
				   is ignored by metacity. */
				functions |= MotifFunctions.Move | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize;
			}
			else {
				if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
					functions |= MotifFunctions.Move;
					decorations |= MotifDecorations.Title | MotifDecorations.Menu;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_THICKFRAME)) {
					functions |= MotifFunctions.Move | MotifFunctions.Resize;
					decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
					functions |= MotifFunctions.Minimize;
					decorations |= MotifDecorations.Minimize;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
					functions |= MotifFunctions.Maximize;
					decorations |= MotifDecorations.Maximize;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_SIZEBOX)) {
					functions |= MotifFunctions.Resize;
					decorations |= MotifDecorations.ResizeH;
				}

				if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
					decorations |= MotifDecorations.Border;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_BORDER)) {
					decorations |= MotifDecorations.Border;
				}
			
				if (StyleSet (cp.Style, WindowStyles.WS_DLGFRAME)) {
					decorations |= MotifDecorations.Border;
				}

				if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
					functions |= MotifFunctions.Close;
				}
				else {
					functions &= ~(MotifFunctions.Maximize | MotifFunctions.Minimize | MotifFunctions.Close);
					decorations &= ~(MotifDecorations.Menu | MotifDecorations.Maximize | MotifDecorations.Minimize);
					if (cp.Caption == "") {
						functions &= ~MotifFunctions.Move;
						decorations &= ~(MotifDecorations.Title | MotifDecorations.ResizeH);
					}
				}
			}

			if ((functions & MotifFunctions.Resize) == 0) {
				fixed_size = true;
				SetMinMax (new Rectangle(cp.X, cp.Y, cp.Width, cp.Height), new Size(cp.Width, cp.Height), new Size(cp.Width, cp.Height));
			} else {
				fixed_size = false;
			}

			mwmHints.functions = (IntPtr)functions;
			mwmHints.decorations = (IntPtr)decorations;

			FormWindowState current_state = GetWindowState ();
			if (current_state == (FormWindowState)(-1))
				current_state = FormWindowState.Normal;

			client_rect = ClientRect;

			atom_count = 0;

			// needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
			// and get those windows in front of their parents
			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
				WINDOW_TYPE = display.Atoms._NET_WM_WINDOW_TYPE_UTILITY;

				Form f = Control.FromHandle(Handle) as Form;
				if (f != null && !reparented) {
					if (f.Owner != null && f.Owner.Handle != IntPtr.Zero) {
						Hwnd owner_hwnd = Hwnd.ObjectFromHandle(f.Owner.Handle);
						if (owner_hwnd != null)
							Xlib.XSetTransientForHint (display.Handle, WholeWindow,
										   owner_hwnd.WholeWindow);
					}
				}
			}
				
			Xlib.XChangeProperty (display.Handle, WholeWindow,
					      display.Atoms._MOTIF_WM_HINTS, display.Atoms._MOTIF_WM_HINTS, 32,
					      PropertyMode.Replace, ref mwmHints, 5);

			if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (parent != null) && (parent.WholeWindow != IntPtr.Zero)) {
				WINDOW_TYPE = display.Atoms._NET_WM_WINDOW_TYPE_NORMAL;
				Xlib.XSetTransientForHint(display.Handle, WholeWindow, parent.WholeWindow);
			} else if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_APPWINDOW)) {
				/* this line keeps the window from showing up in gnome's taskbar */
				atoms[atom_count++] = display.Atoms._NET_WM_STATE_SKIP_TASKBAR;
			}
			if ((client_rect.Width < 1) || (client_rect.Height < 1)) {
				Xlib.XMoveResizeWindow (display.Handle, ClientWindow, -5, -5, 1, 1);
			} else {
				Xlib.XMoveResizeWindow (display.Handle, ClientWindow, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
			}

			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW))
				atoms[atom_count++] = display.Atoms._NET_WM_STATE_SKIP_TASKBAR;

			/* we need to add these atoms in the
			 * event we're maximized, since we're
			 * replacing the existing
			 * _NET_WM_STATE here.  If we don't
			 * add them, future calls to
			 * GetWindowState will return Normal
			 * for a window which is maximized. */
			if (current_state == FormWindowState.Maximized) {
				atoms[atom_count++] = display.Atoms._NET_WM_STATE_MAXIMIZED_HORZ;
				atoms[atom_count++] = display.Atoms._NET_WM_STATE_MAXIMIZED_VERT;
			}

			Set_WM_STATE (atoms, atom_count);

			atom_count = 0;
			atoms[atom_count++] = display.Atoms.WM_DELETE_WINDOW;
			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_CONTEXTHELP))
				atoms[atom_count++] = display.Atoms._NET_WM_CONTEXT_HELP;

			Xlib.XSetWMProtocols (display.Handle, WholeWindow, atoms, atom_count);
		}