Skip to content

Commit a985f29

Browse files
Merge pull request livecode#5990 from livecode/bugfix-13992
[Bug 13992] Fixed bug causing crash on mouseEnter
2 parents d9df82b + 831585a commit a985f29

4 files changed

Lines changed: 56 additions & 40 deletions

File tree

docs/notes/bugfix-13992.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fixed bug causing crash on mouse enter

engine/src/control.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,9 +1359,16 @@ void MCControl::newmessage()
13591359

13601360
void MCControl::enter()
13611361
{
1362+
MCControlHandle t_this(this);
1363+
13621364
if (focused.IsValid() && !focused.IsBoundTo(this))
13631365
{
1364-
leave();
1366+
leave();
1367+
}
1368+
1369+
if (!t_this.IsValid())
1370+
{
1371+
return;
13651372
}
13661373

13671374
if (MCdispatcher -> isdragtarget())
@@ -1387,7 +1394,11 @@ void MCControl::enter()
13871394
else
13881395
message(MCM_mouse_enter);
13891396
// AL-2013-01-14: [[ Bug 11343 ]] Add timer if the object handles mouseWithin in the behavior chain.
1390-
if (handlesmessage(MCM_mouse_within) && !(hashandlers & HH_IDLE))
1397+
if(!t_this.IsValid())
1398+
{
1399+
return;
1400+
}
1401+
if (handlesmessage(MCM_mouse_within) && !(hashandlers & HH_IDLE))
13911402
MCscreen->addtimer(this, MCM_idle, MCidleRate);
13921403
if (getstack()->gettool(this) == T_BROWSE)
13931404
MCtooltip->settip(tooltip);

engine/src/group.cpp

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ MCGroup::MCGroup() :
120120
kfocused(NULL),
121121
oldkfocused(NULL),
122122
newkfocused(NULL),
123-
mfocused(NULL),
124123
vscrollbar(NULL),
125124
hscrollbar(NULL),
126125
scrollx(0),
@@ -144,7 +143,6 @@ MCGroup::MCGroup(const MCGroup &gref, bool p_copy_ids) :
144143
kfocused(NULL),
145144
oldkfocused(NULL),
146145
newkfocused(NULL),
147-
mfocused(NULL),
148146
vscrollbar(NULL),
149147
hscrollbar(NULL),
150148
scrollx(gref.scrollx),
@@ -381,7 +379,7 @@ void MCGroup::open()
381379
if (opened == 1)
382380
{
383381
mgrabbed = False;
384-
newkfocused = oldkfocused = kfocused = mfocused = NULL;
382+
newkfocused = oldkfocused = kfocused = NULL;
385383
computeminrect(False);
386384
setsbrects();
387385
}
@@ -611,7 +609,7 @@ void MCGroup::mdrag(void)
611609
if (getstack() -> gettool(this) != T_BROWSE)
612610
return;
613611

614-
if (mfocused != NULL)
612+
if (mfocused.IsValid())
615613
{
616614
mfocused -> mdrag();
617615
}
@@ -626,21 +624,21 @@ bool MCGroup::mfocus_control(int2 x, int2 y, bool p_check_selected)
626624
{
627625
if (controls != nil)
628626
{
629-
MCControl *tptr = controls->prev();
627+
MCControlHandle tptr(controls->prev());
630628
do
631629
{
632630
// Check if any group's child is selected and focused
633631
if (p_check_selected && tptr -> gettype() == CT_GROUP)
634632
{
635-
if (static_cast<MCGroup *>(tptr) -> mfocus_control(x, y, true))
633+
if (tptr.IsValid() && tptr.GetAs<MCGroup>() -> mfocus_control(x, y, true))
636634
{
637635
mfocused = tptr;
638636
return true;
639637
}
640638
}
641639

642640
bool t_focused;
643-
if (p_check_selected)
641+
if (p_check_selected && tptr.IsValid())
644642
{
645643
// On the first pass (checking selected objects), just check
646644
// if the object is selected and the mouse is inside a resize handle.
@@ -653,26 +651,30 @@ bool MCGroup::mfocus_control(int2 x, int2 y, bool p_check_selected)
653651
tptr -> mfocus(x, y);
654652

655653
}
656-
else
654+
else if (tptr.IsValid())
657655
{
658656
t_focused = tptr -> mfocus(x, y);
659657
}
658+
else
659+
{
660+
t_focused = false;
661+
}
660662

661663
if (t_focused)
662664
{
663665
Boolean newfocused = tptr != mfocused;
664666

665-
if (newfocused && mfocused != NULL)
667+
if (newfocused && mfocused.IsValid())
666668
{
667669
MCControl *oldfocused = mfocused;
668670
mfocused = tptr;
669671
oldfocused->munfocus();
670672
}
671-
else
673+
else if (tptr.IsValid())
672674
mfocused = tptr;
673675

674676
// The widget event manager handles enter/leave itself
675-
if (newfocused && mfocused != nil &&
677+
if (newfocused && mfocused.IsValid() &&
676678
mfocused -> gettype() != CT_GROUP &&
677679
#ifdef WIDGETS_HANDLE_DND
678680
mfocused -> gettype() != CT_WIDGET)
@@ -681,12 +683,14 @@ bool MCGroup::mfocus_control(int2 x, int2 y, bool p_check_selected)
681683
mfocused -> gettype() != CT_WIDGET))
682684
#endif
683685
{
686+
if (mfocused.IsValid())
687+
{
684688
mfocused->enter();
685-
689+
}
686690
// MW-2007-10-31: mouseMove sent before mouseEnter - make sure we send an mouseMove
687691
// ... and now lets make sure it doesn't crash!
688692
// Here mfocused can be NULL if a control was deleted in mfocused -> enter()
689-
if (mfocused != NULL)
693+
if (mfocused.IsValid())
690694
mfocused->mfocus(x, y);
691695
}
692696
return true;
@@ -696,16 +700,16 @@ bool MCGroup::mfocus_control(int2 x, int2 y, bool p_check_selected)
696700
if (!p_check_selected && tptr == mfocused)
697701
{
698702
// Use the group's munfocus method if the group has an mfocused control.
699-
if (mfocused -> gettype() != CT_GROUP
700-
|| static_cast<MCGroup *>(mfocused) -> getmfocused() != nil)
703+
if (mfocused.IsValid() && (mfocused -> gettype() != CT_GROUP
704+
|| mfocused.GetAs<MCGroup>() -> getmfocused() != nil))
701705
{
702706
MCControl *oldfocused = mfocused;
703-
mfocused = NULL;
707+
mfocused = nullptr;
704708
oldfocused->munfocus();
705709
}
706-
else
710+
else if (mfocused.IsValid())
707711
{
708-
static_cast<MCGroup *>(mfocused) -> clearmfocus();
712+
mfocused.GetAs<MCGroup>() -> clearmfocus();
709713
mfocused = nil;
710714
}
711715
}
@@ -726,7 +730,7 @@ Boolean MCGroup::mfocus(int2 x, int2 y)
726730
return MCObject::mfocus(x, y);
727731
if (!(flags & F_VISIBLE || showinvisible()))
728732
{
729-
mfocused = NULL;
733+
mfocused = nullptr;
730734
mgrabbed = False;
731735
return False;
732736
}
@@ -745,10 +749,10 @@ Boolean MCGroup::mfocus(int2 x, int2 y)
745749
mgrabbed = False;
746750
if (sbfocus(x, y, hscrollbar, vscrollbar))
747751
{
748-
if (mfocused != NULL)
752+
if (mfocused.IsValid())
749753
{
750754
mfocused->munfocus();
751-
mfocused = NULL;
755+
mfocused = nullptr;
752756
}
753757
return True;
754758
}
@@ -764,10 +768,10 @@ Boolean MCGroup::mfocus(int2 x, int2 y)
764768
return True;
765769
}
766770
else
767-
if (mfocused != NULL)
771+
if (mfocused.IsValid())
768772
{
769773
MCControl *oldfocused = mfocused;
770-
mfocused = NULL;
774+
mfocused = nullptr;
771775
oldfocused->munfocus();
772776
}
773777
}
@@ -779,17 +783,17 @@ Boolean MCGroup::mfocus(int2 x, int2 y)
779783
void MCGroup::munfocus()
780784
{
781785
mgrabbed = False;
782-
if (mfocused != NULL)
786+
if (mfocused.IsValid())
783787
{
784788
MCControl *oldfocused = mfocused;
785-
mfocused = NULL;
789+
mfocused = nullptr;
786790
// IM-2013-08-07: [[ Bug 10671 ]] Release grabbed controls when removing focus
787791
state &= ~CS_GRAB;
788792
oldfocused->munfocus();
789793
}
790794
else
791795
{
792-
mfocused = NULL;
796+
mfocused = nullptr;
793797
message(MCM_mouse_leave);
794798
}
795799
state &= ~(CS_MFOCUSED | CS_HSCROLL | CS_VSCROLL);
@@ -816,7 +820,7 @@ Boolean MCGroup::mdown(uint2 which)
816820
if (tool == T_BROWSE && sbdown(which, hscrollbar, vscrollbar))
817821
return True;
818822

819-
if (tool == T_POINTER && (mfocused == NULL || !MCselectgrouped || getflag(F_SELECT_GROUP)))
823+
if (tool == T_POINTER && (!mfocused.IsValid() || !MCselectgrouped || getflag(F_SELECT_GROUP)))
820824
{
821825
if (which == Button1)
822826
{
@@ -830,7 +834,7 @@ Boolean MCGroup::mdown(uint2 which)
830834
return True;
831835
}
832836

833-
if (mfocused == NULL)
837+
if (!mfocused.IsValid())
834838
return False;
835839
mgrabbed = True;
836840

@@ -842,7 +846,7 @@ Boolean MCGroup::mdown(uint2 which)
842846
t_handled = false;
843847

844848
state |= CS_MFOCUSED;
845-
if (mfocused == NULL || !mfocused->mdown(which))
849+
if (!mfocused.IsValid() || !mfocused->mdown(which))
846850
{
847851
mgrabbed = False;
848852
state &= ~CS_MFOCUSED;
@@ -867,7 +871,7 @@ Boolean MCGroup::mup(uint2 which, bool p_release)
867871
if (sbup(which, hscrollbar, vscrollbar))
868872
return True;
869873
Tool tool = getstack()->gettool(this);
870-
if (tool == T_POINTER && (mfocused == NULL || !MCselectgrouped || getflag(F_SELECT_GROUP)))
874+
if (tool == T_POINTER && (!mfocused.IsValid() || !MCselectgrouped || getflag(F_SELECT_GROUP)))
871875
{
872876
if (which == Button1)
873877
{
@@ -890,7 +894,7 @@ Boolean MCGroup::mup(uint2 which, bool p_release)
890894
if (tool != T_POINTER)
891895
radio(0, oldfocused);
892896
mgrabbed = False;
893-
if (mfocused == NULL || mfocused->mup(which, p_release))
897+
if (!mfocused.IsValid() || mfocused->mup(which, p_release))
894898
{
895899
newkfocused = NULL;
896900
// MH-2007-03-20: [[ Bug 705 ]] Selecting a radio button using pointer tool unhilites other radio buttons in the group with radiobehavior set.
@@ -910,18 +914,18 @@ Boolean MCGroup::doubledown(uint2 which)
910914
return True;
911915

912916
Tool tool = getstack() -> gettool(this);
913-
if (tool == T_POINTER && (mfocused == NULL || !MCselectgrouped || getflag(F_SELECT_GROUP)))
917+
if (tool == T_POINTER && (!mfocused.IsValid() || !MCselectgrouped || getflag(F_SELECT_GROUP)))
914918
{
915919
message_with_args(MCM_mouse_double_down, which);
916920
return True;
917921
}
918922

919-
if (mfocused == NULL)
923+
if (!mfocused.IsValid())
920924
return False;
921925

922926
mgrabbed = True;
923927
state |= CS_MFOCUSED;
924-
if (mfocused == NULL || !mfocused->doubledown(which))
928+
if (!mfocused.IsValid() || !mfocused->doubledown(which))
925929
{
926930
mgrabbed = False;
927931
state &= ~CS_MFOCUSED;
@@ -937,15 +941,15 @@ Boolean MCGroup::doubleup(uint2 which)
937941
return True;
938942

939943
Tool tool = getstack() -> gettool(this);
940-
if (tool == T_POINTER && (mfocused == NULL || !MCselectgrouped || getflag(F_SELECT_GROUP)))
944+
if (tool == T_POINTER && (!mfocused.IsValid() || !MCselectgrouped || getflag(F_SELECT_GROUP)))
941945
{
942946
message_with_args(MCM_mouse_double_up, which);
943947
return True;
944948
}
945949

946950
mgrabbed = False;
947951
state &= ~CS_MFOCUSED;
948-
if (mfocused == NULL || mfocused -> doubleup(which))
952+
if (!mfocused.IsValid() || mfocused -> doubleup(which))
949953
return True;
950954

951955
return False;
@@ -1861,7 +1865,7 @@ void MCGroup::clearfocus(MCControl *cptr)
18611865
{
18621866
if (cptr == mfocused)
18631867
{
1864-
mfocused = NULL;
1868+
mfocused = nullptr;
18651869
mgrabbed = False;
18661870
}
18671871
if (cptr == oldkfocused)

engine/src/group.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class MCGroup : public MCControl, public MCMixinObjectHandle<MCGroup>
4141
MCControl *kfocused;
4242
MCControl *oldkfocused;
4343
MCControl *newkfocused;
44-
MCControl *mfocused;
44+
MCControlHandle mfocused;
4545
MCScrollbar *vscrollbar;
4646
MCScrollbar *hscrollbar;
4747
int4 scrollx;

0 commit comments

Comments
 (0)