void nsSystemTrayIconBase::DispatchEvent(const nsAString& aType, PRUint16 aButton, PRInt32 aDetail, bool aCtrlKey, bool aAltKey, bool aShiftKey, bool aMetaKey) { nsresult rv; // first, create an event... nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mEventTarget, &rv)); if (NS_FAILED(rv)) return; nsCOMPtr<nsIDOMDocument> doc; rv = node->GetOwnerDocument(getter_AddRefs(doc)); if (NS_FAILED(rv)) return; nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(doc, &rv)); if (NS_FAILED(rv)) return; nsCOMPtr<nsIDOMEvent> event; rv = docEvent->CreateEvent(NS_LITERAL_STRING("mouseevent"), getter_AddRefs(event)); if (NS_FAILED(rv)) return; nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event, &rv)); if (NS_FAILED(rv)) return; // get the view the event occurred on nsCOMPtr<nsIDOMDocumentView> documentView(do_QueryInterface(doc, &rv)); if (NS_FAILED(rv)) return; nsCOMPtr<nsIDOMAbstractView> view; rv = documentView->GetDefaultView(getter_AddRefs(view)); if (NS_FAILED(rv)) return; // figure out where to position the popup nsPoint position = GetPopupPosition(); // initialize the event // TODO: give useful arguments here rv = mouseEvent->InitMouseEvent(aType, PR_FALSE, PR_TRUE, view, aDetail, position.x, position.y, position.x, position.y, aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton, nsnull); if (NS_FAILED(rv)) return; // and dispatch it. (yes, return value is ignored; we can't do anything) bool result; mEventTarget->DispatchEvent(event, &result); }
LRESULT CALLBACK nsWindowUtil::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { bool handled = true; WNDPROC proc; nsWindowUtil* self = (nsWindowUtil*)GetProp(hwnd, S_PROPINST); if (self && self->mOldProc && self->mDOMWindow) { proc = self->mOldProc; } else { // property not found - we don't exist anymore // use the original window proc proc = (WNDPROC)GetProp(hwnd, S_PROPPROC); if (!proc) // can't find the right process... skip over to the default // (this will, at the minimum, totally break the app) proc = DefWindowProc; handled = false; } /* * For this next section, including all the switches, we are simply * collecting messages we feel are important to collect. Once we collect * all the windows messages that may be important to us, then these messages * are dispatched as DOM events to the window. */ nsAutoString typeArg; POINT clientPos = { 0, 0}; POINT screenPos = { 0, 0}; if (handled) { switch (uMsg) { case WM_NCLBUTTONDOWN: switch(wParam) { // these are the min, max, and close buttons for case HTMINBUTTON: typeArg = NS_LITERAL_STRING("minimizing"); break; case HTMAXBUTTON: typeArg = NS_LITERAL_STRING("maximizing"); break; case HTCLOSE: typeArg = NS_LITERAL_STRING("closing"); break; default: handled = false; } clientPos.x = screenPos.x = LOWORD(lParam); clientPos.y = screenPos.y = LOWORD(lParam); ::ClientToScreen(hwnd, &screenPos); break; case WM_ACTIVATE: switch (LOWORD(wParam)) { case WA_ACTIVE: case WA_CLICKACTIVE: // window is being activated typeArg = NS_LITERAL_STRING("activating"); break; default: handled = false; } break; case WM_SIZE: switch (wParam) { case SIZE_MINIMIZED: typeArg = NS_LITERAL_STRING("minimizing"); break; default: // for some reason this message is received with wParam == // SIZE_MAXIMIZED when the browser is shutting down, and calling // Restore() results in the maximized window being "restored" // (returned to non-maximized) size. This size is preserved // after restarting, which is annoying, so I'm commenting it out // until someone can prove that this is actually useful. // // we're resizing, but not minimized, so some part must be visible //typeArg = NS_LITERAL_STRING("activating"); break; } break; case WM_SYSCOMMAND: switch (wParam) { case SC_CLOSE: //The user has clicked on the top left window icon and selected close... //Or the user typed Alt+F4. typeArg = NS_LITERAL_STRING("closing"); break; default: handled = false; } break; default: handled = false; break; } } PRBool ctrlArg = PR_FALSE; PRBool altArg = PR_FALSE; PRBool shiftArg = PR_FALSE; if (handled) { // check modifier key states if (::GetKeyState(VK_CONTROL) & 0x8000) ctrlArg = PR_TRUE; if (::GetKeyState(VK_MENU) & 0x8000) altArg = PR_TRUE; if (::GetKeyState(VK_SHIFT) & 0x8000) shiftArg = PR_TRUE; // dispatch the event PRBool ret = TRUE; nsresult rv; nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(self->mDOMWindow, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMDocument> document; rv = self->mDOMWindow->GetDocument(getter_AddRefs(document)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMDocumentEvent> documentEvent(do_QueryInterface(document, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMDocumentView> documentView(do_QueryInterface(document, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMAbstractView> abstractView; rv = documentView->GetDefaultView(getter_AddRefs(abstractView)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMEvent> event; rv = documentEvent->CreateEvent(NS_LITERAL_STRING("mouseevent"), getter_AddRefs(event)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event, &rv)); NS_ENSURE_SUCCESS(rv, rv); rv = mouseEvent->InitMouseEvent(typeArg, PR_TRUE, PR_TRUE, abstractView, 1, screenPos.x, screenPos.y, clientPos.x, clientPos.y, ctrlArg, altArg, shiftArg, PR_FALSE, 0, nsnull); NS_ENSURE_SUCCESS(rv, rv); rv = eventTarget->DispatchEvent(mouseEvent, &ret); NS_ENSURE_SUCCESS(rv, rv); if (!ret) // event was hooked return FALSE; } return CallWindowProc(proc, hwnd, uMsg, wParam, lParam); }