/* readonly attribute boolean isCompositionEnabled; */
NS_IMETHODIMP
sbWindowChromeService::GetIsCompositionEnabled(bool *aIsCompositionEnabled)
{
  NS_ENSURE_ARG_POINTER(aIsCompositionEnabled);
  *aIsCompositionEnabled = IsCompositionEnabled(this);
  return NS_OK;
}
Exemplo n.º 2
0
	bool DwmFunctions::is_composition_enabled()
	{
		if (IsCompositionEnabled)
		{
			BOOL is_enabled = FALSE;
			HRESULT result = IsCompositionEnabled(&is_enabled);
			return SUCCEEDED(result) && is_enabled == TRUE;
		}
		else
		{
			return false;
		}
	}
Exemplo n.º 3
0
bool FD3D11Viewport::Present(bool bLockToVsync)
{
	bool bNativelyPresented = true;
#if	D3D11_WITH_DWMAPI
	// We can't call Present if !bIsValid, as it waits a window message to be processed, but the main thread may not be pumping the message handler.
	if(bIsValid)
	{
		// Check if the viewport's swap chain has been invalidated by DXGI.
		BOOL bSwapChainFullscreenState;
		TRefCountPtr<IDXGIOutput> SwapChainOutput;
		VERIFYD3D11RESULT(SwapChain->GetFullscreenState(&bSwapChainFullscreenState,SwapChainOutput.GetInitReference()));
		// Can't compare BOOL with bool...
		if ( (!!bSwapChainFullscreenState)  != bIsFullscreen )
		{
			bIsValid = false;
			
			// Minimize the window.
			// use SW_FORCEMINIMIZE if the messaging thread is likely to be blocked for a sizeable period.
			// SW_FORCEMINIMIZE also prevents the minimize animation from playing.
			::ShowWindow(WindowHandle,SW_MINIMIZE);
		}
	}


	// When desktop composition is enabled, locking to vsync via the Present
	// call is unreliable. Instead, communicate with the desktop window manager
	// directly to enable vsync.
	const bool bSyncWithDWM = bLockToVsync && !bIsFullscreen && RHIConsoleVariables::bSyncWithDWM && IsCompositionEnabled();
	if (bSyncWithDWM)
	{
		PresentWithVsyncDWM();
	}
	else
#endif	//D3D11_WITH_DWMAPI
	{
		// Present the back buffer to the viewport window.
		bNativelyPresented = PresentChecked(bLockToVsync ? RHIConsoleVariables::SyncInterval : 0);
	}
	return bNativelyPresented;
}
Exemplo n.º 4
0
bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result) {
	using ShadowsChange = MainWindow::ShadowsChange;

	if (auto tbCreatedMsgId = Platform::MainWindow::TaskbarCreatedMsgId()) {
		if (msg == tbCreatedMsgId) {
			Platform::MainWindow::TaskbarCreated();
		}
	}

	switch (msg) {

	case WM_TIMECHANGE: {
		if (AuthSession::Exists()) {
			Auth().checkAutoLockIn(100);
		}
	} return false;

	case WM_WTSSESSION_CHANGE: {
		if (wParam == WTS_SESSION_LOGOFF || wParam == WTS_SESSION_LOCK) {
			setSessionLoggedOff(true);
		} else if (wParam == WTS_SESSION_LOGON || wParam == WTS_SESSION_UNLOCK) {
			setSessionLoggedOff(false);
		}
	} return false;

	case WM_DESTROY: {
		App::quit();
	} return false;

	case WM_ACTIVATE: {
		if (LOWORD(wParam) == WA_CLICKACTIVE) {
			App::wnd()->setInactivePress(true);
		}
		if (LOWORD(wParam) != WA_INACTIVE) {
			App::wnd()->shadowsActivate();
		} else {
			App::wnd()->shadowsDeactivate();
		}
		if (Global::started()) {
			App::wnd()->update();
		}
	} return false;

	case WM_NCPAINT: {
		if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
		if (result) *result = 0;
	} return true;

	case WM_NCCALCSIZE: {
		WINDOWPLACEMENT wp;
		wp.length = sizeof(WINDOWPLACEMENT);
		if (GetWindowPlacement(hWnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
			LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam;
			LPRECT r = (wParam == TRUE) ? &params->rgrc[0] : (LPRECT)lParam;
			HMONITOR hMonitor = MonitorFromPoint({ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, MONITOR_DEFAULTTONEAREST);
			if (hMonitor) {
				MONITORINFO mi;
				mi.cbSize = sizeof(mi);
				if (GetMonitorInfo(hMonitor, &mi)) {
					*r = mi.rcWork;
				}
			}
		}
		if (result) *result = 0;
		return true;
	}

	case WM_NCACTIVATE: {
		if (IsCompositionEnabled()) {
			const auto res = DefWindowProc(hWnd, msg, wParam, -1);
			if (result) *result = res;
		} else {
			// Thanks https://github.com/melak47/BorderlessWindow
			if (result) *result = 1;
		}
	} return true;

	case WM_WINDOWPOSCHANGING:
	case WM_WINDOWPOSCHANGED: {
		WINDOWPLACEMENT wp;
		wp.length = sizeof(WINDOWPLACEMENT);
		if (GetWindowPlacement(hWnd, &wp) && (wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED)) {
			App::wnd()->shadowsUpdate(ShadowsChange::Hidden);
		} else {
			App::wnd()->shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized, (WINDOWPOS*)lParam);
		}
	} return false;

	case WM_SIZE: {
		if (App::wnd()) {
			if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) {
				if (wParam != SIZE_RESTORED || App::wnd()->windowState() != Qt::WindowNoState) {
					Qt::WindowState state = Qt::WindowNoState;
					if (wParam == SIZE_MAXIMIZED) {
						state = Qt::WindowMaximized;
					} else if (wParam == SIZE_MINIMIZED) {
						state = Qt::WindowMinimized;
					}
					emit App::wnd()->windowHandle()->windowStateChanged(state);
				} else {
					App::wnd()->positionUpdated();
				}
				App::wnd()->psUpdateMargins();
				MainWindow::ShadowsChanges changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? ShadowsChange::Hidden : (ShadowsChange::Resized | ShadowsChange::Shown);
				App::wnd()->shadowsUpdate(changes);
			}
		}
	} return false;

	case WM_SHOWWINDOW: {
		LONG style = GetWindowLong(hWnd, GWL_STYLE);
		auto changes = ShadowsChange::Resized | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) ? ShadowsChange::Shown : ShadowsChange::Hidden);
		App::wnd()->shadowsUpdate(changes);
	} return false;

	case WM_MOVE: {
		App::wnd()->shadowsUpdate(ShadowsChange::Moved);
		App::wnd()->positionUpdated();
	} return false;

	case WM_NCHITTEST: {
		if (!result) return false;

		POINTS p = MAKEPOINTS(lParam);
		RECT r;
		GetWindowRect(hWnd, &r);
		auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
		switch (res) {
		case Window::HitTestResult::Client:
		case Window::HitTestResult::SysButton:   *result = HTCLIENT; break;
		case Window::HitTestResult::Caption:     *result = HTCAPTION; break;
		case Window::HitTestResult::Top:         *result = HTTOP; break;
		case Window::HitTestResult::TopRight:    *result = HTTOPRIGHT; break;
		case Window::HitTestResult::Right:       *result = HTRIGHT; break;
		case Window::HitTestResult::BottomRight: *result = HTBOTTOMRIGHT; break;
		case Window::HitTestResult::Bottom:      *result = HTBOTTOM; break;
		case Window::HitTestResult::BottomLeft:  *result = HTBOTTOMLEFT; break;
		case Window::HitTestResult::Left:        *result = HTLEFT; break;
		case Window::HitTestResult::TopLeft:     *result = HTTOPLEFT; break;
		case Window::HitTestResult::None:
		default:                                 *result = HTTRANSPARENT; break;
		};
	} return true;

	case WM_NCRBUTTONUP: {
		SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
	} return true;

	case WM_SYSCOMMAND: {
		if (wParam == SC_MOUSEMENU) {
			POINTS p = MAKEPOINTS(lParam);
			App::wnd()->updateSystemMenu(App::wnd()->windowHandle()->windowState());
			TrackPopupMenu(App::wnd()->psMenu(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, p.x, p.y, 0, hWnd, 0);
		}
	} return false;

	case WM_COMMAND: {
		if (HIWORD(wParam)) return false;
		int cmd = LOWORD(wParam);
		switch (cmd) {
		case SC_CLOSE: App::wnd()->close(); return true;
		case SC_MINIMIZE: App::wnd()->setWindowState(Qt::WindowMinimized); return true;
		case SC_MAXIMIZE: App::wnd()->setWindowState(Qt::WindowMaximized); return true;
		case SC_RESTORE: App::wnd()->setWindowState(Qt::WindowNoState); return true;
		}
	} return true;

	}
	return false;
}
/* static */
LRESULT
sbWindowChromeService::WndProc(HWND hWnd,
                               UINT uMsg,
                               WPARAM wParam,
                               LPARAM lParam,
                               UINT_PTR uIdSubclass,
                               DWORD_PTR dwRefData)
{
  if (uIdSubclass != gSubclassId) {
    // We're majorly screwed up somehow; do nothing
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
  }
  TRACE(("%s: WndProc(%p, %08x)", __FUNCTION__, hWnd, uMsg));
  switch (uMsg) {
  case WM_NCDESTROY:
  {
    // clean up
    RemoveWindowSubclass(hWnd, &sbWindowChromeService::WndProc, uIdSubclass);
    break;
  }
  case WM_NCCALCSIZE:
  {
    if (!(BOOL)wParam) {
      // we do not need to do anything special for this case
      break;
    }
    NCCALCSIZE_PARAMS* params = (NCCALCSIZE_PARAMS*)lParam;
    bool willMinimize = (params->rgrc[0].left == -32000) &&
                        (params->rgrc[0].top  == -32000);
    if (willMinimize) {
      // we are going to minimize; don't touch anything
      break;
    }
    if (IsZoomed(hWnd)) {
      // On Windows 7, Windows will adjust the size of the maximized windows
      // so that they're larger than the screen to account for the window
      // border (even with Aero disabled).  On XP, however, it does _not_ do
      // that.  So, figure out how big the window wants to be, and how big the
      // screen is, and go for the closest solution.
      RECT* rectWindow = &params->rgrc[0]; // shorthand
      RECT rectMon = {0};
      int xSize = ::GetSystemMetrics(SM_CXSIZEFRAME);
      int ySize = ::GetSystemMetrics(SM_CYSIZEFRAME);
      // Bug 21344 - HMONITOR's are not handles
      HMONITOR hMon = ::MonitorFromRect(rectWindow, MONITOR_DEFAULTTONULL);
      if (hMon) {
        MONITORINFO monInfo = {0};
        monInfo.cbSize = sizeof(monInfo);
        BOOL success = ::GetMonitorInfo(hMon, &monInfo);
        if (success) {
          ::CopyRect(&rectMon, &monInfo.rcWork);
        }
        else {
          ::CopyRect(&rectMon, rectWindow);
        }
      }
      else {
        // no monitor!?
        ::CopyRect(&rectMon, rectWindow);
      }

      const LONG TOLERANCE = 2;
      if (rectMon.top > rectWindow->top &&
          rectMon.top - rectWindow->top < ySize + TOLERANCE)
      {
        rectWindow->top += ySize;
      }
      if (rectWindow->bottom > rectMon.bottom &&
          rectWindow->bottom - rectMon.bottom < ySize + TOLERANCE)
      {
        rectWindow->bottom -= ySize;
      }
      if (rectMon.left > rectWindow->left &&
          rectMon.left - rectWindow->left < xSize + TOLERANCE)
      {
        rectWindow->left += xSize;
      }
      if (rectWindow->right > rectMon.right &&
          rectWindow->right - rectMon.right < xSize + TOLERANCE)
      {
        rectWindow->right -= xSize;
      }

      // Chop off one pixel on any edge with auto-hidden taskbars (deskbars,
      // really).  This is required to make sure those taskbars will remain
      // functional (i.e. pop up) when the mouse goes near them - otherwise
      // Windows assumes we really meant to be a full screen window instead.
      APPBARDATA appbarData = {sizeof(APPBARDATA)};
      appbarData.hWnd = hWnd;
      HWND wnd;
      // Bug 21344 - HMONITOR's are not handles
      HMONITOR selfMon = ::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
               targetMon;

      appbarData.uEdge = ABE_TOP;
      wnd = (HWND)::SHAppBarMessage(ABM_GETAUTOHIDEBAR, &appbarData);
      if (wnd) {
        targetMon = ::MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
        if (targetMon == selfMon) {
          // instead of bumping the window down, subtract a pixel from the
          // bottom instead - otherwise we end up exposing a pixel of the
          // top which 1) can lead to clicking on nearly-invisible widgets (e.g.
          // the close button), 2) loses fitt's law gains of having things at top
          params->rgrc[0].bottom -= 1;
        }
      }
      appbarData.uEdge = ABE_RIGHT;
      wnd = (HWND)::SHAppBarMessage(ABM_GETAUTOHIDEBAR, &appbarData);
      if (wnd) {
        targetMon = ::MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
        if (targetMon == selfMon) {
          params->rgrc[0].right -= 1;
        }
      }
      appbarData.uEdge = ABE_BOTTOM;
      wnd = (HWND)::SHAppBarMessage(ABM_GETAUTOHIDEBAR, &appbarData);
      if (wnd) {
        targetMon = ::MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
        if (targetMon == selfMon) {
          params->rgrc[0].bottom -= 1;
        }
      }
      appbarData.uEdge = ABE_LEFT;
      wnd = (HWND)::SHAppBarMessage(ABM_GETAUTOHIDEBAR, &appbarData);
      if (wnd) {
        targetMon = ::MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
        if (targetMon == selfMon) {
          params->rgrc[0].left += 1;
        }
      }
      return 0;
    }
    // we have a window we want to hook, but it's not maximized; leave the
    // rectangles as-is, meaning that there should be no non-client area (i.e.
    // no chrome at all).
    return 0;
  }
  case WM_NCACTIVATE:
  {
    if (IsCompositionEnabled((sbWindowChromeService*)uIdSubclass)) {
      // When DWM composition is enabled, call the default handler so that
      // it draws the window shadow.  In this case the window is also double
      // buffered (by the DWM), so we don't have to worry about flickering.
      
      // We skip doing this if we're maximized (or look like we are, since that
      // is how Mozilla implemented full screen) to avoid problems with the
      // video window showing the (win9x) non-client area.  We don't need to
      // have shadows in that case anyway.
      RECT rectMon = {0}, rectWindow;
      BOOL success = ::GetWindowRect(hWnd, &rectWindow);
      if (!success) {
        ::SetRect(&rectWindow, -1, -1, -1, -1);
      }
      // Bug 21344 - HMONITOR's are not handles
      HMONITOR hMon = ::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONULL);
      if (hMon) {
        MONITORINFO monInfo = {0};
        monInfo.cbSize = sizeof(monInfo);
        success = ::GetMonitorInfo(hMon, &monInfo);
        if (success) {
          ::CopyRect(&rectMon, &monInfo.rcMonitor);
        }
      }
      if (!::EqualRect(&rectMon, &rectWindow)) {
        return DefSubclassProc(hWnd, uMsg, wParam, lParam);
      }
    }
    else {
      // Let's turn off themes to make sure our borders don't get rounded!
      ::SetWindowTheme(hWnd, L"", L"");
    }
    // No DWM, don't do anything to avoid extra paints of the non-client area
    // which causes bad flickering.
    return TRUE;
  }
  case WM_NCPAINT:
  {
    TRACE(("WM_NCPAINT(%p)", hWnd));
    // We need to call the default implementation in order to get window shadow.
    // Since that only works when DWM is enabled anyway, check if it is - if it
    // is not, do not call the default implementation since that causes flicker
    // on systems with theming but not DWM (e.g. XP, or Vista with 16bpp).
    if (!IsCompositionEnabled((sbWindowChromeService*)uIdSubclass)) {
      // no need to do anything; however, invalidate the window anyway in case
      // this paint was caused by invalidation.
      InvalidateRgn(hWnd, NULL, FALSE);
      return 0;
    }
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
  }
  case 0xAE: /* undocumented: WM_NCUAHDRAWCAPTION */
  case 0xAF: /* undocumented: WM_NCUAHDRAWFRAME */
    // these messages, according to chromium.org, are sent by Windows to redraw
    // the caption / frame at unpredictable times.  Intercept these and don't
    // use the default behaviour.
    return 0;
  }
  return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}