Bug 29856. Support SetWindowClass in GTK2. r+sr=roc, patch-midden by Andrew Taylor, Arik Devens, Rob Ginda, Kenneth Herron, timeless, Alex Zbyslaw, and me.

This commit is contained in:
roc+%cs.cmu.edu 2006-04-09 22:45:04 +00:00
Родитель 6670dd2a7d
Коммит 079a097ecc
3 изменённых файлов: 58 добавлений и 20 удалений

Просмотреть файл

@ -2564,6 +2564,7 @@ nsWindow::NativeCreate(nsIWidget *aParent,
}
else if (mWindowType == eWindowType_popup) {
mShell = gtk_window_new(GTK_WINDOW_POPUP);
gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", "Mozilla");
if (topLevelParent) {
gtk_window_set_transient_for(GTK_WINDOW(mShell),
topLevelParent);
@ -2579,6 +2580,7 @@ nsWindow::NativeCreate(nsIWidget *aParent,
else { // must be eWindowType_toplevel
mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
SetDefaultIcon();
gtk_window_set_wmclass(GTK_WINDOW(mShell), "Toplevel", "Mozilla");
// each toplevel window gets its own window group
mWindowGroup = gtk_window_group_new();
@ -2784,6 +2786,56 @@ nsWindow::NativeCreate(nsIWidget *aParent,
return NS_OK;
}
NS_IMETHODIMP
nsWindow::SetWindowClass(const nsAString& aName,
const nsAString &xulWinType)
{
if (!mShell)
return NS_ERROR_FAILURE;
XClassHint *class_hint = XAllocClassHint();
if (!class_hint)
return NS_ERROR_OUT_OF_MEMORY;
const char *role = NULL;
class_hint->res_name = ToNewCString(xulWinType);
if (!class_hint->res_name) {
XFree(class_hint);
return NS_ERROR_OUT_OF_MEMORY;
}
class_hint->res_class = ToNewCString(aName);
if (!class_hint->res_class) {
nsMemory::Free(class_hint->res_name);
XFree(class_hint);
return NS_ERROR_OUT_OF_MEMORY;
}
// Parse res_name into a name and role. Characters other than
// [A-Za-z0-9_-] are converted to '_'. Anything after the first
// colon is assigned to role; if there's no colon, assign the
// whole thing to both role and res_name.
for (char *c = class_hint->res_name; *c; c++) {
if (':' == *c) {
*c = 0;
role = c + 1;
}
else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
*c = '_';
}
class_hint->res_name[0] = toupper(class_hint->res_name[0]);
if (!role) role = class_hint->res_name;
gdk_window_set_role(GTK_WIDGET(mShell)->window, role);
// Can't use gtk_window_set_wmclass() for this; it prints
// a warning & refuses to make the change.
XSetClassHint(GDK_DISPLAY(),
GDK_WINDOW_XWINDOW(GTK_WIDGET(mShell)->window),
class_hint);
nsMemory::Free(class_hint->res_class);
nsMemory::Free(class_hint->res_name);
XFree(class_hint);
return NS_OK;
}
void
nsWindow::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{

Просмотреть файл

@ -138,6 +138,8 @@ public:
NS_IMETHOD SetBorderStyle(nsBorderStyle aBorderStyle);
NS_IMETHOD SetTitle(const nsAString& aTitle);
NS_IMETHOD SetIcon(const nsAString& aIconSpec);
NS_IMETHOD SetWindowClass(const nsAString& aName,
const nsAString& xulWinType);
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
NS_IMETHOD ShowMenuBar(PRBool aShow);
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect,

Просмотреть файл

@ -1332,33 +1332,17 @@ void nsXULWindow::StaggerPosition(PRInt32 &aRequestedX, PRInt32 &aRequestedY,
NS_IMETHODIMP nsXULWindow::LoadWindowClassFromXUL()
{
if (mWindow->GetWindowClass(nsnull)==NS_ERROR_NOT_IMPLEMENTED)
return NS_OK;
nsCOMPtr<nsIDOMElement> docShellElement;
GetWindowDOMElement(getter_AddRefs(docShellElement));
NS_ENSURE_TRUE(docShellElement, NS_ERROR_FAILURE);
nsAutoString windowClass;
nsAutoString windowType;
docShellElement->GetAttribute(NS_LITERAL_STRING("windowtype"),
windowClass);
windowType);
if (!windowClass.IsEmpty())
{
PRBool persistPosition;
PRBool persistSize;
PRBool persistSizeMode;
if (NS_SUCCEEDED(
mContentTreeOwner->
GetPersistence(&persistPosition, &persistSize, &persistSizeMode)
) && !persistPosition && !persistSize && !persistSizeMode)
windowClass.AppendLiteral("-jsSpamPopupCrap");
char *windowClass_cstr = ToNewCString(windowClass);
mWindow->SetWindowClass(windowClass_cstr);
nsMemory::Free(windowClass_cstr);
if (!windowType.IsEmpty()) {
mWindow->SetWindowClass(NS_LITERAL_STRING("Mozilla"), windowType);
}
return NS_OK;