Setting Window Flags

The Window constructor of the servers/app/Window.cpp calls a function native to this class only which is SetFlags(flags, NULL);

#1 SetFlags(flags, NULL)

This function is defined at: src/servers/app/Window.cpp

The SetFlags function in the Window class is responsible for updating the window's flags and applying necessary changes based on the new flags.

void
Window::SetFlags(uint32 flags, BRegion* updateRegion)
{
	fOriginalFlags = flags;
	fFlags = flags & ValidWindowFlags(fFeel);
	if (!IsNormal())
		fFlags |= B_SAME_POSITION_IN_ALL_WORKSPACES;

	if ((fFlags & B_SAME_POSITION_IN_ALL_WORKSPACES) != 0)
		_PropagatePosition();

	::Decorator* decorator = Decorator();
	if (decorator == NULL)
		return;

	int32 stackPosition = PositionInStack();
	decorator->SetFlags(stackPosition, flags, updateRegion);

	// we might need to resize the window!
	decorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
	_ObeySizeLimits();

// TODO: not sure if we want to do this
#if 0
	if ((fOriginalFlags & kWindowScreenFlag) != (flags & kWindowScreenFlag)) {
		// TODO: disabling needs to be nestable (or we might lose the previous
		// update state)
		if ((flags & kWindowScreenFlag) != 0)
			DisableUpdateRequests();
		else
			EnableUpdateRequests();
	}
#endif
}

Parameters:

  • uint32 flags: The new flags to be set for the window.
  • BRegion* updateRegion (optional): A region specifying the area that needs to be updated due to flag changes.

Functionality:

  • The function first stores the original flags (fOriginalFlags) and then applies the new flags to fFlags, ensuring that only valid window flags for the current window feel are retained (flags & ValidWindowFlags(fFeel)).
  • If the window is not a normal window (e.g., modal, floating, etc.), it ensures that the B_SAME_POSITION_IN_ALL_WORKSPACES flag is set.
  • If the B_SAME_POSITION_IN_ALL_WORKSPACES flag is set, it propagates the window's position across all workspaces by calling _PropagatePosition. TODO _PropagatePosition()
  • It then retrieves the decorator associated with the window and sets the flags for the window in the decorator. The stackPosition variable determines the position of the window in the window stack. TODO PositionInStack().
  • After setting the flags in the decorator, the function retrieves the size limits from the decorator and applies them to the window using _ObeySizeLimits. TODO _ObeySIzeLimits().

#2 Window::ValidWindowFlags(feel)

This function is defined at: src/servers/app/Window.cpp

/*static*/ uint32
Window::ValidWindowFlags(window_feel feel)
{
	uint32 flags = ValidWindowFlags();
	if (IsModalFeel(feel))
		return flags & ~(B_AVOID_FOCUS | B_AVOID_FRONT);

	return flags;
}

ValidWindowFlags():

  • This function is called to obtain the bitmask of valid window flags without considering the window feel. It retrieves the basic set of valid flags for any window.

IsModalFeel(feel):

  • This function checks if the provided window feel corresponds to a modal window. If it does, it returns true; otherwise, it returns false.

Returning Adjusted Flags:

  • If the provided window feel (feel) is modal, the function modifies the set of valid flags.
  • It removes the B_AVOID_FOCUS and B_AVOID_FRONT flags from the bitmask of valid flags.
  • These flags are typically not applicable to modal windows since modal windows usually need to receive focus and be brought to the front for user interaction.
  • NOTE: I will give a simple illustration of how doing negation removes that particular flag from the bitmask.

Illustration of doing AND Operation on negative of a flag will remove that flag:

Suppose We have two flags B_NOT_MOVABLE and B_AVOID_FOCUS,

So the function ValidWindowFlags() will return BItwise OR operation with both of the flags:

B_NOT_MOVABLE = 0x1       = 0000 0000 0000 0001

B_AVOID_FOCUS = 0x2000 = 0010 0000 0000 0000

Bitwise OR operation (flagOR) =   0010 0000 0000 0001

flagOR & ~(B_AVOID_FOCUS);

Let's see what the above code will do:

~(B_AVOID_FOCUS) = 1101 1111 1111 1111

flagOR & ~(B_AVOID_FOCUS) = 0010 0000 0000 0001 & 1101 1111 1111 1111

 => 0000 0000 0000 0001 (which is only B_NOT_MOVABLE)

Returning the Final Flags:

  • After adjusting the flags based on the window feel, the function returns the final bitmask of valid window flags.

#3 Window::ValidWindowFlags()

/*static*/ uint32
Window::ValidWindowFlags()
{
	return B_NOT_MOVABLE
		| B_NOT_CLOSABLE
		| B_NOT_ZOOMABLE
		| B_NOT_MINIMIZABLE
		| B_NOT_RESIZABLE
		| B_NOT_H_RESIZABLE
		| B_NOT_V_RESIZABLE
		| B_AVOID_FRONT
		| B_AVOID_FOCUS
		| B_WILL_ACCEPT_FIRST_CLICK
		| B_OUTLINE_RESIZE
		| B_NO_WORKSPACE_ACTIVATION
		| B_NOT_ANCHORED_ON_ACTIVATE
		| B_ASYNCHRONOUS_CONTROLS
		| B_QUIT_ON_WINDOW_CLOSE
		| B_SAME_POSITION_IN_ALL_WORKSPACES
		| B_AUTO_UPDATE_SIZE_LIMITS
		| B_CLOSE_ON_ESCAPE
		| B_NO_SERVER_SIDE_WINDOW_MODIFIERS
		| kWindowScreenFlag
		| kAcceptKeyboardFocusFlag;
}
  1. B_NOT_MOVABLE (0x00000001): This flag indicates that the window is not movable by the user.
  2. B_NOT_CLOSABLE (0x00000020): Indicates that the window cannot be closed by the user.
  3. B_NOT_ZOOMABLE (0x00000040): Specifies that the window cannot be zoomed (maximized) by the user.
  4. B_NOT_MINIMIZABLE (0x00004000): Indicates that the window cannot be minimized by the user.
  5. B_NOT_RESIZABLE (0x00000002): Specifies that the window is not resizable.
  6. B_NOT_H_RESIZABLE (0x00000004): Indicates that the window cannot be horizontally resized.
  7. B_NOT_V_RESIZABLE (0x00000008): Indicates that the window cannot be vertically resized.
  8. B_AVOID_FRONT (0x00000080): Suggests to the window manager to avoid bringing the window to the front.
  9. B_AVOID_FOCUS (0x00002000): Suggests to the window manager to avoid giving focus to the window.
  10. B_WILL_ACCEPT_FIRST_CLICK (0x00000010): Specifies that the window will accept the first mouse click, even if it's not in focus.
  11. B_OUTLINE_RESIZE (0x00001000): Indicates that the window should show an outline when being resized.
  12. B_NO_WORKSPACE_ACTIVATION (0x00000100): Specifies that the window should not activate a workspace when opened.
  13. B_NOT_ANCHORED_ON_ACTIVATE (0x00020000): Specifies that the window should not be anchored when activated.
  14. B_ASYNCHRONOUS_CONTROLS (0x00080000): Allows the window's controls to operate asynchronously.
  15. B_QUIT_ON_WINDOW_CLOSE (0x00100000): Specifies that the application should quit when the window is closed.
  16. B_SAME_POSITION_IN_ALL_WORKSPACES (0x00200000): Specifies that the window should maintain the same position across all workspaces.
  17. B_AUTO_UPDATE_SIZE_LIMITS (0x00400000): Indicates that the window should automatically update its size limits.
  18. B_CLOSE_ON_ESCAPE (0x00800000): Allows the window to be closed when the escape key is pressed.
  19. B_NO_SERVER_SIDE_WINDOW_MODIFIERS (0x00000200): Specifies that window modifiers should not be handled on the server side.
  20. kWindowScreenFlag (0x10000): A custom flag for specifying screen-related behavior.
  21. kAcceptKeyboardFocusFlag (0x40000): A custom flag for specifying keyboard focus behavior.

Now, let's perform the bitwise OR operation on all these flags:

0x00000001 | 0x00000020 | 0x00000040 | 0x00004000 | 0x00000002 | 0x00000004 | 0x00000008 | 0x00000080 |
0x00002000 | 0x00000010 | 0x00001000 | 0x00000100 | 0x00020000 | 0x00080000 | 0x00100000 | 0x00200000 |
0x00400000 | 0x00800000 | 0x00000200 | 0x00010000 | 0x00040000

Performing the bitwise OR operation, we get:

0x00CFC1FF

So, the function Window::ValidWindowFlags() returns 0x00CFC1FF. This value represents the combined bitmask of all the valid window flags defined in the function.