@@ -51,7 +51,10 @@ const double kGtkCursorBlinkCycleFactor = 2000.0;
51
51
NativeWindowGtk::NativeWindowGtk (const base::WeakPtr<content::Shell>& shell,
52
52
base::DictionaryValue* manifest)
53
53
: NativeWindow(shell, manifest),
54
- content_thinks_its_fullscreen_ (false ) {
54
+ state_ (GDK_WINDOW_STATE_WITHDRAWN),
55
+ content_thinks_its_fullscreen_(false ),
56
+ frame_cursor_(NULL ),
57
+ resizable_(true ) {
55
58
window_ = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
56
59
57
60
vbox_ = gtk_vbox_new (FALSE , 0 );
@@ -124,6 +127,9 @@ NativeWindowGtk::NativeWindowGtk(const base::WeakPtr<content::Shell>& shell,
124
127
if (!has_frame_) {
125
128
g_signal_connect (window_, " button-press-event" ,
126
129
G_CALLBACK (OnButtonPressThunk), this );
130
+
131
+ g_signal_connect (window_, " motion-notify-event" ,
132
+ G_CALLBACK (OnMouseMoveEventThunk), this );
127
133
}
128
134
129
135
SetWebKitColorStyle ();
@@ -193,6 +199,14 @@ bool NativeWindowGtk::IsFullscreen() {
193
199
return content_thinks_its_fullscreen_;
194
200
}
195
201
202
+ bool NativeWindowGtk::IsMaximized () const {
203
+ return (state_ & GDK_WINDOW_STATE_MAXIMIZED);
204
+ }
205
+
206
+ bool NativeWindowGtk::IsMinimized () const {
207
+ return (state_ & GDK_WINDOW_STATE_ICONIFIED);
208
+ }
209
+
196
210
void NativeWindowGtk::SetSize (const gfx::Size& size) {
197
211
gtk_window_util::SetWindowSize (window_, size);
198
212
}
@@ -225,6 +239,7 @@ void NativeWindowGtk::SetMaximumSize(int width, int height) {
225
239
}
226
240
227
241
void NativeWindowGtk::SetResizable (bool resizable) {
242
+ resizable_ = resizable;
228
243
// Should request widget size after setting unresizable, otherwise the
229
244
// window will shrink to a very small size.
230
245
if (resizable == false ) {
@@ -514,6 +529,8 @@ gboolean NativeWindowGtk::OnFocusOut(GtkWidget* window, GdkEventFocus*) {
514
529
// Window state has changed.
515
530
gboolean NativeWindowGtk::OnWindowState (GtkWidget* window,
516
531
GdkEventWindowState* event) {
532
+ state_ = event->new_window_state ;
533
+
517
534
switch (event->changed_mask ) {
518
535
case GDK_WINDOW_STATE_ICONIFIED:
519
536
if (shell ()) {
@@ -562,23 +579,107 @@ gboolean NativeWindowGtk::OnWindowDeleteEvent(GtkWidget* widget,
562
579
return FALSE ;
563
580
}
564
581
582
+ bool NativeWindowGtk::GetWindowEdge (int x, int y, GdkWindowEdge* edge) {
583
+ if (has_frame_)
584
+ return false ;
585
+
586
+ if (IsMaximized () || IsFullscreen ())
587
+ return false ;
588
+
589
+ return gtk_window_util::GetWindowEdge (GetBounds ().size (), 0 , x, y, edge);
590
+ }
591
+
592
+ gboolean NativeWindowGtk::OnMouseMoveEvent (GtkWidget* widget,
593
+ GdkEventMotion* event) {
594
+ if (has_frame_) {
595
+ // Reset the cursor.
596
+ if (frame_cursor_) {
597
+ frame_cursor_ = NULL ;
598
+ gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window_)), NULL );
599
+ }
600
+ return FALSE ;
601
+ }
602
+
603
+ if (!resizable_)
604
+ return FALSE ;
605
+
606
+ int win_x, win_y;
607
+ GdkWindow* gdk_window = gtk_widget_get_window (GTK_WIDGET (window_));
608
+ gdk_window_get_origin (gdk_window, &win_x, &win_y);
609
+ gfx::Point point (static_cast <int >(event->x_root - win_x),
610
+ static_cast <int >(event->y_root - win_y));
611
+
612
+ // Update the cursor if we're on the custom frame border.
613
+ GdkWindowEdge edge;
614
+ bool has_hit_edge = GetWindowEdge (point.x (), point.y (), &edge);
615
+ GdkCursorType new_cursor = GDK_LAST_CURSOR;
616
+ if (has_hit_edge)
617
+ new_cursor = gtk_window_util::GdkWindowEdgeToGdkCursorType (edge);
618
+
619
+ GdkCursorType last_cursor = GDK_LAST_CURSOR;
620
+ if (frame_cursor_)
621
+ last_cursor = frame_cursor_->type ;
622
+
623
+ if (last_cursor != new_cursor) {
624
+ frame_cursor_ = has_hit_edge ? gfx::GetCursor (new_cursor) : NULL ;
625
+ gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window_)),
626
+ frame_cursor_);
627
+ }
628
+ return FALSE ;
629
+ }
630
+
565
631
// Capture mouse click on window.
566
632
gboolean NativeWindowGtk::OnButtonPress (GtkWidget* widget,
567
633
GdkEventButton* event) {
568
- if (!draggable_region_.isEmpty () &&
569
- draggable_region_.contains (event->x , event->y )) {
570
- if (event->button == 1 && GDK_BUTTON_PRESS == event->type ) {
571
- if (!suppress_window_raise_)
634
+ DCHECK (!has_frame_);
635
+ // Make the button press coordinate relative to the browser window.
636
+ int win_x, win_y;
637
+ GdkWindow* gdk_window = gtk_widget_get_window (GTK_WIDGET (window_));
638
+ gdk_window_get_origin (gdk_window, &win_x, &win_y);
639
+
640
+ GdkWindowEdge edge;
641
+ gfx::Point point (static_cast <int >(event->x_root - win_x),
642
+ static_cast <int >(event->y_root - win_y));
643
+ bool has_hit_edge = resizable_ && GetWindowEdge (point.x (), point.y (), &edge);
644
+ bool has_hit_titlebar =
645
+ !draggable_region_.isEmpty () && draggable_region_.contains (event->x , event->y );
646
+
647
+ if (event->button == 1 ) {
648
+ if (GDK_BUTTON_PRESS == event->type ) {
649
+ // Raise the window after a click on either the titlebar or the border to
650
+ // match the behavior of most window managers, unless that behavior has
651
+ // been suppressed.
652
+ if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_)
572
653
gdk_window_raise (GTK_WIDGET (widget)->window );
573
654
574
- return gtk_window_util::HandleTitleBarLeftMousePress (
575
- GTK_WINDOW (widget), GetBounds (), event);
576
- } else if (event->button == 2 ) {
577
- gdk_window_lower (GTK_WIDGET (widget)->window );
578
- return TRUE ;
655
+ if (has_hit_edge) {
656
+ gtk_window_begin_resize_drag (window_, edge, event->button ,
657
+ static_cast <gint>(event->x_root ),
658
+ static_cast <gint>(event->y_root ),
659
+ event->time );
660
+ return TRUE ;
661
+ } else if (has_hit_titlebar) {
662
+ return gtk_window_util::HandleTitleBarLeftMousePress (
663
+ window_, GetBounds (), event);
664
+ }
665
+ } else if (GDK_2BUTTON_PRESS == event->type ) {
666
+ if (has_hit_titlebar && resizable_) {
667
+ // Maximize/restore on double click.
668
+ if (IsMaximized ()) {
669
+ gtk_window_unmaximize (window_);
670
+ // gtk_window_util::UnMaximize(GTK_WINDOW(widget),
671
+ // GetBounds(), restored_bounds_);
672
+ } else {
673
+ gtk_window_maximize (window_);
674
+ }
675
+ return TRUE ;
676
+ }
579
677
}
678
+ } else if (event->button == 2 ) {
679
+ if (has_hit_titlebar || has_hit_edge)
680
+ gdk_window_lower (gdk_window);
681
+ return TRUE ;
580
682
}
581
-
582
683
return FALSE ;
583
684
}
584
685
0 commit comments