Commit f17eaa14 authored by Martin Stransky's avatar Martin Stransky
Browse files

Bug 496653 - Command line option --class <WM_CLASS> does not work, use...

Bug 496653 - Command line option --class <WM_CLASS> does not work, use MOZ_WM_CLASS workaround. r=karlt
parent 2f51830e
Loading
Loading
Loading
Loading
+29 −60
Original line number Diff line number Diff line
@@ -3733,14 +3733,11 @@ nsWindow::Create(nsIWidget *aParent,
        // If we get explicitly moved, the position will also be set.
        mNeedsResize = true;

        nsXPIDLString brandName;
        GetBrandName(brandName);
        NS_ConvertUTF16toUTF8 cBrand(brandName);

        if (mWindowType == eWindowType_dialog) {
            mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
            SetDefaultIcon();
            gtk_window_set_wmclass(GTK_WINDOW(mShell), "Dialog", cBrand.get());
            gtk_window_set_wmclass(GTK_WINDOW(mShell), "Dialog", 
                                   gdk_get_program_class());
            gtk_window_set_type_hint(GTK_WINDOW(mShell),
                                     GDK_WINDOW_TYPE_HINT_DIALOG);
            gtk_window_set_transient_for(GTK_WINDOW(mShell),
@@ -3781,12 +3778,14 @@ nsWindow::Create(nsIWidget *aParent,
                // GTK_WINDOW_POPUP, which will use a Window with the
                // override-redirect attribute (for temporary windows).
                mShell = gtk_window_new(GTK_WINDOW_POPUP);
                gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", cBrand.get());
                gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", 
                                       gdk_get_program_class());
            } else {
                // For long-lived windows, their stacking order is managed by
                // the window manager, as indicated by GTK_WINDOW_TOPLEVEL ...
                mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
                gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", cBrand.get());
                gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", 
                                       gdk_get_program_class());
                // ... but the window manager does not decorate this window,
                // nor provide a separate taskbar icon.
                if (mBorderStyle == eBorderStyle_default) {
@@ -3848,7 +3847,8 @@ nsWindow::Create(nsIWidget *aParent,
        else { // must be eWindowType_toplevel
            mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
            SetDefaultIcon();
            gtk_window_set_wmclass(GTK_WINDOW(mShell), "Toplevel", cBrand.get());
            gtk_window_set_wmclass(GTK_WINDOW(mShell), "Toplevel", 
                                   gdk_get_program_class());

            // each toplevel window gets its own window group
            mWindowGroup = gtk_window_group_new();
@@ -4076,31 +4076,21 @@ nsWindow::SetWindowClass(const nsAString &xulWinType)
  if (!mShell)
    return NS_ERROR_FAILURE;

#ifdef MOZ_X11
  nsXPIDLString brandName;
  GetBrandName(brandName);
  const char *res_class = gdk_get_program_class();
  if (!res_class)
    return NS_ERROR_FAILURE;
  
  XClassHint *class_hint = XAllocClassHint();
  if (!class_hint)
  char *res_name = ToNewCString(xulWinType);
  if (!res_name)
    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(brandName);
  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++) {
  for (char *c = res_name; *c; c++) {
    if (':' == *c) {
      *c = 0;
      role = c + 1;
@@ -4108,52 +4098,31 @@ nsWindow::SetWindowClass(const nsAString &xulWinType)
    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;
  res_name[0] = toupper(res_name[0]);
  if (!role) role = res_name;

  GdkWindow *shellWindow = gtk_widget_get_window(GTK_WIDGET(mShell));
  gdk_window_set_role(shellWindow, role);

#ifdef MOZ_X11
  XClassHint *class_hint = XAllocClassHint();
  if (!class_hint) {
    nsMemory::Free(res_name);
    return NS_ERROR_OUT_OF_MEMORY;
  }
  class_hint->res_name = res_name;
  class_hint->res_class = const_cast<char*>(res_class);

  // Can't use gtk_window_set_wmclass() for this; it prints
  // a warning & refuses to make the change.
  XSetClassHint(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
                gdk_x11_window_get_xid(shellWindow),
                class_hint);
  nsMemory::Free(class_hint->res_class);
  nsMemory::Free(class_hint->res_name);
  XFree(class_hint);
#else /* MOZ_X11 */

  char *res_name;

  res_name = ToNewCString(xulWinType);
  if (!res_name)
    return NS_ERROR_OUT_OF_MEMORY;

  printf("WARN: res_name = '%s'\n", res_name);


  const char *role = NULL;

  // 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 = res_name; *c; c++) {
    if (':' == *c) {
      *c = 0;
      role = c + 1;
    }
    else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
      *c = '_';
  }
  res_name[0] = toupper(res_name[0]);
  if (!role) role = res_name;

  gdk_window_set_role(gtk_widget_get_window(GTK_WIDGET(mShell)), role);
#endif /* MOZ_X11 */

  nsMemory::Free(res_name);

#endif /* MOZ_X11 */
  return NS_OK;
}