From 999c375f5342947525813584fbdc92f3b63dced6 Mon Sep 17 00:00:00 2001
From: Christian Hesse
Date: Wed, 25 Sep 2013 15:16:57 +0200
Subject: [PATCH 1/1] xfwm4: hide titlebar when maximized
---
defaults/defaults | 1 +
settings-dialogs/tweaks-settings.c | 5 +
settings-dialogs/xfwm4-tweaks-dialog.glade | 25 +-
settings-dialogs/xfwm4-tweaks-dialog_ui.h | 612 +++++++++++++++--------------
src/client.c | 6 +
src/client.h | 1 +
src/display.c | 3 +-
src/display.h | 1 +
src/events.c | 5 +
src/frame.c | 366 ++++++++++-------
src/netwm.c | 38 ++
src/placement.c | 4 +-
src/settings.c | 8 +
src/settings.h | 1 +
14 files changed, 616 insertions(+), 460 deletions(-)
diff --git a/defaults/defaults b/defaults/defaults
index 6db210a..1582fc1 100644
--- a/defaults/defaults
+++ b/defaults/defaults
@@ -1,5 +1,6 @@
activate_action=bring
borderless_maximize=true
+titleless_maximize=false
box_move=false
box_resize=false
button_layout=O|SHMC
diff --git a/settings-dialogs/tweaks-settings.c b/settings-dialogs/tweaks-settings.c
index f60b606..2532733 100644
--- a/settings-dialogs/tweaks-settings.c
+++ b/settings-dialogs/tweaks-settings.c
@@ -180,6 +180,7 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
GtkWidget *easy_click_combo_box = GTK_WIDGET (gtk_builder_get_object (builder, "easy_click_combo_box"));
GtkWidget *raise_with_any_button_check = GTK_WIDGET (gtk_builder_get_object (builder, "raise_with_any_button_check"));
GtkWidget *borderless_maximize_check = GTK_WIDGET (gtk_builder_get_object (builder, "borderless_maximize_check"));
+ GtkWidget *titleless_maximize_check = GTK_WIDGET (gtk_builder_get_object (builder, "titleless_maximize_check"));
GtkWidget *restore_on_move_check = GTK_WIDGET (gtk_builder_get_object (builder, "restore_on_move_check"));
GtkWidget *tile_on_move_check = GTK_WIDGET (gtk_builder_get_object (builder, "tile_on_move_check"));
GtkWidget *snap_resist_check = GTK_WIDGET (gtk_builder_get_object (builder, "snap_resist_check"));
@@ -336,6 +337,10 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
G_TYPE_BOOLEAN,
(GObject *)borderless_maximize_check, "active");
xfconf_g_property_bind (xfwm4_channel,
+ "/general/titleless_maximize",
+ G_TYPE_BOOLEAN,
+ (GObject *)titleless_maximize_check, "active");
+ xfconf_g_property_bind (xfwm4_channel,
"/general/restore_on_move",
G_TYPE_BOOLEAN,
(GObject *)restore_on_move_check, "active");
diff --git a/settings-dialogs/xfwm4-tweaks-dialog.glade b/settings-dialogs/xfwm4-tweaks-dialog.glade
index bd2a86f..7d604c6 100644
--- a/settings-dialogs/xfwm4-tweaks-dialog.glade
+++ b/settings-dialogs/xfwm4-tweaks-dialog.glade
@@ -343,6 +343,21 @@ or "skip taskbar" properties set
+
+ Hide _title of windows when maximized
+ True
+ True
+ False
+ True
+ True
+
+
+ False
+ False
+ 3
+
+
+
Restore original _size of maximized windows when moving
True
@@ -354,7 +369,7 @@ or "skip taskbar" properties set
False
False
- 3
+ 4
@@ -369,7 +384,7 @@ or "skip taskbar" properties set
False
False
- 4
+ 5
@@ -384,7 +399,7 @@ or "skip taskbar" properties set
False
False
- 5
+ 6
@@ -399,7 +414,7 @@ or "skip taskbar" properties set
False
False
- 5
+ 7
@@ -414,7 +429,7 @@ or "skip taskbar" properties set
False
False
- 6
+ 8
diff --git a/settings-dialogs/xfwm4-tweaks-dialog_ui.h b/settings-dialogs/xfwm4-tweaks-dialog_ui.h
index a6121dd..8ddbf30 100644
--- a/settings-dialogs/xfwm4-tweaks-dialog_ui.h
+++ b/settings-dialogs/xfwm4-tweaks-dialog_ui.h
@@ -177,332 +177,340 @@ static const char tweaks_dialog_ui[] =
"y>True FalseFalse"
"property>2
Restore original _size of maxim"
- "ized windows when movingTrueTrue False True
True False F"
- "alse 3 Automatically _tile windows "
- "when moving toward the screen edgeTrue True False True True False False 4 Use _edge resistanc"
- "e instead of window snapping True<"
- "/property>True False Tru"
- "e True <"
- "packing>False False 5 "
- "child>Notify of _urgency by making w"
- "indow\'s decoration blinkTrueHide _title of windows when "
+ "maximized True True "
+ "False True True False False "
+ "3 Restore original _size of maximized wind"
+ "ows when moving True TrueFalse True <"
+ "property name=\"draw_indicator\">TrueFalseFalse4 "
+ "Automatically _tile windows when movi"
+ "ng toward the screen edge TrueTrue False True"
"property>True False "
"False 5 <"
- "property name=\"label\" translatable=\"yes\">Keep urgent windows _blink"
- "ing repeatedlyTrue Use _edge resistance instead"
+ " of window snappingTrue True False TrueTrue <"
+ "property name=\"expand\">FalseFalse<"
+ "/property>6 Notify of _urgency by making window\'s "
+ "decoration blink True TrueFalse True "
+ "True
FalseFalse7 Keep urgent windows _blinking repea"
+ "tedly True True Fals"
+ "e True True False False 8 2 True _Acce"
+ "ssibility True 2 False True 12 vert"
+ "ical 6 Use the _mouse wheel on the desktop to swi"
+ "tch workspaces True TrueFalse True True
FalseFalse6 2 True _Accessibility True 2 False True 12 vertical 6 "
- "Use the _mouse wheel on the desk"
- "top to switch workspacesTrueTrue False TrueTrue False F"
- "alse 0 _Remember and recall pre"
- "vious workspace\nwhen switching via keyboard shortcuts TrueTrue"
- "property>False True True FalseFalse 1 "
- "Wrap workspaces depending on the actual desktop _layout TrueTrue<"
- "/property>False True True FalseFalse 2 W"
- "rap workspaces when the _first or the last workspace is reachedTrue True False <"
- "property name=\"use_underline\">True True Fa"
- "lse False 3 3 True_WorkspacesTrue <"
- "property name=\"position\">3 Fals"
- "e True 12 vertical "
- "6 True 0 _"
- "Minimum size of windows to trigger smart placement: True placement_ratio_scale False False 0 True6 12 True 1"
- "2 True <i>Small</i>True False False0 True Trueadjustment1 False "
- "False 1 <"
- "property name=\"visible\">True<i>Large</i&"
- "gt; True False 2 <"
- "property name=\"expand\">FalseFalse<"
- "/property>1 True vertical"
- "property>6 True 0 By default, place windows: 0 True"
- "property>6 12 True 6 vertical 6
At the _center of the screen True True FalseTrue True 0 <"
- "/child>Under the mouse _po"
- "inter True True Fals"
- "e True True Trueplacement_center_option 1 1 Fals"
- "e False 2 4 True_Placement True 4False"
- "property> True 12 vertical 6_Enable display compositing True True False True True False False 0 True False True "
- "never automatic True queue"
- "none "
- "True 6 12 Truevertical 6 Display _fullscreen overlay windows directly 0 <"
+ "object class=\"GtkCheckButton\" id=\"toggle_workspaces_check\">_Remember and recall previous wor"
+ "kspace\nwhen switching via keyboard shortcuts True True "
+ "False True True False False1 Wrap wor"
+ "kspaces depending on the actual desktop _layout True TrueFalse True True"
"property> False 0
Show shadows under _regular windows True True FalseTrue True False 1 Show shadows under po"
- "p_up windows True TrueFalse True True False2 Show "
- "shadows under _dock windows True"
- "property>True False True"
- " True False 3
True 0 Op"
- "aci_ty of window decorations: True frame_opacity_scale<"
- "/property> False <"
- "property name=\"position\">4Tr"
- "ue 2 12 True True <i>Transparent</i>"
- ";True False F"
- "alse 0 False2 Wrap wo"
+ "rkspaces when the _first or the last workspace is reached TrueTru"
+ "e False TrueTrue FalseFalse 3 3 True _Workspaces True
3False <"
+ "property name=\"visible\">True12 vertical 6True 0 _Minimu"
+ "m size of windows to trigger smart placement: True pla"
+ "cement_ratio_scale False False 0 True "
+ "6 12 True12True <i>Small</i> True
False False 0 True True adjustment1False False<"
+ "/property> 1 True<i>Large</i>True "
+ "False 2"
+ " FalseFalse1 True vertical6 True 0 By default, place windows: 0 True6 12 <"
+ "property name=\"visible\">True 6 vertical 6 At the _center of the screen True True False True True 0 "
+ "Under the mouse _pointer<"
+ "/property>True True FalseTrue True Trueplacement_center_option <"
+ "packing>1 1 <"
+ "/packing>FalseFalse 2 4 True <"
+ "property name=\"label\" translatable=\"yes\">_PlacementTrue 4 False True1"
+ "2 vertical 6 _Enable display compositing Tru"
+ "e True False T"
+ "rue True False False 0 "
+ "True False True neverautomatic True queue none"
+ " True6 12 Truevertical 6 D"
+ "isplay _fullscreen overlay windows directly True True False
True True False 0 Show shadows under _regular windowsTrue True False True True Fals"
+ "e 1 <"
+ "child><"
+ "property name=\"label\" translatable=\"yes\">Show shadows under pop_up "
+ "windowsTrue True Fa"
+ "lse True True False 2 "
+ "packing>Show shado"
+ "ws under _dock windows TrueTrue False True True False 3 True 0 Opaci_t"
+ "y of window decorations: Tru"
+ "e frame_opacity_scale False 4 True"
+ "property>2 12 True True <i>Transparent</i>True "
+ "False False"
+ " 0 True Truediscontinuous adjustment2 False False 1 True <i>Opaque</i> T"
+ "rue FalseFalse "
+ "2 FalseFalse5 <"
+ "object class=\"GtkLabel\" id=\"label13\">Tru"
+ "e 0 Opacity of _inactive windows: Trueinactive_opacity_scale False False 6 True"
+ " 2 12 True True <i>Transparent</i><"
+ "/property>True False Fal"
+ "se 0 "
+ "TrueTrue"
+ "property>discontinuous adjustment3 False False"
+ "property> 1 True<i>Opaque</i> True FalseFalse 2 <"
+ "property name=\"expand\">FalseFalse<"
+ "/property>7 True 0 Opacity of windows during _move: True move_opacity_scale False False "
+ "8 T"
+ "rue 2 12 True True <i>Transparent</i&g"
+ "t;True False "
+ "False 0 TrueTruediscontinuous adjustment2 adjustment4 False False 1 True <i>Opaque</i> True FalseFalse 2 FalseFalse"
- "property>5
9 True 0 Opacity of _inactive windows: True
inactive_opacity_scale False False 6 "
- "True 2 12 True True <i>Transparent</i&g"
- "t;True False "
- "False 0 TrueTru"
- "e discontinuous adjustment3False Fals"
- "e
1 <"
- "/packing>True<i>Opaque</i> True False"
- " False 2 False Fal"
- "se 7 "
- "True 0 Opacity of windows during _move:True move_opacity_scale Opacity of windows during resi_ze: True resize_opacity_scale FalseFalse8 True 2 12 True True <i>Transparent<"
- "/i> True "
- "False False 0 <"
- "/child>TrueTru"
- "e discontinuous adjustment4False Fals"
- "e
1 <"
- "/packing>True<i>Opaque</i> True False"
- " False 2 False Fal"
- "se 9 "
- "True 0 Opacity of windows during resi_ze:True resize_opacity_scale FalseFalse10 True 2 12True True<i>Transparent"
- "</i> True False False 0 True True discontinuousadjustment5 False "
- "False 1 <"
- "property name=\"visible\">True<i>Opaque</i> True F"
- "alse False 10 <"
+ "object class=\"GtkAlignment\" id=\"alignment8\">True 2 12 True True<i>Transparent<"
+ ";/i> True False False 0 "
+ ""
+ "True "
+ "True discontinuous adjustment5 False F"
+ "alse 1 True<i>Opaque</i> True
Fa"
+ "lse False 2 False "
"False 11 "
};
-static const unsigned tweaks_dialog_ui_length = 37803u;
+static const unsigned tweaks_dialog_ui_length = 38338u;
diff --git a/src/client.c b/src/client.c
index 4e86808..b92c264 100644
--- a/src/client.c
+++ b/src/client.c
@@ -64,6 +64,8 @@
#include "xsync.h"
#include "event_filter.h"
+//#define TRACE(fmt, ...) printf(fmt"\n", ##__VA_ARGS__); fflush(stdout);
+
/* Event mask definition */
#define POINTER_EVENT_MASK \
@@ -173,6 +175,7 @@ clientCreateTitleName (Client *c, gchar *name, gchar *hostname)
gchar *title;
g_return_val_if_fail (c != NULL, NULL);
+
TRACE ("entering clientCreateTitleName");
screen_info = c->screen_info;
@@ -1729,6 +1732,7 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture)
clientGetInitialNetWmDesktop (c);
/* workarea will be updated when shown, no need to worry here */
clientGetNetStruts (c);
+ clientGetExtra (c);
/* Once we know the type of window, we can initialize window position */
if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED))
@@ -3137,6 +3141,8 @@ clientNewMaxSize (Client *c, XWindowChanges *wc, GdkRectangle *rect, tilePositio
wc->width = full_w - frameLeft (c) - frameRight (c);
wc->height = full_h - frameTop (c) - frameBottom (c);
+ TRACE ("clientNewMaxSize %d %d %d %d", wc->x, wc->y, wc->width, wc->height);
+
return ((wc->width <= c->size->max_width) && (wc->height <= c->size->max_height));
}
diff --git a/src/client.h b/src/client.h
index e8bc4e3..b5e54df 100644
--- a/src/client.h
+++ b/src/client.h
@@ -161,6 +161,7 @@
#define CLIENT_FLAG_DEMANDS_ATTENTION (1L<<17)
#define CLIENT_FLAG_HAS_SHAPE (1L<<18)
#define CLIENT_FLAG_FULLSCREN_MONITORS (1L<<19)
+#define CLIENT_FLAG_TITLELESS_MAXIMIZE (1L<<20)
#define WM_FLAG_DELETE (1L<<0)
#define WM_FLAG_INPUT (1L<<1)
diff --git a/src/display.c b/src/display.c
index 00318d5..4f847f4 100644
--- a/src/display.c
+++ b/src/display.c
@@ -169,7 +169,8 @@ myDisplayInitAtoms (DisplayInfo *display_info)
"XFWM4_COMPOSITING_MANAGER",
"XFWM4_TIMESTAMP_PROP",
"_XROOTPMAP_ID",
- "_XSETROOT_ID"
+ "_XSETROOT_ID",
+ "_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"
};
g_assert (ATOM_COUNT == G_N_ELEMENTS (atom_names));
diff --git a/src/display.h b/src/display.h
index 8797237..a297cf2 100644
--- a/src/display.h
+++ b/src/display.h
@@ -265,6 +265,7 @@ enum
XFWM4_TIMESTAMP_PROP,
XROOTPMAP,
XSETROOT,
+ _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED,
ATOM_COUNT
};
diff --git a/src/events.c b/src/events.c
index 4b49171..044cd11 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1921,6 +1921,11 @@ handlePropertyNotify (DisplayInfo *display_info, XPropertyEvent * ev)
TRACE ("Window 0x%lx has NET_WM_SYNC_REQUEST_COUNTER set to 0x%lx", c->window, c->xsync_counter);
}
#endif /* HAVE_XSYNC */
+ else if (ev->atom == display_info->atoms[_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED])
+ {
+ TRACE ("Client \"%s\" Window 0x%lx has received GTK CRAP\n", c->name, c->window);
+ clientUpdateExtra (c);
+ }
return status;
}
diff --git a/src/frame.c b/src/frame.c
index 7f4cbd3..23c01cd 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -39,6 +39,8 @@
#include "frame.h"
#include "compositor.h"
+//#define TRACE(fmt, ...) printf(fmt"\n", ##__VA_ARGS__); fflush(stdout);
+
typedef struct
{
xfwmPixmap pm_title;
@@ -121,7 +123,14 @@ frameTop (Client * c)
g_return_val_if_fail (c != NULL, 0);
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)
- && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
+ && !(FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)
+ || (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT)
+ && (c->screen_info->params->titleless_maximize
+ || FLAG_TEST (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE))
+ && c->screen_info->params->borderless_maximize
+ )
+ )
+ )
{
return c->screen_info->title[TITLE_3][ACTIVE].height;
}
@@ -136,8 +145,13 @@ frameBottom (Client * c)
g_return_val_if_fail (c != NULL, 0);
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)
&& !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)
- && (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
- || !(c->screen_info->params->borderless_maximize)))
+ && !(FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
+ && (c->screen_info->params->borderless_maximize))
+ && !(FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT)
+ && (c->screen_info->params->borderless_maximize)
+ && (c->screen_info->params->titleless_maximize
+ || FLAG_TEST (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE)))
+ )
{
return c->screen_info->sides[SIDE_BOTTOM][ACTIVE].height;
}
@@ -203,7 +217,14 @@ frameHeight (Client * c)
return frameTop (c) + frameBottom (c);
}
else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)
- && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
+ && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)
+ && !(
+ FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT)
+ && (c->screen_info->params->borderless_maximize)
+ && (c->screen_info->params->titleless_maximize
+ || FLAG_TEST (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE))
+ ))
+
{
return c->height + frameTop (c) + frameBottom (c);
}
@@ -882,6 +903,7 @@ frameDrawWin (Client * c)
gboolean requires_clearing;
gboolean width_changed;
gboolean height_changed;
+ gboolean vert_only;
TRACE ("entering frameDraw");
TRACE ("drawing frame for \"%s\" (0x%lx)", c->name, c->window);
@@ -955,128 +977,152 @@ frameDrawWin (Client * c)
}
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)
- && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
+ && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)
+ && !(FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
+ && (c->screen_info->params->borderless_maximize)
+ && (c->screen_info->params->titleless_maximize
+ || FLAG_TEST (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE))
+ ))
{
- /* First, hide the buttons that we don't have... */
- for (i = 0; i < BUTTON_COUNT; i++)
+ vert_only = FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT)
+ && (c->screen_info->params->borderless_maximize) //only vertical decorations shown (titleless vertical maximize)
+ && (c->screen_info->params->titleless_maximize
+ || FLAG_TEST (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE));
+
+ if (vert_only)
{
- char b = getLetterFromButton (i, c);
- if ((!b) || !strchr (screen_info->params->button_layout, b))
+ //hide all buttons
+ for (i = 0; i < BUTTON_COUNT; i++)
{
xfwmWindowHide (&c->buttons[i]);
}
+ xfwmWindowHide (&c->title);
+ xfwmWindowHide (&c->sides[SIDE_BOTTOM]);
+ xfwmWindowHide (&c->sides[SIDE_TOP]);
+ xfwmWindowHide (&c->corners[CORNER_TOP_LEFT]);
+ xfwmWindowHide (&c->corners[CORNER_TOP_RIGHT]);
+ xfwmWindowHide (&c->corners[CORNER_BOTTOM_LEFT]);
+ xfwmWindowHide (&c->corners[CORNER_BOTTOM_RIGHT]);
}
-
- /* Then, show the ones that we do have on left... */
- x = frameLeft (c) + frameButtonOffset (c);
- if (x < 0)
- {
- x = 0;
- }
- right = frameWidth (c) - frameRight (c) - frameButtonOffset (c);
- for (i = 0; i < strlen (screen_info->params->button_layout); i++)
+ else
{
- button = getButtonFromLetter (screen_info->params->button_layout[i], c);
- if (button == TITLE_SEPARATOR)
+ /* First, hide the buttons that we don't have... */
+ for (i = 0; i < BUTTON_COUNT; i++)
{
- break;
- }
- else if (button >= 0)
- {
- if (x + screen_info->buttons[button][state].width + screen_info->params->button_spacing < right)
- {
- my_pixmap = clientGetButtonPixmap (c, button, clientGetButtonState (c, button, state));
- if (!xfwmPixmapNone(my_pixmap))
- {
- xfwmWindowSetBG (&c->buttons[button], my_pixmap);
- }
- xfwmWindowShow (&c->buttons[button], x,
- (frameTop (c) - screen_info->buttons[button][state].height + 1) / 2,
- screen_info->buttons[button][state].width,
- screen_info->buttons[button][state].height, TRUE);
- button_x[button] = x;
- x = x + screen_info->buttons[button][state].width +
- screen_info->params->button_spacing;
- }
- else
+ char b = getLetterFromButton (i, c);
+ if ((!b) || !strchr (screen_info->params->button_layout, b))
{
- xfwmWindowHide (&c->buttons[button]);
+ xfwmWindowHide (&c->buttons[i]);
}
}
- }
- left = x + screen_info->params->button_spacing;
- /* and those that we do have on right... */
- x = frameWidth (c) - frameRight (c) + screen_info->params->button_spacing -
- frameButtonOffset (c);
- for (j = strlen (screen_info->params->button_layout) - 1; j >= i; j--)
- {
- button = getButtonFromLetter (screen_info->params->button_layout[j], c);
- if (button == TITLE_SEPARATOR)
+ /* Then, show the ones that we do have on left... */
+ x = frameLeft (c) + frameButtonOffset (c);
+ if (x < 0)
{
- break;
+ x = 0;
}
- else if (button >= 0)
+ right = frameWidth (c) - frameRight (c) - frameButtonOffset (c);
+ for (i = 0; i < strlen (screen_info->params->button_layout); i++)
{
- if (x - screen_info->buttons[button][state].width - screen_info->params->button_spacing > left)
+ button = getButtonFromLetter (screen_info->params->button_layout[i], c);
+ if (button == TITLE_SEPARATOR)
{
- my_pixmap = clientGetButtonPixmap (c, button, clientGetButtonState (c, button, state));
- if (!xfwmPixmapNone(my_pixmap))
+ break;
+ }
+ else if (button >= 0)
+ {
+ if (x + screen_info->buttons[button][state].width + screen_info->params->button_spacing < right)
+ {
+ my_pixmap = clientGetButtonPixmap (c, button, clientGetButtonState (c, button, state));
+ if (!xfwmPixmapNone(my_pixmap))
+ {
+ xfwmWindowSetBG (&c->buttons[button], my_pixmap);
+ }
+ xfwmWindowShow (&c->buttons[button], x,
+ (frameTop (c) - screen_info->buttons[button][state].height + 1) / 2,
+ screen_info->buttons[button][state].width,
+ screen_info->buttons[button][state].height, TRUE);
+ button_x[button] = x;
+ x = x + screen_info->buttons[button][state].width +
+ screen_info->params->button_spacing;
+ }
+ else
{
- xfwmWindowSetBG (&c->buttons[button], my_pixmap);
+ xfwmWindowHide (&c->buttons[button]);
}
- x = x - screen_info->buttons[button][state].width -
- screen_info->params->button_spacing;
- xfwmWindowShow (&c->buttons[button], x,
- (frameTop (c) - screen_info->buttons[button][state].height + 1) / 2,
- screen_info->buttons[button][state].width,
- screen_info->buttons[button][state].height, TRUE);
- button_x[button] = x;
}
- else
+ }
+ left = x + screen_info->params->button_spacing;
+
+ /* and those that we do have on right... */
+ x = frameWidth (c) - frameRight (c) + screen_info->params->button_spacing -
+ frameButtonOffset (c);
+ for (j = strlen (screen_info->params->button_layout) - 1; j >= i; j--)
+ {
+ button = getButtonFromLetter (screen_info->params->button_layout[j], c);
+ if (button == TITLE_SEPARATOR)
{
- xfwmWindowHide (&c->buttons[button]);
+ break;
+ }
+ else if (button >= 0)
+ {
+ if (x - screen_info->buttons[button][state].width - screen_info->params->button_spacing > left)
+ {
+ my_pixmap = clientGetButtonPixmap (c, button, clientGetButtonState (c, button, state));
+ if (!xfwmPixmapNone(my_pixmap))
+ {
+ xfwmWindowSetBG (&c->buttons[button], my_pixmap);
+ }
+ x = x - screen_info->buttons[button][state].width -
+ screen_info->params->button_spacing;
+ xfwmWindowShow (&c->buttons[button], x,
+ (frameTop (c) - screen_info->buttons[button][state].height + 1) / 2,
+ screen_info->buttons[button][state].width,
+ screen_info->buttons[button][state].height, TRUE);
+ button_x[button] = x;
+ }
+ else
+ {
+ xfwmWindowHide (&c->buttons[button]);
+ }
}
}
+ left = left - 2 * screen_info->params->button_spacing;
+ right = x;
+ xfwmPixmapInit (screen_info, &frame_pix.pm_title);
+ xfwmPixmapInit (screen_info, &frame_pix.pm_sides[SIDE_TOP]);
+ xfwmPixmapInit (screen_info, &frame_pix.pm_sides[SIDE_BOTTOM]);
+
+ top_width = frameWidth (c) - frameTopLeftWidth (c, state) - frameTopRightWidth (c, state);
+ bottom_width = frameWidth (c) -
+ screen_info->corners[CORNER_BOTTOM_LEFT][state].width -
+ screen_info->corners[CORNER_BOTTOM_RIGHT][state].width;
+
+ /* The title is almost always visible */
+ frameCreateTitlePixmap (c, state, left, right, &frame_pix.pm_title, &frame_pix.pm_sides[SIDE_TOP]);
+ xfwmWindowSetBG (&c->title, &frame_pix.pm_title);
+ xfwmWindowShow (&c->title,
+ frameTopLeftWidth (c, state), 0, top_width,
+ frameTop (c), (requires_clearing | width_changed));
+
+ /* Corners are never resized, we need to update them separately */
+ if (requires_clearing)
+ {
+ xfwmWindowSetBG (&c->corners[CORNER_TOP_LEFT],
+ &screen_info->corners[CORNER_TOP_LEFT][state]);
+ xfwmWindowSetBG (&c->corners[CORNER_TOP_RIGHT],
+ &screen_info->corners[CORNER_TOP_RIGHT][state]);
+ xfwmWindowSetBG (&c->corners[CORNER_BOTTOM_LEFT],
+ &screen_info->corners[CORNER_BOTTOM_LEFT][state]);
+ xfwmWindowSetBG (&c->corners[CORNER_BOTTOM_RIGHT],
+ &screen_info->corners[CORNER_BOTTOM_RIGHT][state]);
+ }
}
- left = left - 2 * screen_info->params->button_spacing;
- right = x;
-
- top_width = frameWidth (c) - frameTopLeftWidth (c, state) - frameTopRightWidth (c, state);
- bottom_width = frameWidth (c) -
- screen_info->corners[CORNER_BOTTOM_LEFT][state].width -
- screen_info->corners[CORNER_BOTTOM_RIGHT][state].width;
- left_height = frameHeight (c) - frameTop (c) -
- screen_info->corners[CORNER_BOTTOM_LEFT][state].height;
- right_height = frameHeight (c) - frameTop (c) -
- screen_info->corners[CORNER_BOTTOM_RIGHT][state].height;
-
- xfwmPixmapInit (screen_info, &frame_pix.pm_title);
- xfwmPixmapInit (screen_info, &frame_pix.pm_sides[SIDE_TOP]);
- xfwmPixmapInit (screen_info, &frame_pix.pm_sides[SIDE_BOTTOM]);
+
xfwmPixmapInit (screen_info, &frame_pix.pm_sides[SIDE_LEFT]);
xfwmPixmapInit (screen_info, &frame_pix.pm_sides[SIDE_RIGHT]);
- /* The title is always visible */
- frameCreateTitlePixmap (c, state, left, right, &frame_pix.pm_title, &frame_pix.pm_sides[SIDE_TOP]);
- xfwmWindowSetBG (&c->title, &frame_pix.pm_title);
- xfwmWindowShow (&c->title,
- frameTopLeftWidth (c, state), 0, top_width,
- frameTop (c), (requires_clearing | width_changed));
-
- /* Corners are never resized, we need to update them separately */
- if (requires_clearing)
- {
- xfwmWindowSetBG (&c->corners[CORNER_TOP_LEFT],
- &screen_info->corners[CORNER_TOP_LEFT][state]);
- xfwmWindowSetBG (&c->corners[CORNER_TOP_RIGHT],
- &screen_info->corners[CORNER_TOP_RIGHT][state]);
- xfwmWindowSetBG (&c->corners[CORNER_BOTTOM_LEFT],
- &screen_info->corners[CORNER_BOTTOM_LEFT][state]);
- xfwmWindowSetBG (&c->corners[CORNER_BOTTOM_RIGHT],
- &screen_info->corners[CORNER_BOTTOM_RIGHT][state]);
- }
-
if (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
&& (c->screen_info->params->borderless_maximize))
{
@@ -1091,6 +1137,18 @@ frameDrawWin (Client * c)
}
else
{
+ if (vert_only)
+ {
+ left_height = right_height = c->height;
+ }
+ else
+ {
+ left_height = frameHeight (c) - frameTop (c)
+ - screen_info->corners[CORNER_BOTTOM_LEFT][state].height;
+ right_height = frameHeight (c) - frameTop (c)
+ - screen_info->corners[CORNER_BOTTOM_RIGHT][state].height;
+ }
+
if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
{
xfwmWindowHide (&c->sides[SIDE_LEFT]);
@@ -1120,63 +1178,69 @@ frameDrawWin (Client * c)
right_height, (requires_clearing | height_changed));
}
- xfwmPixmapCreate (screen_info, &frame_pix.pm_sides[SIDE_BOTTOM],
- bottom_width, frameBottom (c));
- xfwmPixmapFill (&screen_info->sides[SIDE_BOTTOM][state],
- &frame_pix.pm_sides[SIDE_BOTTOM],
- 0, 0, bottom_width, frameBottom (c));
- xfwmWindowSetBG (&c->sides[SIDE_BOTTOM],
- &frame_pix.pm_sides[SIDE_BOTTOM]);
- xfwmWindowShow (&c->sides[SIDE_BOTTOM],
- screen_info->corners[CORNER_BOTTOM_LEFT][state].width,
- frameHeight (c) - frameBottom (c), bottom_width, frameBottom (c),
- (requires_clearing | width_changed));
-
- if (!xfwmPixmapNone(&frame_pix.pm_sides[SIDE_TOP]))
+ if (!vert_only)
{
- xfwmWindowSetBG (&c->sides[SIDE_TOP], &frame_pix.pm_sides[SIDE_TOP]);
- xfwmWindowShow (&c->sides[SIDE_TOP],
- screen_info->corners[CORNER_TOP_LEFT][state].width,
- 0, top_width, frame_pix.pm_sides[SIDE_TOP].height,
+ xfwmPixmapCreate (screen_info, &frame_pix.pm_sides[SIDE_BOTTOM],
+ bottom_width, frameBottom (c));
+ xfwmPixmapFill (&screen_info->sides[SIDE_BOTTOM][state],
+ &frame_pix.pm_sides[SIDE_BOTTOM],
+ 0, 0, bottom_width, frameBottom (c));
+ xfwmWindowSetBG (&c->sides[SIDE_BOTTOM],
+ &frame_pix.pm_sides[SIDE_BOTTOM]);
+ xfwmWindowShow (&c->sides[SIDE_BOTTOM],
+ screen_info->corners[CORNER_BOTTOM_LEFT][state].width,
+ frameHeight (c) - frameBottom (c), bottom_width, frameBottom (c),
(requires_clearing | width_changed));
- }
- else
- {
- xfwmWindowHide (&c->sides[SIDE_TOP]);
- }
- xfwmWindowShow (&c->corners[CORNER_TOP_LEFT], 0, 0,
- frameTopLeftWidth (c, state),
- screen_info->corners[CORNER_TOP_LEFT][state].height,
- requires_clearing);
-
- xfwmWindowShow (&c->corners[CORNER_TOP_RIGHT],
- frameWidth (c) - frameTopRightWidth (c, state),
- 0, frameTopRightWidth (c, state),
- screen_info->corners[CORNER_TOP_RIGHT][state].height,
- requires_clearing);
-
- xfwmWindowShow (&c->corners[CORNER_BOTTOM_LEFT], 0,
- frameHeight (c) -
- screen_info->corners[CORNER_BOTTOM_LEFT][state].height,
- screen_info->corners[CORNER_BOTTOM_LEFT][state].width,
- screen_info->corners[CORNER_BOTTOM_LEFT][state].height,
- requires_clearing);
-
- xfwmWindowShow (&c->corners[CORNER_BOTTOM_RIGHT],
- frameWidth (c) -
- screen_info->corners[CORNER_BOTTOM_RIGHT][state].width,
- frameHeight (c) -
- screen_info->corners[CORNER_BOTTOM_RIGHT][state].height,
- screen_info->corners[CORNER_BOTTOM_RIGHT][state].width,
- screen_info->corners[CORNER_BOTTOM_RIGHT][state].height,
- requires_clearing);
+ if (!xfwmPixmapNone(&frame_pix.pm_sides[SIDE_TOP]))
+ {
+ xfwmWindowSetBG (&c->sides[SIDE_TOP], &frame_pix.pm_sides[SIDE_TOP]);
+ xfwmWindowShow (&c->sides[SIDE_TOP],
+ screen_info->corners[CORNER_TOP_LEFT][state].width,
+ 0, top_width, frame_pix.pm_sides[SIDE_TOP].height,
+ (requires_clearing | width_changed));
+ }
+ else
+ {
+ xfwmWindowHide (&c->sides[SIDE_TOP]);
+ }
+
+ xfwmWindowShow (&c->corners[CORNER_TOP_LEFT], 0, 0,
+ frameTopLeftWidth (c, state),
+ screen_info->corners[CORNER_TOP_LEFT][state].height,
+ requires_clearing);
+
+ xfwmWindowShow (&c->corners[CORNER_TOP_RIGHT],
+ frameWidth (c) - frameTopRightWidth (c, state),
+ 0, frameTopRightWidth (c, state),
+ screen_info->corners[CORNER_TOP_RIGHT][state].height,
+ requires_clearing);
+
+ xfwmWindowShow (&c->corners[CORNER_BOTTOM_LEFT], 0,
+ frameHeight (c) -
+ screen_info->corners[CORNER_BOTTOM_LEFT][state].height,
+ screen_info->corners[CORNER_BOTTOM_LEFT][state].width,
+ screen_info->corners[CORNER_BOTTOM_LEFT][state].height,
+ requires_clearing);
+
+ xfwmWindowShow (&c->corners[CORNER_BOTTOM_RIGHT],
+ frameWidth (c) -
+ screen_info->corners[CORNER_BOTTOM_RIGHT][state].width,
+ frameHeight (c) -
+ screen_info->corners[CORNER_BOTTOM_RIGHT][state].height,
+ screen_info->corners[CORNER_BOTTOM_RIGHT][state].width,
+ screen_info->corners[CORNER_BOTTOM_RIGHT][state].height,
+ requires_clearing);
+ }
}
frameSetShape (c, state, &frame_pix, button_x);
- xfwmPixmapFree (&frame_pix.pm_title);
- xfwmPixmapFree (&frame_pix.pm_sides[SIDE_TOP]);
- xfwmPixmapFree (&frame_pix.pm_sides[SIDE_BOTTOM]);
+ if (!vert_only)
+ {
+ xfwmPixmapFree (&frame_pix.pm_title);
+ xfwmPixmapFree (&frame_pix.pm_sides[SIDE_TOP]);
+ xfwmPixmapFree (&frame_pix.pm_sides[SIDE_BOTTOM]);
+ }
xfwmPixmapFree (&frame_pix.pm_sides[SIDE_LEFT]);
xfwmPixmapFree (&frame_pix.pm_sides[SIDE_RIGHT]);
}
diff --git a/src/netwm.c b/src/netwm.c
index 1352f08..9e3647c 100644
--- a/src/netwm.c
+++ b/src/netwm.c
@@ -136,6 +136,44 @@ clientSetNetState (Client * c)
}
void
+clientGetExtra (Client *c)
+{
+ long val;
+ DisplayInfo *display_info;
+
+ display_info = c->screen_info->display_info;
+
+ getHint (display_info, c->window, _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED, &val);
+ if (val)
+ FLAG_SET (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE);
+}
+
+void
+clientUpdateExtra (Client *c)
+{
+ long val;
+ unsigned long maximization_flags = 0L;
+ DisplayInfo *display_info;
+
+ display_info = c->screen_info->display_info;
+
+ getHint (display_info, c->window, _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED, &val);
+ if (val)
+ FLAG_SET (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE);
+ else
+ FLAG_UNSET (c->flags, CLIENT_FLAG_TITLELESS_MAXIMIZE);
+
+ if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
+ {
+ maximization_flags = c->flags & CLIENT_FLAG_MAXIMIZED;
+
+ /* Force an update by clearing the internal flags */
+ FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ | CLIENT_FLAG_MAXIMIZED_VERT);
+ clientToggleMaximized (c, maximization_flags, TRUE);
+ }
+}
+
+void
clientGetNetState (Client * c)
{
ScreenInfo *screen_info;
diff --git a/src/placement.c b/src/placement.c
index 01f2590..64719a7 100644
--- a/src/placement.c
+++ b/src/placement.c
@@ -38,7 +38,6 @@
#include "frame.h"
#include "netwm.h"
-
/* Compute rectangle overlap area */
static inline unsigned long
@@ -108,6 +107,8 @@ clientMaxSpace (ScreenInfo *screen_info, int *x, int *y, int *w, int *h)
g_return_if_fail (w != NULL);
g_return_if_fail (h != NULL);
+ TRACE ("entering clientMaxSpace");
+
screen_width = 0;
screen_height = 0;
delta = 0;
@@ -157,6 +158,7 @@ clientMaxSpace (ScreenInfo *screen_info, int *x, int *y, int *w, int *h)
}
}
}
+ TRACE ("clientMaxSpace result %d %d %d %d", *x, *y, *w, *h);
}
gboolean
diff --git a/src/settings.c b/src/settings.c
index 607bb7b..37b6c2a 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -667,6 +667,7 @@ loadSettings (ScreenInfo *screen_info)
/* You can change the order of the following parameters */
{"activate_action", NULL, G_TYPE_STRING, TRUE},
{"borderless_maximize", NULL, G_TYPE_BOOLEAN, TRUE},
+ {"titleless_maximize", NULL, G_TYPE_BOOLEAN, TRUE},
{"box_move", NULL, G_TYPE_BOOLEAN, TRUE},
{"box_resize", NULL, G_TYPE_BOOLEAN, TRUE},
{"button_layout", NULL, G_TYPE_STRING, TRUE},
@@ -753,6 +754,8 @@ loadSettings (ScreenInfo *screen_info)
screen_info->params->borderless_maximize =
getBoolValue ("borderless_maximize", rc);
+ screen_info->params->titleless_maximize =
+ getBoolValue ("titleless_maximize", rc);
screen_info->params->box_resize =
getBoolValue ("box_resize", rc);
screen_info->params->box_move =
@@ -1261,6 +1264,11 @@ cb_xfwm4_channel_property_changed(XfconfChannel *channel, const gchar *property_
screen_info->params->borderless_maximize = g_value_get_boolean (value);
reloadScreenSettings (screen_info, UPDATE_MAXIMIZE);
}
+ else if (!strcmp (name, "titleless_maximize"))
+ {
+ screen_info->params->titleless_maximize = g_value_get_boolean (value);
+ reloadScreenSettings (screen_info, UPDATE_MAXIMIZE);
+ }
else if (!strcmp (name, "cycle_minimum"))
{
screen_info->params->cycle_minimum = g_value_get_boolean (value);
diff --git a/src/settings.h b/src/settings.h
index be01b6b..ea8b79b 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -197,6 +197,7 @@ struct _XfwmParams
int title_shadow[2];
int wrap_resistance;
gboolean borderless_maximize;
+ gboolean titleless_maximize;
gboolean box_move;
gboolean box_resize;
gboolean click_to_focus;
--
1.8.4