Dispatch (WIN32 only) and handle a new cross platform message NS_SYSCOLORCHANGE. bug 143174. r=rods sr=roc

This commit is contained in:
kmcclusk%netscape.com 2002-06-04 17:47:54 +00:00
parent a2ea2ebb45
commit 0a88931ae5
13 changed files with 201 additions and 2 deletions

View File

@ -1775,6 +1775,28 @@ nsPresContext::ThemeChanged()
return mShell->ReconstructStyleData(PR_FALSE);
}
NS_IMETHODIMP
nsPresContext::SysColorChanged()
{
if (mLookAndFeel) {
// Don't use the cached values for the system colors
mLookAndFeel->LookAndFeelChanged();
}
// Reset default background and foreground colors for the document since
// they may be using system colors
GetDocumentColorPreferences();
// Clear out all of the style data since it may contain RGB values
// which originated from system colors.
if (mShell) {
// Clear out all our style data.
nsCOMPtr<nsIStyleSet> set;
mShell->GetStyleSet(getter_AddRefs(set));
set->ClearStyleData(this, nsnull, nsnull);
}
return NS_OK;
}
#ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP

View File

@ -535,6 +535,11 @@ public:
*/
NS_IMETHOD ThemeChanged() = 0;
/*
* Notify the pres context that a system color has changed
*/
NS_IMETHOD SysColorChanged() = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRendingContext, nsIFrame * aFrame, PRUint32 aColor) = 0;

View File

@ -5922,6 +5922,25 @@ PresShell::HandleEvent(nsIView *aView,
if (aEvent->message == NS_THEMECHANGED && mPresContext)
return mPresContext->ThemeChanged();
// Check for a system color change up front, since the frame type is irrelevenat
if ((aEvent->message == NS_SYSCOLORCHANGED) && mPresContext) {
nsIViewManager *vm;
if ((NS_SUCCEEDED(GetViewManager(&vm))) && vm) {
// Only dispatch system color change when the message originates from
// from the root views widget. This is necessary to prevent us from
// dispatching the SysColorChanged notification for each child window
// which may be redundant.
nsIView *view;
vm->GetRootView(view);
if (view == aView) {
aHandled = PR_TRUE;
*aEventStatus = nsEventStatus_eConsumeDoDefault;
return mPresContext->SysColorChanged();
}
}
return NS_OK;
}
aView->GetClientData(clientData);
frame = (nsIFrame *)clientData;

View File

@ -535,6 +535,11 @@ public:
*/
NS_IMETHOD ThemeChanged() = 0;
/*
* Notify the pres context that a system color has changed
*/
NS_IMETHOD SysColorChanged() = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRendingContext, nsIFrame * aFrame, PRUint32 aColor) = 0;

View File

@ -535,6 +535,11 @@ public:
*/
NS_IMETHOD ThemeChanged() = 0;
/*
* Notify the pres context that a system color has changed
*/
NS_IMETHOD SysColorChanged() = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRendingContext, nsIFrame * aFrame, PRUint32 aColor) = 0;

View File

@ -1775,6 +1775,28 @@ nsPresContext::ThemeChanged()
return mShell->ReconstructStyleData(PR_FALSE);
}
NS_IMETHODIMP
nsPresContext::SysColorChanged()
{
if (mLookAndFeel) {
// Don't use the cached values for the system colors
mLookAndFeel->LookAndFeelChanged();
}
// Reset default background and foreground colors for the document since
// they may be using system colors
GetDocumentColorPreferences();
// Clear out all of the style data since it may contain RGB values
// which originated from system colors.
if (mShell) {
// Clear out all our style data.
nsCOMPtr<nsIStyleSet> set;
mShell->GetStyleSet(getter_AddRefs(set));
set->ClearStyleData(this, nsnull, nsnull);
}
return NS_OK;
}
#ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP

View File

@ -199,6 +199,7 @@ public:
NS_IMETHOD GetTheme(nsITheme** aResult);
NS_IMETHOD ThemeChanged();
NS_IMETHOD SysColorChanged();
protected:
nsPresContext();

View File

@ -5922,6 +5922,25 @@ PresShell::HandleEvent(nsIView *aView,
if (aEvent->message == NS_THEMECHANGED && mPresContext)
return mPresContext->ThemeChanged();
// Check for a system color change up front, since the frame type is irrelevenat
if ((aEvent->message == NS_SYSCOLORCHANGED) && mPresContext) {
nsIViewManager *vm;
if ((NS_SUCCEEDED(GetViewManager(&vm))) && vm) {
// Only dispatch system color change when the message originates from
// from the root views widget. This is necessary to prevent us from
// dispatching the SysColorChanged notification for each child window
// which may be redundant.
nsIView *view;
vm->GetRootView(view);
if (view == aView) {
aHandled = PR_TRUE;
*aEventStatus = nsEventStatus_eConsumeDoDefault;
return mPresContext->SysColorChanged();
}
}
return NS_OK;
}
aView->GetClientData(clientData);
frame = (nsIFrame *)clientData;

View File

@ -1798,7 +1798,17 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
}
break;
case NS_SYSCOLORCHANGED:
{
nsView *view = nsView::GetViewFor(aEvent->widget);
nsCOMPtr<nsIViewObserver> obs;
GetViewObserver(*getter_AddRefs(obs));
if (obs) {
PRBool handled;
obs->HandleEvent(view, aEvent, aStatus, PR_TRUE, handled);
}
}
break;
default:
{
@ -2029,7 +2039,7 @@ nsEventStatus nsViewManager::HandleEvent(nsView* aView, nsGUIEvent* aEvent, PRBo
}
return status;
}
nsAutoVoidArray targetViews;
nsAutoVoidArray heldRefCountsToOtherVMs;

View File

@ -449,6 +449,11 @@ enum nsDragDropEventStatus {
// Indicates a theme change has occurred
#define NS_THEMECHANGED (NS_WINDOW_START + 41)
// Indicates a System color has changed. It is the platform
// toolkits responsibility to invalidate the window to
// ensure that it is drawn using the current system colors.
#define NS_SYSCOLORCHANGED (NS_WINDOW_START + 42)
// Indicates a script error has occurred
#define NS_SCRIPT_ERROR (NS_WINDOW_START + 50)

View File

@ -370,6 +370,21 @@ LRESULT CALLBACK nsToolkit::WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
MethodInfo *info = (MethodInfo *)lParam;
return info->Invoke();
}
case WM_SYSCOLORCHANGE:
{
// WM_SYSCOLORCHANGE messages are only dispatched to top
// level windows but NS_SYSCOLORCHANGE messages must be dispatched
// to all windows including child windows. We dispatch these messages
// from the nsToolkit because if we are running embedded we may not
// have a top-level nsIWidget window.
// On WIN32 all windows are automatically invalidated after the
// WM_SYSCOLORCHANGE is dispatched so the window is drawn using
// the current system colors.
nsWindow::GlobalMsgWindowProc(hWnd, msg, wParam, lParam);
}
}
#ifdef MOZ_AIMM

View File

@ -644,6 +644,63 @@ private:
static nsAttentionTimerMonitor *gAttentionTimerMonitor = 0;
// Code to dispatch WM_SYSCOLORCHANGE message to all child windows.
// WM_SYSCOLORCHANGE is only sent to top-level windows, but the
// cross platform API requires that NS_SYSCOLORCHANGE message be sent to
// all child windows as well. When running in an embedded application
// we may not receive a WM_SYSCOLORCHANGE message because the top
// level window is owned by the embeddor. Note: this code can be used to
// dispatch other global messages (i.e messages that must be sent to all
// nsIWidget instances.
// Enumerate all child windows sending aMsg to each of them
BOOL CALLBACK nsWindow::BroadcastMsgToChildren(HWND aWnd, LPARAM aMsg)
{
LONG proc = ::GetWindowLong(aWnd, GWL_WNDPROC);
if (proc == (LONG)&nsWindow::WindowProc) {
// its one of our windows so go ahead and send a message to it
WNDPROC winProc = (WNDPROC)GetWindowLong(aWnd, GWL_WNDPROC);
::CallWindowProc(winProc, aWnd, aMsg, 0, 0);
}
// Send message to children of this window
::EnumChildWindows(aWnd, nsWindow::BroadcastMsgToChildren, aMsg);
return TRUE;
}
// Enumerate all top level windows specifying that the children of each
// top level window should be enumerated. Do *not* send the message to
// each top level window since it is assumed that the toolkit will send
// aMsg to them directly.
BOOL CALLBACK nsWindow::BroadcastMsg(HWND aTopWindow, LPARAM aMsg)
{
// Iterate each of aTopWindows child windows sending the aMsg
// to each of them.
EnumChildWindows(aTopWindow, nsWindow::BroadcastMsgToChildren, aMsg);
return TRUE;
}
// This method is called from nsToolkit::WindowProc to forward global
// messages which need to be dispatched to all child windows.
void nsWindow::GlobalMsgWindowProc(HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_SYSCOLORCHANGE:
// System color changes are posted to top-level windows only.
// The NS_SYSCOLORCHANGE must be dispatched to all child
// windows as well.
::EnumThreadWindows(GetCurrentThreadId(), nsWindow::BroadcastMsg, msg);
break;
}
}
// End of the methods to dispatch global messages
PRBool gIsDestroyingAny = PR_FALSE;
//-------------------------------------------------------------------------
@ -3424,6 +3481,15 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
case WM_DISPLAYCHANGE:
DispatchStandardEvent(NS_DISPLAYCHANGED);
break;
case WM_SYSCOLORCHANGE:
// Note: This is sent for child windows as well as top-level windows.
// The Win32 toolkit normally only sends these events to top-level windows.
// But we cycle through all of the childwindows and send it to them as well
// so all presentations get notified properly.
// See nsWindow::GlobalMsgWindowProc.
DispatchStandardEvent(NS_SYSCOLORCHANGED);
break;
case WM_NOTIFY:
// TAB change

View File

@ -561,6 +561,11 @@ protected:
IAccessible* mRootAccessible;
static BOOL gIsAccessibilityOn;
#endif
static BOOL CALLBACK BroadcastMsgToChildren(HWND aWnd, LPARAM aMsg);
static BOOL CALLBACK BroadcastMsg(HWND aTopWindow, LPARAM aMsg);
public:
static void GlobalMsgWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
//